phyml-3.2.0/000077500000000000000000000000001263450375500126575ustar00rootroot00000000000000phyml-3.2.0/.gitignore000066400000000000000000000003371263450375500146520ustar00rootroot00000000000000# Object files *.o *.ko *.obj *.elf # Precompiled Headers *.gch *.pch # Libraries *.lib *.a *.la *.lo # Shared objects (inc. Windows DLLs) *.dll *.so *.so.* *.dylib # Executables *.exe *.out *.app *.i*86 *.x86_64 *.hex phyml-3.2.0/AUTHORS000066400000000000000000000013271263450375500137320ustar00rootroot00000000000000** Authors ** Stephane Guindon Department of Statistics. University of Auckland. New Zealand Universite Montpellier II - CNRS UMR 5506. LIRMM. Montpellier France. e-mail : guindon@stat.auckland.ac.nz Olivier Gascuel Universite Montpellier II - CNRS UMR 5506. LIRMM. Montpellier France. e-mail : gascuel@lirmm.fr Jean-Francois Dufayard Universite Montpellier II - CNRS UMR 5506. LIRMM. Montpellier France. e-mail : jeanfrancois.dufayard@gmail.com ** Authors (before 2006)... ** Wim Hodrijk currently working for the 'National Bioinformatics Network'. Cape Town, South Africa e-mail : wim@santafe.edu Franck Lethiec Universite Montpellier II - CNRS UMR 5506. LIRMM. Montpellier France. e-mail : lethiec@lirmm.fr phyml-3.2.0/COPYING000066400000000000000000000431101263450375500137110ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. phyml-3.2.0/ChangeLog000066400000000000000000000326071263450375500144410ustar00rootroot00000000000000 Version date what has been changed 5.0 26.08.2000 - changes to manual, Makefile.in - cpREV hidden by -DCPREV flag - chi2test, quartio included into source code files - generic scr/Makefile.generic - src/makefile.com for VAX - AUTHORS, README, ChangeLog updated - INSTALL checked 27.08.2000 - test code excluded - '-randseed#' added for debugging purposes - ./align added to autoconf/automake - warning output if cmdline parameter unknown 11.10.2000 - fixed output of rate categories of sites before computing them - check whether rate categories were computed by 1st user tree or NJ tree fixed in the output 12.10.2000 - invariant site model normalization fixed CODE FREEZE =========== 5.0.a33 15.08.2000 - changes for autoconf/automake 5.0.a32 01.08.2000 - a FPE error fixed (badq == 0) - small error in -bestq fixed - fflush's added at several places 5.0.a31 01.08.2000 - comments added to tree structure sorting puzzle2.c - changes in configure.in, Makefile.in 5.0.a30 23.07.2000 - some debugging in checkquart - changed to autoconf 5.0.a29 13.07.2000 - some debugging in checkquart 5.0.a28 13.07.2000 - use best quartet topology option (-bestq) implemented 5.0.a27 13.07.2000 - further developement to checkquart - ascii/binary quartet values (-wqla/-wqlb) - typo correction 5.0.a26 11.07.2000 - fflush at all checktimer - further developement at checkquart - possibility to write quartet values to file (-wqlh) 5.0.a25 06.07.2000 - fflush at checktimer 5.0.a24 02.07.2000 - further debugging of checkquart 5.0.a23 02.07.2000 - further developement to checkquart 5.0.a22 29.06.2000 - checkquart added to makefile - bad quartet stats added after reading in *.allquarts 5.0.a21 27.06.2000 - site pattern statistics implemented and added to SEQUENCE ALIGNMENT section in puzzle report 5.0.a20 26.06.2000 - cpREV45 implemented 5.0.a19 26.06.2000 - for debugging purposes: typo "MPE" changed to "FPE" - fflush(stdout) added in chi2test 5.0.a18 20.06.2000 - checkquart implemented 5.0.a17 19.06.2000 - FPRINTF(STDOUTFILE and STDOUT definition changed and moved; fputid/fputid10 writes to STDOUT instead of stdout - ppuzzle checks slaves enough slave-processes - numquarts, num2quart, quart2num moved from ppuzzle.c to puzzle1.c - read/writeallquart implemented (undocumented feature) to be used by -wqf/-rqf at comandline -wqf = write quartet file (infilename.allquart) after quartet evaluation -rqf = read quartet file (infilename.allquart), no quartet evaluation, unless -wqf is used as well, then quartets are written and read in - '-h' option at comandline -> printusage 5.0.a16 31.05.2000 - chi2test bug fixed - WAG matrix added, model choice adopted 13.06.2000 - date set to June 2000 - author order changed to Schmidt, Strimmer, Vingron, v.Haeseler - CPU time output stopped, due to overflow errors 16.06.2000 - sequence composition chi2test moved before parameter output. - output of chi2test and bad quartet statistics split, to do the chi2test output earlier. 5.0.a15 02.05.2000 - Names changed back from TREE-PUZZLE to PUZZLE 09.05.2000 - and to TREE-PUZZLE again ;-) 5.0.a14 13.03.2000 - Changes to the manual. - Executable names changed to (p)treepuzzle. (changes in the makefiles) 15.03.2000 - Output of parameters after estimation added. 5.0.a13 18.02.2000 - ALPHA version number removed from the code 5.0.a12 18.02.2000 - CPU time measurement problems fixed for case where clock_t is an unsigned type. 5.0.a11 17.02.2000 - time measure problems (CPU/wallclock) fixed not all features in addtimes are used at the moment. - unnecessary and unused routines removed fron source code. 5.0.a10 20.01.2000 - Name changes from PUZZLE to TREE-PUZZLE - Chi2-fit model guessing for VT model added - little model printing bug fixed 5.0.a9 22.12.1999 - VT Model incorporated (Mueller, Vingron (2000) JCB, to appear). - TODO: Chi2-fit model guessing for VT model 5.0.a8 21.12.1999 - 'sys/times.h' and 'sys/types.h' removed from puzzle.h. They were neither ANSI conform nor necessary, but occured in the SUN man pages. - Definition and call of writetimesstat eliminated from the sequention version by compiler switched, and not just the function body as before. - '-O4' canged to '-O' to be more generic. 5.0.a7 21.12.1999 - Macro constants introduced for data_optn (NUCLEOTIDE, AMINOACID, BINARY) - round robbing of datatype and AA model option changed in menu to make adjustment of the model possible by a determined sequence of letters: 'd': Auto -> Nucleotides -> Amino acids -> Binary states -> Auto ('m' && data_optn == AMINOACID): Auto -> Dayhoff -> JTT -> mtREV24 -> BLOSUM62 -> Auto - manual.html adjusted 5.0.a6 20.12.1999 - new manual.html added 5.0.a5 07.12.1999 - output bug fixed (bestrates were written before they were computed) 5.0.a4 02.12.1999 - header file inclusion ajusted: added: #include changed from: #include "ppuzzle.h" to: #ifdef PARALLEL # include "ppuzzle.h" #endif 5.0.a3 27.11.1999 - '-h' comandline option removed, because of problems with MPICH under LINUX - new memory leaks of 5.0.a2 closed in PP_Finalize 5.0.a2 27.11.1999 - Cleanup of the source code - Measurement of CPU time added - Parallel load statistics added (quartets, trees, time) to puzzle report. - Cleanup debug messages - Comments "[...]" are removed from usertrees now. - single quotes will only be printed arount species names if -DUSEQUOTES is set at compiletime. - tree likelihood is printed infront of a tree as a comment, [ lh=-xx.xxxxx ](...); 5.0.a1 26.11.1999 - Cleanup of the directories - Copyright changes - Version changes VERSION CHANGE ============== 4.1.a26 25.11.1999 - Makefile made universal for pauzzle and ppuzzle - lines not needed removed from puzzle.h 4.1.a25 19.11.1999 - Output file prefixes for distances, trees, and puzzlereport changed in user trees analysis case to user tree file name - Temporary output of likelihood to treefile added 4.1.a24 11.11.1999 - Output of puzzling step trees changed ptorder: [ orderno # % ID #UniqTopos #Steps ]PHYLIP pstep: chunk #InChunk sum ID #UniqTopos #Steps - preliminary leap frog RNG implemented, i.e. uses the rand4 in the usual way in the sequential case. If run in parallel all rand4 are initialized with the same seed and started with PP_Myid-th random number. after that each process uses the every PP_NumProcs-th random number to make sure that these unique. 4.1.a23 08.11.1999 - output of sequential and parallel version to *.pstep made identical 4.1.a22 05.11.1999 - two different puzzle step tree outputs intruduced and added to the menu ("[ 1. 35 ](...);": - ordered unique tree list -> *.ptorder Format: "[ 1. 35 ]" (Ordernumber, Amount) - chronological tree list -> *.pstep Format: "[ 1. 35 ]" (Chunknumber, Amount in chunk) (the last is a problem in parallel, because the come in chunks, as scheduled) - debugged the output 4.1.a21 04.11.1999 - Makefile adjustments for other Plattforms - pstep tree output changed. unique treestructures printed to *.pstep file with a leading comment containing an order number and the ammount padded with blanks (e.g. "[ 1. 356 ]('mouse'..."). output is done right before writing the puzzle file. - controlled MPI finish to the Quit menu option added 4.1.a20 03.11.1999 - some garbage collection (free) added - makefile adjusted, OFLAGS for optimization added (ppuzzle/MPICH has problems with -O, so the ppuzzle is created without optimization) Some minor changes in the makefiles - still to do: garbage collection from 'internalnode' in master process 4.1.a19 13.10.1999 - adding the output of standardized (i.e. sorted) puzzling step trees. Those are printed to the standard output at the moment. (Routines to sort and print the trees implemented) 14.10.1999 - routines for printing the sorted trees to a string. needed to send them between Master and Worker, and to have a unique key to sort and count the trees. 21.10.1999 - counting of sorted trees implemented by doubly linked list, sort routine, print to stdout 25.10.1999 - change place of writing distances to file right after distances have been computed. - output of puzzling step trees now with true name, not numbers 02.11.1999 - parallel counting and sending of puzzling step trees - some parallel sending bugs fixed 4.1.a18 14.09.1999 - adding possibility to specify input file at command line, this specifies also the output filenames (puzzle output: *.puzzle; treefile: *.tree; distances: *.dist; Triangel EPS: *.eps; unresolved: *.qlist; puzzling step trees: *.pstep) If an unexisting name is given, one has to reenter the right name, but the wrong one is used as prefix. 15.09.1999 - sending back of bad quartets from slaves added - bug in quart2num fixed (not used before; was shifted by 1) - first version of a README added ;-) 4.1.a17 03.08.1999 - Recv-Error in receiving DoPuzzleBlock fixed - double freeing of same MPI_Datatype fixed - changing of scheduling algorithm to smaller chunks in gss -> sgss 13.09.1999 - bug fixed in optimization routine in ml2.c: boundary check added 4.1.a16 12.07.1999 - slight changes in verbosity levels - changed all printf to FPRINTF(STDOUTFILE to change easily from stdout to a file. 4.1.a15 08.07.1999 - scheduler for both parallel parts - several small changes 4.1.a14 25.06.1999 - computation of tree parallel, scheduler dependent, sending all biparts in one message instead of one by one - several small changes since a13 in sched.c, et al. 4.1.a13 10.06.1999 - computation of tree parallel (chunk = #trees/#slaves) - scheduling schemes implemented for minimum chunk sizes 4.1.a12 07.06.1999 - computation of quartets properly parallel - scheduling implemented - counting of quartets by slave ajusted - TODO: sending of bad quartets (array + list) - distinction between '1st user tree' and 'NJ tree' in result output removed again 4.1.a11 28.05.1999 - PP_SendDoQuartBlock, PP_RecvDoQuartBlock, PP_SendQuartBlock, PP_RecvQuartBlock - mallocquartets() changed from global to local variables to be more flexible - Quartet computation moved to slave (badquartet handling missing: output, badquartet vector); - distinction between '1st user tree' and 'NJ tree' added in result output (puzzle1.c around l.1756) 4.1.a10 20.05.1999 - num2quart, numquarts, quart2num introduced - parallel init/finalize, quartets computed on master and slave, compared -> equal -> all necessary parameter exported 4.1.a9 19.05.1999 - 'dvector forg' removed from onepamratematrix cmdline, because it's not used in the function. 4.1.a8 18.05.1999 - add _GAMMA_ (not necessary) to gamma.h and _PUZZLE_ to puzzle.h to avoid dublicate includes, possible due to ppuzzle.h - ppuzzle added to makefile and to check - 1st parallel version but no slave computations only sending parameters and done signals. 4.1.a7 18.05.1999 - export reevaluation of tree and evaluation of usertrees to evaluatetree. 4.1.a6 17.05.1999 - -DNEWFORLOOP added to fixed.src, because the changed for loop structure changes the sequence of randomized quartets during likelihood mapping - change 'int main()' to 'int main(argc, argv)' - export more functionalities from main: memcleanup(), inputandinit(&argc, &argv) - grouping if's (excluding eachother) together in switch() - split treereavaluation and 1st usertree, evaluate all usertrees together (TODO: both, treereavaluation and usertrees in one loop) - MAKE CHECK added to ./makefile 4.1.a5 16.05.1999 - adding ´dvector Brnlength´ to lslength cmdline to reduce globality of Brnlength. (Later better to *Tree) 4.1.a4 11.05.1999 - structure of for loops changed in computeallquartets and recon_tree, so that the quarted addresses are in one contigous sequence (for a 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {description} Copyright (C) {year} {fullname} This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. {signature of Ty Coon}, 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. phyml-3.2.0/Makefile.am000066400000000000000000000001131263450375500147060ustar00rootroot00000000000000SUBDIRS = src EXTRA_DIST = doc bin examples DIST_SUBDIRS = $(SUBDIRS) doc phyml-3.2.0/NEWS000066400000000000000000000000001263450375500133440ustar00rootroot00000000000000phyml-3.2.0/README000066400000000000000000000016231263450375500135410ustar00rootroot00000000000000 ////////////////////////////////////////////////////////////////////////// // You have downloaded the Stable or the Development version of PhyML // ////////////////////////////////////////////////////////////////////////// To install PhyML, type the following commands: ./configure; make; To install PhyML (MPI version_, type the following commands: ./configure --enable-mpi; make; To install PhyTime, type the following commands: ./configure --enable-phytime; make; To compile a Windows executable, install MinGW and run: ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes mingw64-configure; make; ////////////////////////////////////////////////////////////////////////// // You have cloned PhyML from GitHub // ////////////////////////////////////////////////////////////////////////// To install PhyML, type the following command: sh ./autogen.sh; phyml-3.2.0/README.md000066400000000000000000000013501263450375500141350ustar00rootroot00000000000000phyml ===== PhyML -- Phylogenetic estimation using (Maximum) Likelihood PhyML is a software that estimates maximum likelihood phylogenies from alignments of nucleotide or amino acid sequences. The main strength of PhyML lies in the large number of substitution models coupled to various options to search the space of phylogenetic tree topologies, going from very fast and efficient methods to slower but generally more accurate approaches. PhyML was designed to process moderate to large data sets. In theory, alignments with up to 4,000 sequences 2,000,000 character-long can be processed. PhyML can process data sets made of multiple genes and fit sophisticated substitution models with heterogeneous components across partition elements. phyml-3.2.0/autogen.sh000066400000000000000000000000521263450375500146520ustar00rootroot00000000000000#!/bin/sh autoreconf --force --install -v phyml-3.2.0/config.h.in000066400000000000000000000072031263450375500147040ustar00rootroot00000000000000/* config.h.in. Generated from configure.ac by autoheader. */ /* BEAGLE tag on */ #undef BEAGLE /* CHECKPOINT tag on */ #undef CHECKPOINT /* Debug tag on */ #undef DEBUG /* EVOLVE tag on */ #undef EVOLVE /* GEO tag on */ #undef GEO /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ #undef HAVE_DOPRNT /* Define to 1 if you have the header file. */ #undef HAVE_FLOAT_H /* Define to 1 if you have the `floor' function. */ #undef HAVE_FLOOR /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `m' library (-lm). */ #undef HAVE_LIBM /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `pow' function. */ #undef HAVE_POW /* Define to 1 if your system has a GNU libc compatible `realloc' function, and to 0 otherwise. */ #undef HAVE_REALLOC /* Define to 1 if you have the `rint' function. */ #undef HAVE_RINT /* Define to 1 if you have the `sqrt' function. */ #undef HAVE_SQRT /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the `vprintf' function. */ #undef HAVE_VPRINTF /* INVITEE tag on */ #undef INVITEE /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* m4 tag on */ #undef M4 /* MPI tag on */ #undef MPI /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* PART tag on */ #undef PART /* PHYCONT tag on */ #undef PHYCONT /* PHYML tag on */ #undef PHYML /* PHYREX tag on */ #undef PHYREX /* PHYTIME tag on */ #undef PHYTIME /* RF tag on */ #undef RF /* RWRAP tag on */ #undef RWRAP /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* TEST tag on */ #undef TEST /* TIPORDER tag on */ #undef TIPORDER /* Unix tag on */ #undef UNIX /* Version number of package */ #undef VERSION /* Define to empty if `const' does not conform to ANSI C. */ #undef const /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus #undef inline #endif /* Define to rpl_malloc if the replacement function should be used. */ #undef malloc /* Define to rpl_realloc if the replacement function should be used. */ #undef realloc /* Define to `unsigned int' if does not define. */ #undef size_t phyml-3.2.0/configure.ac000066400000000000000000000163651263450375500151600ustar00rootroot00000000000000# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_INIT([PhyML],esyscmd([sh -c "date \"+%Y%m%d\" | tr -d '\n'"]),[s.guindon@auckland.ac.nz]) AM_INIT_AUTOMAKE([foreign]) m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES]) AC_CONFIG_SRCDIR([src/simu.c],[doc/phyml-manual.tex]) AC_CONFIG_HEADERS([config.h]) AC_DEFINE([UNIX],[1],[Unix tag on]) AC_DEFINE([DEBUG],[1],[Debug tag on]) AM_INIT_AUTOMAKE AC_CANONICAL_HOST AC_PROG_CC([gcc]) # Checks for libraries. AC_CHECK_LIB([m], [log]) # Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS([float.h stdlib.h string.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T # Check for presence of LaTeX and pdfLaTeX AC_CHECK_PROGS([PDFLATEX], pdflatex, [/bin/false]) AC_CHECK_PROGS([LATEX], latex, [/bin/false]) if test "x$PDFLATEX" = x/bin/false || test "x$LATEX" = x/bin/false; then enable_docs=no AC_MSG_WARN([Documentation will not be built!]) fi AM_CONDITIONAL([HAVE_PDFLATEX], test -n "$PDFLATEX") # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_REALLOC AC_FUNC_SETVBUF_REVERSED AC_FUNC_VPRINTF AC_CHECK_FUNCS([floor pow rint sqrt strchr strstr]) # Thanks for Charles Plessy from Debian case "${host}" in *i386*|*amd64*|*x86_64*) MSSE=-msse AC_MSG_NOTICE("On arch ${host} use MSSE = ${MSSE}") ;; *) MSSE= AC_MSG_NOTICE("Do not use MSSE = ${MSSE} because not available on arch ${host}") ;; esac dnl CFLAGS="-O3 -fomit-frame-pointer -funroll-loops -Wall ${ARCH_flag}" dnl CFLAGS="-O3 -Wfloat-equal -fomit-frame-pointer -funroll-loops" dnl CFLAGS="-O3 -Wfloat-equal" dnl CFLAGS="-g" LDFLAGS="${ARGC_flag}" LT_INIT AC_PROG_LIBTOOL dnl Add option for compiling with debugging informations AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [Remove optimization options and add debug informations.])]) AS_IF([test "x$enable_debug" = "xyes"], [CFLAGS="-ansi -pedantic -Wall -std=c99 -O0 -g -Wuninitialized"], [CFLAGS="-Wall -O2 ${MSSE} -fomit-frame-pointer -funroll-loops -Wempty-body -Wuninitialized ${ARCH_flag}"]) AC_ARG_ENABLE([gprof], [AS_HELP_STRING([--enable-gprof], [Remove optimization options and add profiling informations.])]) AS_IF([test "x$enable_gprof" = "xyes"], [CFLAGS="-ansi -pedantic -Wall -std=c99 -O0 -g -pg"], [AS_IF([test "x$enable_debug" = "xno"],[CFLAGS="-Wall -O2 -msse -fomit-frame-pointer -funroll-loops ${ARCH_flag}"])]) AC_ARG_ENABLE([mpi], [AS_HELP_STRING([--enable-mpi], [Compile with mpicc instead of gcc.])]) AS_IF([test "x$enable_mpi" = "xyes"],[CC="mpicc"]) AS_IF([test "x$enable_mpi" = "xyes"],AC_DEFINE([MPI],[1],[MPI tag on])) AM_CONDITIONAL([WANT_MPI], [test "x$enable_mpi" = "xyes"]) AC_ARG_ENABLE([win], [AS_HELP_STRING([--enable-win], [Compile with mingw instead of gcc.])]) AS_IF([test "x$enable_win" = "xyes"],[CC="i686-w64-mingw32-gcc"]) AC_ARG_ENABLE([beagle], [AS_HELP_STRING([--enable-beagle], [Compute likelihoods using BEAGLE library.])], [beagle=yes],[beagle=no]) AS_IF([test "x$enable_beagle" = "xyes"],[PKG_CHECK_MODULES(BEAGLE, hmsbeagle-1)]) AS_IF([test "x$enable_beagle" = "xyes"], [CFLAGS="${CFLAGS} ${BEAGLE_CFLAGS} ${BEAGLE_LIBS} -lstdc++ ${ARCH_flag}"], [CFLAGS=${CFLAGS}]) AS_IF([test "x$enable_beagle" = "xyes"], AC_DEFINE([BEAGLE],[1],[BEAGLE tag on])) AM_CONDITIONAL([WANT_BEAGLE], [test "$enable_beagle" = yes]) AC_ARG_ENABLE([phytime],[AS_HELP_STRING([--enable-phytime],[Compile PhyTime])],[phytime=yes],[phytime=no]) AM_CONDITIONAL([WANT_PHYTIME], [test "$phytime" = yes]) if test "$phytime" = yes; then AC_DEFINE([PHYTIME],[1],[PHYTIME tag on]) fi AC_ARG_ENABLE([tiporder],[AS_HELP_STRING([--enable-tiporder],[Compile tiporder])],[tiporder=yes],[tiporder=no]) AM_CONDITIONAL([WANT_TIPORDER], [test "$tiporder" = yes]) if test "$tiporder" = yes; then AC_DEFINE([TIPORDER],[1],[TIPORDER tag on]) fi AC_ARG_ENABLE([part],[AS_HELP_STRING([--enable-part],[Compile Part])],[part=yes],[part=no]) AM_CONDITIONAL([WANT_PART], [test "$part" = yes]) if test "$part" = yes; then AC_DEFINE([PART],[1],[PART tag on]) fi AC_ARG_ENABLE([rwrap],[AS_HELP_STRING([--enable-rwrap],[Compile Rwrap])],[rwrap=yes],[rwrap=no]) AM_CONDITIONAL([WANT_RWRAP], [test "$rwrap" = yes]) if test "$rwrap" = yes; then AC_DEFINE([RWRAP],[1],[RWRAP tag on]) fi AC_ARG_ENABLE([phycont],[AS_HELP_STRING([--enable-phycont],[Compile PhyCont])],[phycont=yes],[phycont=no]) AM_CONDITIONAL([WANT_PHYCONT], [test "$phycont" = yes]) if test "$phycont" = yes; then AC_DEFINE([PHYCONT],[1],[PHYCONT tag on]) fi AC_ARG_ENABLE([m4],[AS_HELP_STRING([--enable-m4],[Compile M4])],[m4=yes],[m4=no]) AM_CONDITIONAL([WANT_M4], [test "$m4" = yes]) if test "$m4" = yes; then AC_DEFINE([M4],[1],[m4 tag on]) fi AC_ARG_ENABLE([rf],[AS_HELP_STRING([--enable-rf],[Compile RF])],[rf=yes],[rf=no]) AM_CONDITIONAL([WANT_RF], [test "$rf" = yes]) if test "$rf" = yes; then AC_DEFINE([RF],[1],[RF tag on]) fi AC_ARG_ENABLE([test],[AS_HELP_STRING([--enable-test],[Compile test])],[test=yes],[test=no]) AM_CONDITIONAL([WANT_TEST], [test "$test" = yes]) if test "$test" = yes; then AC_DEFINE([TEST],[1],[TEST tag on]) fi AC_ARG_ENABLE([evolve],[AS_HELP_STRING([--enable-evolve],[Compile evolve])],[evolve=yes],[evolve=no]) AM_CONDITIONAL([WANT_EVOLVE], [test "$evolve" = yes]) if test "$evolve" = yes; then AC_DEFINE([EVOLVE],[1],[EVOLVE tag on]) fi AC_ARG_ENABLE([invitee],[AS_HELP_STRING([--enable-invitee],[Compile invitee])],[invitee=yes],[invitee=no]) AM_CONDITIONAL([WANT_INVITEE], [test "$invitee" = yes]) if test "$invitee" = yes; then AC_DEFINE([INVITEE],[1],[INVITEE tag on]) fi AC_ARG_ENABLE([geo],[AS_HELP_STRING([--enable-geo],[Compile geo])],[geo=yes],[geo=no]) AM_CONDITIONAL([WANT_GEO], [test "$geo" = yes]) if test "$geo" = yes; then AC_DEFINE([GEO],[1],[GEO tag on]) fi AC_ARG_ENABLE([checkpoint],[AS_HELP_STRING([--enable-checkpoint],[Compile checkpoint])],[checkpoint=yes],[checkpoint=no]) AM_CONDITIONAL([WANT_CHECKPOINT], [test "$checkpoint" = yes]) if test "$checkpoint" = yes; then AC_DEFINE([CHECKPOINT],[1],[CHECKPOINT tag on]) fi AC_ARG_ENABLE([phyrex],[AS_HELP_STRING([--enable-phyrex],[Compile phyrex])],[phyrex=yes],[phyrex=no]) AM_CONDITIONAL([WANT_PHYREX], [test "$phyrex" = yes]) if test "$phyrex" = yes; then AC_DEFINE([PHYREX],[1],[PHYREX tag on]) fi dnl AS_IF([test "x$enable_phyrex" = "xyes"],[PKG_CHECK_MODULES([GTK], [gtk+-3.0])]) dnl AS_IF([test "x$enable_phyrex" = "xyes"],[PKG_CHECK_MODULES([CAIRO], [cairo])]) dnl AS_IF([test "x$enable_phyrex" = "xyes"],[CFLAGS="${CFLAGS} `pkg-config --cflags --libs gtk+-3.0` ${ARCH_flag}"]) dnl AM_PATH_GTK_3_0(,,AC_MSG_ERROR(windoe-default needs GTK+-3)) if test "$phytime" = no; then if test "$tiporder" = no; then if test "$part" = no; then if test "$rwrap" = no; then if test "$phycont" = no; then if test "$m4" = no; then if test "$test" = no; then if test "$invitee" = no; then if test "$geo" = no; then if test "$evolve" = no; then if test "$checkpoint" = no; then if test "$phyrex" = no; then AC_DEFINE([PHYML],[1],[PHYML tag on]) fi fi fi fi fi fi fi fi fi fi fi fi AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile]) AC_OUTPUT phyml-3.2.0/confmc000077500000000000000000000001751263450375500140550ustar00rootroot00000000000000#!/bin/bash -x aclocal; autoheader; autoconf -f; automake -f --add-missing; ./configure --enable-phytime; make clean; make; phyml-3.2.0/confr000077500000000000000000000001731263450375500137150ustar00rootroot00000000000000#!/bin/bash -x aclocal; autoheader; autoconf -f; automake -f --add-missing; ./configure --enable-rwrap; make clean; make; phyml-3.2.0/confrf000077500000000000000000000001701263450375500140600ustar00rootroot00000000000000#!/bin/bash -x aclocal; autoheader; autoconf -f; automake -f --add-missing; ./configure --enable-rf; make clean; make; phyml-3.2.0/doc/000077500000000000000000000000001263450375500134245ustar00rootroot00000000000000phyml-3.2.0/doc/Makefile.am000066400000000000000000000011721263450375500154610ustar00rootroot00000000000000 docdir = $(datadir)/doc docfiles = phyml-manual.tex if HAVE_PDFLATEX docfiles += phyml-manual.pdf endif MANNAME = phyml-manual MANTEXSRC = $(MANNAME).tex MANIDX = $(MANNAME).idx CLEANFILES = $(MANNAME).pdf $(MANNAME).log $(MANNAME).idx $(MANNAME).out \ $(MANNAME).toc $(MANNAME).aux $(MANNAME).ilg $(MANNAME).ind $(MANNAME).dvi latex: $(MANTEXSRC) latex $< pdflatex: $(MANTEXSRC) pdflatex $< makeindex: $(MANIDX) makeindex $< phyml-manual.pdf: intro latex makeindex pdflatex @echo "" @echo "Done." intro: @echo "" @echo "" @echo ".: Building documentation :." @echo "" @echo "" dist_doc_DATA = $(docfiles) phyml-3.2.0/doc/naturemag.bst000066400000000000000000001070471263450375500161320ustar00rootroot00000000000000%% %% This is file `naturemag.bst', %% generated with the docstrip utility. %% %% The original source files were: %% %% merlin.mbs (with options: `head,seq-no,nm-rev,ed-rev,jnrlst,nmlm,x5,m1,yr-par,xmth,vol-bf,vnum-x,volp-com,num-xser,jnm-x,bkpg-x,pub-date,edparxc,ppx,ed,abr,xedn,jabr,amper,and-xcom,etal-it,eprint,url,url-blk,bibinfo,nfss,{}') %% physjour.mbs (with options: `seq-no,nm-rev,ed-rev,jnrlst,nmlm,x5,m1,yr-par,xmth,vol-bf,vnum-x,volp-com,num-xser,jnm-x,bkpg-x,pub-date,edparxc,ppx,ed,abr,xedn,jabr,amper,and-xcom,etal-it,eprint,url,url-blk,bibinfo,nfss,{}') %% geojour.mbs (with options: `seq-no,nm-rev,ed-rev,jnrlst,nmlm,x5,m1,yr-par,xmth,vol-bf,vnum-x,volp-com,num-xser,jnm-x,bkpg-x,pub-date,edparxc,ppx,ed,abr,xedn,jabr,amper,and-xcom,etal-it,eprint,url,url-blk,bibinfo,nfss,{}') %% photjour.mbs (with options: `seq-no,nm-rev,ed-rev,jnrlst,nmlm,x5,m1,yr-par,xmth,vol-bf,vnum-x,volp-com,num-xser,jnm-x,bkpg-x,pub-date,edparxc,ppx,ed,abr,xedn,jabr,amper,and-xcom,etal-it,eprint,url,url-blk,bibinfo,nfss,{}') %% merlin.mbs (with options: `tail,seq-no,nm-rev,ed-rev,jnrlst,nmlm,x5,m1,yr-par,xmth,vol-bf,vnum-x,volp-com,num-xser,jnm-x,bkpg-x,pub-date,edparxc,ppx,ed,abr,xedn,jabr,amper,and-xcom,etal-it,eprint,url,url-blk,bibinfo,nfss,{}') %% ---------------------------------------- %% *** Style for the journal Nature (created by Peter Czoschke) *** %% %% Copyright 1994-2002 Patrick W Daly % =============================================================== % IMPORTANT NOTICE: % This bibliographic style (bst) file has been generated from one or % more master bibliographic style (mbs) files, listed above. % % This generated file can be redistributed and/or modified under the terms % of the LaTeX Project Public License Distributed from CTAN % archives in directory macros/latex/base/lppl.txt; either % version 1 of the License, or any later version. % =============================================================== % Name and version information of the main mbs file: % \ProvidesFile{merlin.mbs}[2002/10/21 4.05 (PWD, AO, DPC)] % For use with BibTeX version 0.99a or later %------------------------------------------------------------------- % This bibliography style file is intended for texts in ENGLISH % This is a numerical citation style, and as such is standard LaTeX. % It requires no extra package to interface to the main text. % The form of the \bibitem entries is % \bibitem{key}... % Usage of \cite is as follows: % \cite{key} ==>> [#] % \cite[chap. 2]{key} ==>> [#, chap. 2] % where # is a number determined by the ordering in the reference list. % The order in the reference list is that by which the works were originally % cited in the text, or that in the database. %--------------------------------------------------------------------- ENTRY { address archive author booktitle chapter edition editor eprint howpublished institution journal key month note number organization pages publisher school series title type url volume year } {} { label } INTEGERS { output.state before.all mid.sentence after.sentence after.block } FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := #2 'after.sentence := #3 'after.block := } STRINGS { s t} FUNCTION {output.nonnull} { 's := output.state mid.sentence = { ", " * write$ } { output.state after.block = { add.period$ write$ newline$ "\newblock " write$ } { output.state before.all = 'write$ { add.period$ " " * write$ } if$ } if$ mid.sentence 'output.state := } if$ s } FUNCTION {output} { duplicate$ empty$ 'pop$ 'output.nonnull if$ } FUNCTION {output.check} { 't := duplicate$ empty$ { pop$ "empty " t * " in " * cite$ * warning$ } 'output.nonnull if$ } FUNCTION {fin.entry} { add.period$ write$ newline$ } FUNCTION {new.block} { output.state before.all = 'skip$ { after.block 'output.state := } if$ } FUNCTION {new.sentence} { output.state after.block = 'skip$ { output.state before.all = 'skip$ { after.sentence 'output.state := } if$ } if$ } FUNCTION {add.blank} { " " * before.all 'output.state := } FUNCTION {date.block} { new.block } FUNCTION {not} { { #0 } { #1 } if$ } FUNCTION {and} { 'skip$ { pop$ #0 } if$ } FUNCTION {or} { { pop$ #1 } 'skip$ if$ } FUNCTION {new.block.checka} { empty$ 'skip$ 'new.block if$ } FUNCTION {new.block.checkb} { empty$ swap$ empty$ and 'skip$ 'new.block if$ } FUNCTION {new.sentence.checka} { empty$ 'skip$ 'new.sentence if$ } FUNCTION {new.sentence.checkb} { empty$ swap$ empty$ and 'skip$ 'new.sentence if$ } FUNCTION {field.or.null} { duplicate$ empty$ { pop$ "" } 'skip$ if$ } FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } { "\emph{" swap$ * "}" * } if$ } FUNCTION {bolden} { duplicate$ empty$ { pop$ "" } { "\textbf{" swap$ * "}" * } if$ } FUNCTION {tie.or.space.prefix} { duplicate$ text.length$ #3 < { "~" } { " " } if$ swap$ } FUNCTION {capitalize} { "u" change.case$ "t" change.case$ } FUNCTION {space.word} { " " swap$ * " " * } % Here are the language-specific definitions for explicit words. % Each function has a name bbl.xxx where xxx is the English word. % The language selected here is ENGLISH FUNCTION {bbl.and} { "and"} FUNCTION {bbl.etal} { "et~al." } FUNCTION {bbl.editors} { "eds." } FUNCTION {bbl.editor} { "ed." } FUNCTION {bbl.edby} { "edited by" } FUNCTION {bbl.edition} { "edn." } FUNCTION {bbl.volume} { "vol." } FUNCTION {bbl.of} { "of" } FUNCTION {bbl.number} { "no." } FUNCTION {bbl.nr} { "no." } FUNCTION {bbl.in} { "in" } FUNCTION {bbl.pages} { "" } FUNCTION {bbl.page} { "" } FUNCTION {bbl.chapter} { "chap." } FUNCTION {bbl.techrep} { "Tech. Rep." } FUNCTION {bbl.mthesis} { "Master's thesis" } FUNCTION {bbl.phdthesis} { "Ph.D. thesis" } MACRO {jan} {"Jan."} MACRO {feb} {"Feb."} MACRO {mar} {"Mar."} MACRO {apr} {"Apr."} MACRO {may} {"May"} MACRO {jun} {"Jun."} MACRO {jul} {"Jul."} MACRO {aug} {"Aug."} MACRO {sep} {"Sep."} MACRO {oct} {"Oct."} MACRO {nov} {"Nov."} MACRO {dec} {"Dec."} %------------------------------------------------------------------- % Begin module: % \ProvidesFile{physjour.mbs}[2002/01/14 2.2 (PWD)] MACRO {aa}{"Astron. \& Astrophys."} MACRO {aasup}{"Astron. \& Astrophys. Suppl. Ser."} MACRO {aj} {"Astron. J."} MACRO {aph} {"Acta Phys."} MACRO {advp} {"Adv. Phys."} MACRO {ajp} {"Amer. J. Phys."} MACRO {ajm} {"Amer. J. Math."} MACRO {amsci} {"Amer. Sci."} MACRO {anofd} {"Ann. Fluid Dyn."} MACRO {am} {"Ann. Math."} MACRO {ap} {"Ann. Phys. (NY)"} MACRO {adp} {"Ann. Phys. (Leipzig)"} MACRO {ao} {"Appl. Opt."} MACRO {apl} {"Appl. Phys. Lett."} MACRO {app} {"Astroparticle Phys."} MACRO {apj} {"Astrophys. J."} MACRO {apjsup} {"Astrophys. J. Suppl."} MACRO {apss} {"Astrophys. Space Sci."} MACRO {araa} {"Ann. Rev. Astron. Astrophys."} MACRO {baas} {"Bull. Amer. Astron. Soc."} MACRO {baps} {"Bull. Amer. Phys. Soc."} MACRO {cmp} {"Comm. Math. Phys."} MACRO {cpam} {"Commun. Pure Appl. Math."} MACRO {cppcf} {"Comm. Plasma Phys. \& Controlled Fusion"} MACRO {cpc} {"Comp. Phys. Comm."} MACRO {cqg} {"Class. Quant. Grav."} MACRO {cra} {"C. R. Acad. Sci. A"} MACRO {fed} {"Fusion Eng. \& Design"} MACRO {ft} {"Fusion Tech."} MACRO {grg} {"Gen. Relativ. Gravit."} MACRO {ieeens} {"IEEE Trans. Nucl. Sci."} MACRO {ieeeps} {"IEEE Trans. Plasma Sci."} MACRO {ijimw} {"Interntl. J. Infrared \& Millimeter Waves"} MACRO {ip} {"Infrared Phys."} MACRO {irp} {"Infrared Phys."} MACRO {jap} {"J. Appl. Phys."} MACRO {jasa} {"J. Acoust. Soc. America"} MACRO {jcp} {"J. Comp. Phys."} MACRO {jetp} {"Sov. Phys.--JETP"} MACRO {jfe} {"J. Fusion Energy"} MACRO {jfm} {"J. Fluid Mech."} MACRO {jmp} {"J. Math. Phys."} MACRO {jne} {"J. Nucl. Energy"} MACRO {jnec} {"J. Nucl. Energy, C: Plasma Phys., Accelerators, Thermonucl. Res."} MACRO {jnm} {"J. Nucl. Mat."} MACRO {jpc} {"J. Phys. Chem."} MACRO {jpp} {"J. Plasma Phys."} MACRO {jpsj} {"J. Phys. Soc. Japan"} MACRO {jsi} {"J. Sci. Instrum."} MACRO {jvst} {"J. Vac. Sci. \& Tech."} MACRO {nat} {"Nature"} MACRO {nature} {"Nature"} MACRO {nedf} {"Nucl. Eng. \& Design/Fusion"} MACRO {nf} {"Nucl. Fusion"} MACRO {nim} {"Nucl. Inst. \& Meth."} MACRO {nimpr} {"Nucl. Inst. \& Meth. in Phys. Res."} MACRO {np} {"Nucl. Phys."} MACRO {npb} {"Nucl. Phys. B"} MACRO {nt/f} {"Nucl. Tech./Fusion"} MACRO {npbpc} {"Nucl. Phys. B (Proc. Suppl.)"} MACRO {inc} {"Nuovo Cimento"} MACRO {nc} {"Nuovo Cimento"} MACRO {pf} {"Phys. Fluids"} MACRO {pfa} {"Phys. Fluids A: Fluid Dyn."} MACRO {pfb} {"Phys. Fluids B: Plasma Phys."} MACRO {pl} {"Phys. Lett."} MACRO {pla} {"Phys. Lett. A"} MACRO {plb} {"Phys. Lett. B"} MACRO {prep} {"Phys. Rep."} MACRO {pnas} {"Proc. Nat. Acad. Sci. USA"} MACRO {pp} {"Phys. Plasmas"} MACRO {ppcf} {"Plasma Phys. \& Controlled Fusion"} MACRO {phitrsl} {"Philos. Trans. Roy. Soc. London"} MACRO {prl} {"Phys. Rev. Lett."} MACRO {pr} {"Phys. Rev."} MACRO {physrev} {"Phys. Rev."} MACRO {pra} {"Phys. Rev. A"} MACRO {prb} {"Phys. Rev. B"} MACRO {prc} {"Phys. Rev. C"} MACRO {prd} {"Phys. Rev. D"} MACRO {pre} {"Phys. Rev. E"} MACRO {ps} {"Phys. Scripta"} MACRO {procrsl} {"Proc. Roy. Soc. London"} MACRO {rmp} {"Rev. Mod. Phys."} MACRO {rsi} {"Rev. Sci. Inst."} MACRO {science} {"Science"} MACRO {sciam} {"Sci. Am."} MACRO {sam} {"Stud. Appl. Math."} MACRO {sjpp} {"Sov. J. Plasma Phys."} MACRO {spd} {"Sov. Phys.--Doklady"} MACRO {sptp} {"Sov. Phys.--Tech. Phys."} MACRO {spu} {"Sov. Phys.--Uspeki"} MACRO {st} {"Sky and Telesc."} % End module: physjour.mbs %------------------------------------------------------------------- % Begin module: % \ProvidesFile{geojour.mbs}[2002/07/10 2.0h (PWD)] MACRO {aisr} {"Adv. Space Res."} MACRO {ag} {"Ann. Geophys."} MACRO {anigeo} {"Ann. Geofis."} MACRO {angl} {"Ann. Glaciol."} MACRO {andmet} {"Ann. d. Meteor."} MACRO {andgeo} {"Ann. d. Geophys."} MACRO {andphy} {"Ann. Phys.-Paris"} MACRO {afmgb} {"Arch. Meteor. Geophys. Bioklimatol."} MACRO {atph} {"Atm\'osphera"} MACRO {aao} {"Atmos. Ocean"} MACRO {ass}{"Astrophys. Space Sci."} MACRO {atenv} {"Atmos. Environ."} MACRO {aujag} {"Aust. J. Agr. Res."} MACRO {aumet} {"Aust. Meteorol. Mag."} MACRO {blmet} {"Bound.-Lay. Meteorol."} MACRO {bams} {"Bull. Amer. Meteorol. Soc."} MACRO {cch} {"Clim. Change"} MACRO {cdyn} {"Clim. Dynam."} MACRO {cbul} {"Climatol. Bull."} MACRO {cap} {"Contrib. Atmos. Phys."} MACRO {dsr} {"Deep-Sea Res."} MACRO {dhz} {"Dtsch. Hydrogr. Z."} MACRO {dao} {"Dynam. Atmos. Oceans"} MACRO {eco} {"Ecology"} MACRO {empl}{"Earth, Moon and Planets"} MACRO {envres} {"Environ. Res."} MACRO {envst} {"Environ. Sci. Technol."} MACRO {ecms} {"Estuarine Coastal Mar. Sci."} MACRO {expa}{"Exper. Astron."} MACRO {geoint} {"Geofis. Int."} MACRO {geopub} {"Geofys. Publ."} MACRO {geogeo} {"Geol. Geofiz."} MACRO {gafd} {"Geophys. Astrophys. Fluid Dyn."} MACRO {gfd} {"Geophys. Fluid Dyn."} MACRO {geomag} {"Geophys. Mag."} MACRO {georl} {"Geophys. Res. Lett."} MACRO {grl} {"Geophys. Res. Lett."} MACRO {ga} {"Geophysica"} MACRO {gs} {"Geophysics"} MACRO {ieeetap} {"IEEE Trans. Antenn. Propag."} MACRO {ijawp} {"Int. J. Air Water Pollut."} MACRO {ijc} {"Int. J. Climatol."} MACRO {ijrs} {"Int. J. Remote Sens."} MACRO {jam} {"J. Appl. Meteorol."} MACRO {jaot} {"J. Atmos. Ocean. Technol."} MACRO {jatp} {"J. Atmos. Terr. Phys."} MACRO {jastp} {"J. Atmos. Solar-Terr. Phys."} MACRO {jce} {"J. Climate"} MACRO {jcam} {"J. Climate Appl. Meteor."} MACRO {jcm} {"J. Climate Meteor."} MACRO {jcy} {"J. Climatol."} MACRO {jgr} {"J. Geophys. Res."} MACRO {jga} {"J. Glaciol."} MACRO {jh} {"J. Hydrol."} MACRO {jmr} {"J. Mar. Res."} MACRO {jmrj} {"J. Meteor. Res. Japan"} MACRO {jm} {"J. Meteor."} MACRO {jpo} {"J. Phys. Oceanogr."} MACRO {jra} {"J. Rech. Atmos."} MACRO {jaes} {"J. Aeronaut. Sci."} MACRO {japca} {"J. Air Pollut. Control Assoc."} MACRO {jas} {"J. Atmos. Sci."} MACRO {jmts} {"J. Mar. Technol. Soc."} MACRO {jmsj} {"J. Meteorol. Soc. Japan"} MACRO {josj} {"J. Oceanogr. Soc. Japan"} MACRO {jwm} {"J. Wea. Mod."} MACRO {lao} {"Limnol. Oceanogr."} MACRO {mwl} {"Mar. Wea. Log"} MACRO {mau} {"Mausam"} MACRO {meteor} {"``Meteor'' Forschungsergeb."} MACRO {map} {"Meteorol. Atmos. Phys."} MACRO {metmag} {"Meteor. Mag."} MACRO {metmon} {"Meteor. Monogr."} MACRO {metrun} {"Meteor. Rundsch."} MACRO {metzeit} {"Meteor. Z."} MACRO {metgid} {"Meteor. Gidrol."} MACRO {mwr} {"Mon. Weather Rev."} MACRO {nwd} {"Natl. Weather Dig."} MACRO {nzjmfr} {"New Zeal. J. Mar. Freshwater Res."} MACRO {npg} {"Nonlin. Proc. Geophys."} MACRO {om} {"Oceanogr. Meteorol."} MACRO {ocac} {"Oceanol. Acta"} MACRO {oceanus} {"Oceanus"} MACRO {paleoc} {"Paleoceanography"} MACRO {pce} {"Phys. Chem. Earth"} MACRO {pmg} {"Pap. Meteor. Geophys."} MACRO {ppom} {"Pap. Phys. Oceanogr. Meteor."} MACRO {physzeit} {"Phys. Z."} MACRO {pps} {"Planet. Space Sci."} MACRO {pss} {"Planet. Space Sci."} MACRO {pag} {"Pure Appl. Geophys."} MACRO {qjrms} {"Quart. J. Roy. Meteorol. Soc."} MACRO {quatres} {"Quat. Res."} MACRO {rsci} {"Radio Sci."} MACRO {rse} {"Remote Sens. Environ."} MACRO {rgeo} {"Rev. Geophys."} MACRO {rgsp} {"Rev. Geophys. Space Phys."} MACRO {rdgeo} {"Rev. Geofis."} MACRO {revmeta} {"Rev. Meteorol."} MACRO {sgp}{"Surveys in Geophys."} MACRO {sp} {"Solar Phys."} MACRO {ssr} {"Space Sci. Rev."} MACRO {tellus} {"Tellus"} MACRO {tac} {"Theor. Appl. Climatol."} MACRO {tagu} {"Trans. Am. Geophys. Union (EOS)"} MACRO {wrr} {"Water Resour. Res."} MACRO {weather} {"Weather"} MACRO {wafc} {"Weather Forecast."} MACRO {ww} {"Weatherwise"} MACRO {wmob} {"WMO Bull."} MACRO {zeitmet} {"Z. Meteorol."} % End module: geojour.mbs %------------------------------------------------------------------- % Begin module: % \ProvidesFile{photjour.mbs}[1999/02/24 2.0b (PWD)] MACRO {appopt} {"Appl. Opt."} MACRO {bell} {"Bell Syst. Tech. J."} MACRO {ell} {"Electron. Lett."} MACRO {jasp} {"J. Appl. Spectr."} MACRO {jqe} {"IEEE J. Quantum Electron."} MACRO {jlwt} {"J. Lightwave Technol."} MACRO {jmo} {"J. Mod. Opt."} MACRO {josa} {"J. Opt. Soc. America"} MACRO {josaa} {"J. Opt. Soc. Amer.~A"} MACRO {josab} {"J. Opt. Soc. Amer.~B"} MACRO {jdp} {"J. Phys. (Paris)"} MACRO {oc} {"Opt. Commun."} MACRO {ol} {"Opt. Lett."} MACRO {phtl} {"IEEE Photon. Technol. Lett."} MACRO {pspie} {"Proc. Soc. Photo-Opt. Instrum. Eng."} MACRO {sse} {"Solid-State Electron."} MACRO {sjot} {"Sov. J. Opt. Technol."} MACRO {sjqe} {"Sov. J. Quantum Electron."} MACRO {sleb} {"Sov. Phys.--Leb. Inst. Rep."} MACRO {stph} {"Sov. Phys.--Techn. Phys."} MACRO {stphl} {"Sov. Techn. Phys. Lett."} MACRO {vr} {"Vision Res."} MACRO {zph} {"Z. f. Physik"} MACRO {zphb} {"Z. f. Physik~B"} MACRO {zphd} {"Z. f. Physik~D"} MACRO {CLEO} {"CLEO"} MACRO {ASSL} {"Adv. Sol.-State Lasers"} MACRO {OSA} {"OSA"} % End module: photjour.mbs %% Copyright 1994-2002 Patrick W Daly MACRO {acmcs} {"ACM Comput. Surv."} MACRO {acta} {"Acta Inf."} MACRO {cacm} {"Commun. ACM"} MACRO {ibmjrd} {"IBM J. Res. Dev."} MACRO {ibmsj} {"IBM Syst.~J."} MACRO {ieeese} {"IEEE Trans. Software Eng."} MACRO {ieeetc} {"IEEE Trans. Comput."} MACRO {ieeetcad} {"IEEE Trans. Comput. Aid. Des."} MACRO {ipl} {"Inf. Process. Lett."} MACRO {jacm} {"J.~ACM"} MACRO {jcss} {"J.~Comput. Syst. Sci."} MACRO {scp} {"Sci. Comput. Program."} MACRO {sicomp} {"SIAM J. Comput."} MACRO {tocs} {"ACM Trans. Comput. Syst."} MACRO {tods} {"ACM Trans. Database Syst."} MACRO {tog} {"ACM Trans. Graphic."} MACRO {toms} {"ACM Trans. Math. Software"} MACRO {toois} {"ACM Trans. Office Inf. Syst."} MACRO {toplas} {"ACM Trans. Progr. Lang. Syst."} MACRO {tcs} {"Theor. Comput. Sci."} FUNCTION {bibinfo.check} { swap$ duplicate$ missing$ { pop$ pop$ "" } { duplicate$ empty$ { swap$ pop$ } { swap$ "\bibinfo{" swap$ * "}{" * swap$ * "}" * } if$ } if$ } FUNCTION {bibinfo.warn} { swap$ duplicate$ missing$ { swap$ "missing " swap$ * " in " * cite$ * warning$ pop$ "" } { duplicate$ empty$ { swap$ "empty " swap$ * " in " * cite$ * warning$ } { swap$ "\bibinfo{" swap$ * "}{" * swap$ * "}" * } if$ } if$ } FUNCTION {format.eprint} { eprint duplicate$ empty$ 'skip$ { "\eprint" archive empty$ 'skip$ { "[" * archive * "]" * } if$ "{" * swap$ * "}" * } if$ } FUNCTION {format.url} { url empty$ { "" } { "\urlprefix\url{" url * "}" * } if$ } STRINGS { bibinfo} INTEGERS { nameptr namesleft numnames } FUNCTION {format.names} { 'bibinfo := duplicate$ empty$ 'skip$ { 's := "" 't := #1 'nameptr := s num.names$ 'numnames := numnames 'namesleft := { namesleft #0 > } { s nameptr "{vv~}{ll}{, f.}{, jj}" format.name$ bibinfo bibinfo.check 't := nameptr #1 > { nameptr #1 #1 + = numnames #5 > and { "others" 't := #1 'namesleft := } 'skip$ if$ namesleft #1 > { ", " * t * } { s nameptr "{ll}" format.name$ duplicate$ "others" = { 't := } { pop$ } if$ t "others" = { " " * bbl.etal emphasize * } { "\&" space.word * t * } if$ } if$ } 't if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := } while$ } if$ } FUNCTION {format.names.ed} { format.names } FUNCTION {format.authors} { author "author" format.names } FUNCTION {get.bbl.editor} { editor num.names$ #1 > 'bbl.editors 'bbl.editor if$ } FUNCTION {format.editors} { editor "editor" format.names duplicate$ empty$ 'skip$ { " " * get.bbl.editor "(" swap$ * ")" * * } if$ } FUNCTION {format.note} { note empty$ { "" } { note #1 #1 substring$ duplicate$ "{" = 'skip$ { output.state mid.sentence = { "l" } { "u" } if$ change.case$ } if$ note #2 global.max$ substring$ * "note" bibinfo.check } if$ } FUNCTION {format.title} { title duplicate$ empty$ 'skip$ { "t" change.case$ } if$ "title" bibinfo.check } FUNCTION {output.bibitem} { newline$ "\bibitem{" write$ cite$ write$ "}" write$ newline$ "" before.all 'output.state := } FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = { t #1 #2 substring$ "--" = not { "--" * t #2 global.max$ substring$ 't := } { { t #1 #1 substring$ "-" = } { "-" * t #2 global.max$ substring$ 't := } while$ } if$ } { t #1 #1 substring$ * t #2 global.max$ substring$ 't := } if$ } while$ } FUNCTION {word.in} { bbl.in capitalize " " * } FUNCTION {format.date} { "" duplicate$ empty$ year "year" bibinfo.check duplicate$ empty$ { swap$ 'skip$ { "there's a month but no year in " cite$ * warning$ } if$ * } { swap$ 'skip$ { swap$ " " * swap$ } if$ * } if$ duplicate$ empty$ 'skip$ { before.all 'output.state := " (" swap$ * ")" * } if$ } FUNCTION {format.btitle} { title "title" bibinfo.check duplicate$ empty$ 'skip$ { emphasize } if$ } FUNCTION {either.or.check} { empty$ 'pop$ { "can't use both " swap$ * " fields in " * cite$ * warning$ } if$ } FUNCTION {format.bvolume} { volume empty$ { "" } { bbl.volume volume tie.or.space.prefix "volume" bibinfo.check * * series "series" bibinfo.check duplicate$ empty$ 'pop$ { swap$ bbl.of space.word * swap$ emphasize * } if$ "volume and number" number either.or.check } if$ } FUNCTION {format.number.series} { volume empty$ { number empty$ { series field.or.null } { series empty$ { number "number" bibinfo.check } { output.state mid.sentence = { bbl.number } { bbl.number capitalize } if$ number tie.or.space.prefix "number" bibinfo.check * * bbl.in space.word * series "series" bibinfo.check * } if$ } if$ } { "" } if$ } FUNCTION {format.edition} { edition duplicate$ empty$ 'skip$ { output.state mid.sentence = { "l" } { "t" } if$ change.case$ "edition" bibinfo.check " " * bbl.edition * } if$ } INTEGERS { multiresult } FUNCTION {multi.page.check} { 't := #0 'multiresult := { multiresult not t empty$ not and } { t #1 #1 substring$ duplicate$ "-" = swap$ duplicate$ "," = swap$ "+" = or or { #1 'multiresult := } { t #2 global.max$ substring$ 't := } if$ } while$ multiresult } FUNCTION {format.pages} { pages duplicate$ empty$ 'skip$ { duplicate$ multi.page.check { n.dashify } { } if$ "pages" bibinfo.check } if$ } FUNCTION {format.journal.pages} { pages duplicate$ empty$ 'pop$ { swap$ duplicate$ empty$ { pop$ pop$ format.pages } { ", " * swap$ n.dashify "pages" bibinfo.check * } if$ } if$ } FUNCTION {format.vol.num.pages} { volume field.or.null duplicate$ empty$ 'skip$ { "volume" bibinfo.check } if$ bolden format.journal.pages } FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ { bbl.chapter } { type "l" change.case$ "type" bibinfo.check } if$ chapter tie.or.space.prefix "chapter" bibinfo.check * * pages empty$ 'skip$ { ", " * format.pages * } if$ } if$ } FUNCTION {format.booktitle} { booktitle "booktitle" bibinfo.check emphasize } FUNCTION {format.in.ed.booktitle} { format.booktitle duplicate$ empty$ 'skip$ { editor "editor" format.names.ed duplicate$ empty$ 'pop$ { " " * get.bbl.editor "(" swap$ * ") " * * swap$ * } if$ word.in swap$ * } if$ } FUNCTION {empty.misc.check} { author empty$ title empty$ howpublished empty$ month empty$ year empty$ note empty$ and and and and and { "all relevant fields are empty in " cite$ * warning$ } 'skip$ if$ } FUNCTION {format.thesis.type} { type duplicate$ empty$ 'pop$ { swap$ pop$ "t" change.case$ "type" bibinfo.check } if$ } FUNCTION {format.tr.number} { number "number" bibinfo.check type duplicate$ empty$ { pop$ bbl.techrep } 'skip$ if$ "type" bibinfo.check swap$ duplicate$ empty$ { pop$ "t" change.case$ } { tie.or.space.prefix * * } if$ } FUNCTION {format.article.crossref} { key duplicate$ empty$ { pop$ journal duplicate$ empty$ { "need key or journal for " cite$ * " to crossref " * crossref * warning$ } { "journal" bibinfo.check emphasize word.in swap$ * } if$ } { word.in swap$ * " " *} if$ " \cite{" * crossref * "}" * } FUNCTION {format.crossref.editor} { editor #1 "{vv~}{ll}" format.name$ "editor" bibinfo.check editor num.names$ duplicate$ #2 > { pop$ "editor" bibinfo.check " " * bbl.etal emphasize * } { #2 < 'skip$ { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = { "editor" bibinfo.check " " * bbl.etal emphasize * } { " \& " * editor #2 "{vv~}{ll}" format.name$ "editor" bibinfo.check * } if$ } if$ } if$ } FUNCTION {format.book.crossref} { volume duplicate$ empty$ { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ pop$ word.in } { bbl.volume capitalize swap$ tie.or.space.prefix "volume" bibinfo.check * * bbl.of space.word * } if$ editor empty$ editor field.or.null author field.or.null = or { key empty$ { series empty$ { "need editor, key, or series for " cite$ * " to crossref " * crossref * warning$ "" * } { series emphasize * } if$ } { key * } if$ } { format.crossref.editor * } if$ " \cite{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { editor empty$ editor field.or.null author field.or.null = or { key empty$ { format.booktitle duplicate$ empty$ { "need editor, key, or booktitle for " cite$ * " to crossref " * crossref * warning$ } { word.in swap$ * } if$ } { word.in key * " " *} if$ } { word.in format.crossref.editor * " " *} if$ " \cite{" * crossref * "}" * } FUNCTION {format.org.or.pub} { 't := "" year empty$ { "empty year in " cite$ * warning$ } 'skip$ if$ address empty$ t empty$ and year empty$ and 'skip$ { add.blank "(" * t empty$ { address "address" bibinfo.check * } { t * address empty$ 'skip$ { ", " * address "address" bibinfo.check * } if$ } if$ year empty$ 'skip$ { t empty$ address empty$ and 'skip$ { ", " * } if$ year "year" bibinfo.check * } if$ ")" * } if$ } FUNCTION {format.publisher.address} { publisher "publisher" bibinfo.warn format.org.or.pub } FUNCTION {format.organization.address} { organization "organization" bibinfo.check format.org.or.pub } FUNCTION {article} { output.bibitem format.authors "author" output.check new.block format.title "title" output.check new.block crossref missing$ { journal "journal" bibinfo.check emphasize "journal" output.check add.blank format.vol.num.pages output format.date "year" output.check } { format.article.crossref output.nonnull format.pages output } if$ new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check add.blank } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output new.block format.number.series output new.sentence format.publisher.address output } { new.block format.book.crossref output.nonnull format.date "year" output.check } if$ format.edition output new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {booklet} { output.bibitem format.authors output new.block format.title "title" output.check new.block howpublished "howpublished" bibinfo.check output address "address" bibinfo.check output format.date output new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {inbook} { output.bibitem author empty$ { format.editors "author and editor" output.check } { format.authors output.nonnull crossref missing$ { "author and editor" editor either.or.check } 'skip$ if$ } if$ new.block format.btitle "title" output.check crossref missing$ { format.bvolume output format.chapter.pages "chapter and pages" output.check new.block format.number.series output new.sentence format.publisher.address output } { format.chapter.pages "chapter and pages" output.check new.block format.book.crossref output.nonnull format.date "year" output.check } if$ format.edition output new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {incollection} { output.bibitem format.authors "author" output.check new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.chapter.pages output new.sentence format.publisher.address output format.edition output } { format.incoll.inproc.crossref output.nonnull format.chapter.pages output } if$ new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check new.block format.title "title" output.check new.block crossref missing$ { format.in.ed.booktitle "booktitle" output.check format.bvolume output format.number.series output format.pages output new.sentence publisher empty$ { format.organization.address output } { organization "organization" bibinfo.check output format.publisher.address output } if$ } { format.incoll.inproc.crossref output.nonnull format.pages output } if$ new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {conference} { inproceedings } FUNCTION {manual} { output.bibitem author empty$ { organization "organization" bibinfo.check duplicate$ empty$ 'pop$ { output address "address" bibinfo.check output } if$ } { format.authors output.nonnull } if$ new.block format.btitle "title" output.check author empty$ { organization empty$ { address new.block.checka address "address" bibinfo.check output } 'skip$ if$ } { organization address new.block.checkb organization "organization" bibinfo.check output address "address" bibinfo.check output } if$ format.edition output format.date output new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check new.block format.btitle "title" output.check new.block bbl.mthesis format.thesis.type output.nonnull school "school" bibinfo.warn output address "address" bibinfo.check output format.date "year" output.check new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {misc} { output.bibitem format.authors output title howpublished new.block.checkb format.title output howpublished new.block.checka howpublished "howpublished" bibinfo.check output format.date output new.block format.url output new.block format.note output format.eprint output fin.entry empty.misc.check } FUNCTION {phdthesis} { output.bibitem format.authors "author" output.check new.block format.btitle "title" output.check new.block bbl.phdthesis format.thesis.type output.nonnull school "school" bibinfo.warn output address "address" bibinfo.check output format.date "year" output.check new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {proceedings} { output.bibitem editor empty$ { organization "organization" bibinfo.check output } { format.editors output.nonnull } if$ new.block format.btitle "title" output.check format.bvolume output format.number.series output editor empty$ { publisher empty$ 'skip$ { new.sentence format.publisher.address output } if$ } { publisher empty$ { new.sentence format.organization.address output } { new.sentence organization "organization" bibinfo.check output format.publisher.address output } if$ } if$ new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {techreport} { output.bibitem format.authors "author" output.check new.block format.title "title" output.check new.block format.tr.number output.nonnull institution "institution" bibinfo.warn output address "address" bibinfo.check output format.date "year" output.check new.block format.url output new.block format.note output format.eprint output fin.entry } FUNCTION {unpublished} { output.bibitem format.authors "author" output.check new.block format.title "title" output.check format.date output new.block format.url output new.block format.note "note" output.check format.eprint output fin.entry } FUNCTION {default.type} { misc } READ STRINGS { longest.label } INTEGERS { number.label longest.label.width } FUNCTION {initialize.longest.label} { "" 'longest.label := #1 'number.label := #0 'longest.label.width := } FUNCTION {longest.label.pass} { number.label int.to.str$ 'label := number.label #1 + 'number.label := label width$ longest.label.width > { label 'longest.label := label width$ 'longest.label.width := } 'skip$ if$ } EXECUTE {initialize.longest.label} ITERATE {longest.label.pass} FUNCTION {begin.bib} { preamble$ empty$ 'skip$ { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ "\expandafter\ifx\csname url\endcsname\relax" write$ newline$ " \def\url#1{\texttt{#1}}\fi" write$ newline$ "\expandafter\ifx\csname urlprefix\endcsname\relax\def\urlprefix{URL }\fi" write$ newline$ "\providecommand{\bibinfo}[2]{#2}" write$ newline$ "\providecommand{\eprint}[2][]{\url{#2}}" write$ newline$ } EXECUTE {begin.bib} EXECUTE {init.state.consts} ITERATE {call.type$} FUNCTION {end.bib} { newline$ "\end{thebibliography}" write$ newline$ } EXECUTE {end.bib} %% End of customized bst file %% %% End of file `nature.bst'. phyml-3.2.0/doc/phyml-manual.pdf000066400000000000000000014345731263450375500165440ustar00rootroot00000000000000%PDF-1.5 %ÐÔÅØ 2 0 obj << /Type /ObjStm /N 100 /First 807 /Length 1349 /Filter /FlateDecode >> stream xÚ•WÛnÛ8}÷WÌc‹EZ‘Ô…*н! Ù›,¶ ôE–›¨$ª•Ö¿gtqšÝز8¢è™Ã9sf&Œ €"RÅF”R‘Hã·"!ðIȘDB"ÂC“ˆS’‚Dš.¤ÄJ“Œð£V2Áw))8QK) §B ó…€Vš"©ñE±Z„’"òé±À#¦X!–”âß#®4" ' á%„Ÿ$ÅC“– œHÇÉ"–¤SE18àÌ8¦4DJi §œ€€RÀ à`3)lPVLR ¦/´g0æ,ÈÀ . ¢JJ§B…“ðÔx/D®”`š)ð˜`ˆD‰ˆ‘|<çx>;•äH°ˆy¡8É Á;xIBÞ²f V@«h! Ð:à@¡ Æj¥È­€"Mð-DÚ•rôX°‘½ÌÐD"D&¢ꅀ.RFÌúJδ‘*˜! +„`O©˜7Ò+CäZ@%F¼r¨q(”B6Ã…IUÄ\9œedDÆÈl_\1 ydÌ‚áƒÜóÈ × dC¡± µÄWNê1C9©5ï9í³䔵ÄΙ@Ìò©€S.WIWCÚ41΂Jjñö-½¾¥×çîÎÑëOô¢5¹·®z%^Ò»w‹ï2[dK[X¿}¹×Xޯߏ¦Ýo§»ëÓûðùýùåçýŃßMãÖMVR×fkóêàYñ¤ÐÍïÿ\^Ü )µ•7Í}–›ç]ŸxOþUÝyú”ùŒ`pVšª;Æ{”ø»ÞúŽ÷©t+¤ì”QȻƠLÖäÎÙ)S#4Y•oàYs3Ì ìÜG]Y¢À‘Ãj6‡;ß1ô/(»c]ÆXo¦âZ:ç[ßdõþÂH~ ­`»Î÷/÷®á–|Œœ{t¨†Çˆè`HÉ®ÍÍ÷ÎT0h™ùv.óÉcýœgõ0²ri×ëZÊ7`˜#‚£p¦JªMnï·¬?®×Õ(‰!¬v†…ü¥Œ3£xW]ám] u…]W(?Pñš;sóc×zW‚¼­ÜY–Û5™7C+Ì ŒÃâÎÕ®pk›gô¬¸ ÝÛÂÌŒSãº/ˆÞa.èd—¨Ì3]žk¶zÈ›-‘†ÖzÌúÖo€öÓ¬h9´Uaªµßø»¥—)Ô'r¸,õT[Wö§ïš1›-ÜÂzª´&¶Ú{µ›K[qý•ã±\ õewü›ž>®ÙÎ@Er7òj³ÇµHMךc9ESŸzÏ¢7ž ò¿™B]f­Íç²?Î3WHÛŸI¨z³-‹þ‚à*”Õ1ž£J~¨þíiΣdÜjHhcùŠrÀ( æË}c¾Ÿè<Š14ÇØ§!ŒÉæ~c'z]¼Sݦìë`¬‰þ}‡8'üˆöÝ_ò,4?3~¾¡ó»?é7 ñ¹˜Ð;ƒ ¶z„¸<¿Ìø¦£o5y ó§œFócm3­#øˆàÉ•`Ò§GgÝ4ç{lWU˜t+\€öÏ·1ÈÖº?OÿŒ\£÷ª‡;]ߓ܌ÃMµÎòo¸ã¤"‚Ýo³½³%¬ÿ²ynò endstream endobj 280 0 obj << /Length 303 /Filter /FlateDecode >> stream xÚ…AKÄ0…ïý9&`¦IšiR‚.ˆ¢Hñ"ºÛn[è¶¥Û¥,þy“ÍŠ¬{ðô “7y3Oš²ŠÄ?¼Ë£øA¢4k$É·DjÂ"I3›‘¼$ô•ñÄ mŽÏOŒô+àÜ,ú€ÃE³cŸù£sM/\……–p… 0ÑÁ÷K«ißþ'¡hÂO;™•¡cÖÚ ~ÙÌÚq•º‘ Ç›@%$ú¹Hº«™jŠ·•?‰”!*¿ÇŒÔÞÁ‚Vç¦ çñ6Ž÷s56E_ÕLÒCÛ—Cu;Ÿ‡5´C<žêã®ãåÀ”¥Kß E¹O ü½IRÈ\.—оò]–ŠÙ»nøÎåáFw­¡U×µÕÛé×úÂë/ïó蕆€n endstream endobj 323 0 obj << /Length 1295 /Filter /FlateDecode >> stream xÚÝY[s£6~ϯà©#p‘@Hôm“¦i:I“iÜévvû lkŠ‚H6ÿ¾K`⠛˺}‰aŽt¾sûαkÍ,׺8qÍz:>ùþ'Ì,ÌFSßO-ì’ç¾Å\<Â>·Æ÷Ö't–¥¶‡‘ŠõRÚ!®…­¢–To~»0²ð(¤”Ô²\Ë!Áˆpª¥`Û Ý}x°‚„LÄD&RÕŸŒ@}+ë“C|_ú[Î1‚q}J-˜Á•šgEÙ“øÁá²<-ëæ¡¾W\<Èø±'rÊ=P ¯žV3ÛñEEœÃ£¬P}Á.æûc-˜jÁ—i©D’ÈÔÈ¿/½¾êIÇ,Ü.lG×m.Aih9Øù~`N ±ëbt—UE—p" Hïõ&Ê9˜UIp—ÎáÌghd;Ôueé\{·à4Qòœ 6! +`–VX> °2ôû¯—DþmŽbýª|*U¼0P~v©+Ó(©î[I×"ÒÞÜÁq÷ÞO¶( VƦ̵ŒŠ¬Ì¦J¿þC¦÷YýácÙ¿$~ó רߢ±šÇz“‹ÞÇ‰Öøai·¢” Ù´‹Pç^a§ætŸ­Óóõöâê¼Ìw”áËö Ð­ON“äÖÓj Óêm‘Í ±Ð9µ*Å,îI =Ä_Pƒ6¡ÞþüçÕå­N ç“iý âb*¢¸{:¿¥üí~Ý· iAÚêŸ`ø=t–ø`â¢KXQjc”WJ‡ÞB SYMœE¼Äªêžîü(]• Ø b°¸«&¥’ªRmZd¶˽ÎS»á^ðþê†_¡®gÔÛ  ˆML”±(¢Z±y›²viKƒ#°81Âä+ ð §…HµÒ†3Ty¾´xM"÷[Ü%oê‡)Oöö)ïl$Ú@ÐЫ³l±š ù1=$7†ì}T}(þ`hÚdžŠíDÁ£øÛU7ÀkxièÝmÒ“ ÐD‡þ«JUˆ¼_èYË2 êØn>dúWÖ´™Pyë.…rô^²J­ÞM³Bo¢ÍP…7º?„&9z/ÍDaKü2DÜ+¶êTãª8LÖ€[.„ê÷'o)olê¬ÃmQj Ö…ÈK]\ÚvØ/>ù…:gè endstream endobj 362 0 obj << /Length 1360 /Filter /FlateDecode >> stream xÚå™]oÛ6†ïó+t)c°ÊoŠ»k‹$èÐaCæÚ](6c ч#QmÓ_?R¤[’#ÛˆQe»R(É"ÏÃsßs¼¥¼ë °¹z…˜?n®/ÞÍ.Þ\AêAJ‘7»ó !Øã„Þlá}öÀL¦èÏVr2ňùŸ~ÿhþàþ]^¤èGÊ£la_ˆUiïT¥ûIœÙ럫‰¾ý¨?ðÏì·Íê¼ÏS$˜L¦€—¾´& ô1Þ¹Û…£¯SH4 Ö@ Â_R©8[Zkªµ½¦ñwU²Ea*VqîLOóÉT?^ÈÄÁé0ùÕŽUÃù6*ãyÙZêÆ‘Ùц0gˆÛDæçk³Æ²Ëi/âL{öÒ[®I…C¤ "\4?|s…Ñv¨`*ôoë×Ö«Ç4±¯íF&c¨ymž§ëÚòLffÏU{¥$dgtìž„rÊQì²DÃ,U¾Î“|ù؇“âB>&œ§¥1P€€rÖˆ‡‘’i¤Šx.Ë>ˆœÑÃ!rBÎëbƒGÀ /iÃ&zé02 L>Tw…|(ÿÃGàÉG‡ÞQ6_%2[ªU/Å!?‚b}@•NmÆ=¬Ø0«2VÒDh¿·‰1qLhâQ² »ÓÙ'ì¢ãœ²ž’‰L‡ÝÌè°žo"ð§#Ù)·}_äPÞ¿!ÕD“eŸË ÊÑ)"( ‚¶¹q'æÞZ)WÆé:q2T~Œ6×c-+ fþõìÆ¾õ‹½|û®»ó¡‡þ4_"GKÛ°ECÎs«ÅkFúDãã5ùÔžV p´ V{ÉÁZsü‰ˆ«4ŒO8aþ·X­,œÔør•h@*ÞøO«z1²×é; „G»ú{úïÌ‘dV»²Ëo§Ú´Æòº,Õã¯Jý¨ˆ£Æ¾úYÔøNM"Ï2ÍGº[‹HEíS ÓB=–Ò!…£ßNLSȪSãTW-ÐÜ2æëí€ùïcW¡rjjK½¬¾zq|Úv}d·?m¸bÛþÐÅia?½.òe¥¥ÕŬ¾Úâugfûv4Ÿ`äßOò£¥ìfJøþåt:Îúí͇@—jõ滂z§y0ü)%ëù*å>g‚G•ºô ŸÈô®}ÈJ%ɦÏñ P­ÇÒ8 è:‘®Rk 7U–‚@œï|j¢S`‹àïµ> stream xÚµZ[Û¶~÷¯àcòPŠäÌðr°(&MO€6)pÚ`œ]ecÄkùø’4çןodæ²IÖR °@J&‡‡s—‚ Æ™à¢a&™LðÎxGh½ñ=ß?ãKB›M \¾˜Å„ ¹8 á !ŠŒ6ÊCÎ0®@Þ°à9±á‚y$F(õ´$)ÍbDŸs0‘ü,0™ˆ~àhb]N&9ü/Î$< âMÒõA3;½“èK6Yôy1¹`]`/ø"™‚µCŒ¦$}žLÉh“î› v¬O°c—ô ¶ì”FŠÆ{Ý\J`Šh'ÏD³1K ö™øÄX t°sg|Ò¥²²±ÇŒKe {kv«N… q:rÖœ·Ûn¿¹l·½cêýÖ^-æ?u™:N×*]XY›ËÅ ”6  ñ0üÁjÕâ‹Þûéêêü´½˜ÝBЛ5?u›«vÓ“vÍ¿›'ÍCÜÀK^(˜ËyᣳjQ}ôÖÁ&ÃÚ¢N7‰u.`ܳýËh6¿.Vošggý ̓ž]ͳæ÷ó'zÝ{½Û­ÿÕ4Û]»~=_µ×ûÅê ü¼^ì^ï_ÚE׬_¿¿YþpÕ½[-»ùÕ¶¹ÀÿsIV= 'åýmÈïÞ½³óÝõå78°u Åk7öÕæø3”ŸŸùþøS#›3Ãß9[ààVûåòâîÁá0Ø“ÕîÖàÇXب|=Ö0ÖA®à¥¦Ô„QYúÌjžnºËg-˜i{ôØ4ÏÛ¿v_ Áb¨áb¨.ýûÄ0W1̹¶åÐW[_ÛP[ª-×Vjk[é•J¯èiuh}mCm©¶\[©m¬mªm®m¥ç+=_éùJÏWz¾Ò󕞯ô|¥ç+=_ލ_•CÓ â·%Û÷7%»)„b ^1ŒÏI£. ŰæNÃÕÛ­Ó¢àd“¦Š…ƒ‹’¡hå(Œ0Œf cð)Z¯HH,bÄ£(èô(¤ÕÈÝçhDk 6…ÁÀˆÑÒTO`G¶¥bEø( 9! _,#û –5qJdU·%*œ;å“—“Šé,wÊeAÖ‚Î"Æ&ÀÈJŸ&‹ Ø"|RÆB`qà‡&pBVó)$Œ)Ù0>=.l“V tYÎ,È09½ q̪2&ÀM¶3BŸDGU(NÀ‰–‘‡ˆèÛkÎmÛxRâÕñˆúŠZX*×,Pïï•[p& ×ôßæP´Db3Å‘€Â€%!äFœ€ÃÓÚ tªŒ„C§‡C8(-Ì ±)÷E%[˜Gš@Á !JÐRer6jÙ Ï%KóF˜¯$Ñò^°QØr›0Œe#LФ¢5G_´¬„ Ÿc™ v e‚#`.U˜¡õ,rÔð¥ X:T£¡ãð×ã»ÃÊO,ISØäª7†8Û˜µüé4Ö¡GiÇìOõFK™`ÒÁ"{ŸFš@™„… ,&kIÞ2Gi,ª<šZÍÄBÄ2ÃQDšB±k,šiÂ뻎€vʶWsäõhÔGy}ƒ€‡±L­ÓE(·Ó¼-%lÏ0– ",_4x 8k|ðIŠ Î{K:½íõêÕq#ÚK÷Y§£¦7OÀÄœ-+!ÞÓWcÐéAýÉSdmž#ã¹ÀxèvˆqËvÅ#ÚÔWO 'í 0Á1¡a,·ìÊ#óB_3Ž®~1¸Ö¡/.ʸúà÷—cøª$Ý÷•õ¥`_ µdjÉ,Ô’Y¨%8ªã¨–ਖਖਖਖà¨Ò£J*=ªô¸ÒãJ+=®ô¸ÒãJ+=®ô¸ÒãJO*=©ô¤Ò“JO*=©ô¤Ò“JO*=9m‰°ÊlDä’Ã!ÀMBä‹°g^4~B,¯5\¤÷âǤÔyš?¨%ßÂ`3S䳌¸÷ÎZÙ]ß’¸ ‰-½BL_!?V5ûæçiøýŸ+¹B endstream endobj 371 0 obj << /Length 1554 /Filter /FlateDecode >> stream xÚÍXMsÜ6 ½ûWhzÒÎT²¨oåæÔ‰›ŒÓfœmsHzàJÜ]Æ’¸CJ^ûß ¨µìlfOÒôâÂ{!È‘·ñ"ïâ$r¿Ï—'§/“ÄcQXEó–k³°b©WD,L‹Ü[6Þ¿^ü³| žéÜ3HÂ(ñ‚(Lâ’Ü>F,sžÎDžh½~S»E\úwZn¶( ‹ IRŸUU…RâôGQI¦•õ'í[»çîÍ%™ÎÅ ®E«vèÇ%þrQ&¾à]ˆy !`I˜eÇr+AšE¾Qëwîñ×N‹*èAiZùÒz§êod#Ò|dIÊUš_HØËa«ÆÃpì7q­¹‹‘¡E­é—,Ny-û&\E•ú¯zRõÊ"‰CZÿ€œ1ßlyÛ’8 Ä„Áá#„£ i•¦ß­4dÝ®µ¨îìaš´«E€+ç+Ú†ÔZ˜µ¨ÞÈUëìkåv!ŒÂ&  ïøÆyÀ¾±‚c d¿AŸÌ_kÕ‘ä"ÏüÑX!·<‘…ÂÎæyCnlpeþ¯h-áк›ÃÑ«q ¡WØÊN¢q§ªGÏ]ëÑ šRõ“…Ç‚·œAªƒ¤ŒýŽO¥ qKD -E_ RÊž~GC¡HÏaÇkÜ~½È2xƒȪÈ?³Ù´f=-ó­FzzïeŸ_p5Ž?Løàâ¶;¤&ËýýVà5@5¢¬9ñ>é ôH`•,¨¾±•Nè.þø‹4;HθjeMK•ñNˆypîzRovÏNO÷û}¨—=! •ÞÐE§Ê¡—­ ©±ÂcE³,ÅG§EÈ2×ÏÔ ‹3ÿìf‘'>ìâ+ÙÊa‘0Èl?4Hêy,¬²,¶¬SÐq²‰DèzÅ£M,{°‰…e¦ö÷\ö Â<³{Pyzã‘puqâ}Ò$óm÷¹‡Ï‡MtÀ¢²÷k@6 h{­:\ëÓu«®}É—`.¤ Žm³ Žw6ßà b·å½ØŒpgn K¢Ã¸ ¥ºÇ@áâ½î[ÅsúŸA:—¦¡+çXZc÷õ7Z;n”ÍÚ´"¬UGj ®´àì©£zP­A\…qžyAXª‚‚‹§šu­ü«ÊUìiéØÇ(N)ÜJÐåþ$°±ÁÂ6›œÅþŸ­¼‘¶  &ö­(ókw]Þày¶YDS‡AÁ¢¥ÕýË}ê,Ìã„"âí¼‡-½Ò¿¢X˜•ùwJ žî¡]À•«Á‚‹ói„XÊÎ):¹³ÕÑü4qšM„7eœGþ9w ß/ðÝÕ֨ܢ*¥$£íRÀZ]ñþ× ù<Ê2ª,è舎¥µUB=™ž(ŒŠô»æ¸šÓ“Ba¿—8“À$ö»ÒÍ'yM>–’¢¬fu;u_}ÆÚ‘‘#¼{{¬¸¡‚Û¡…«6#¸¶3Á–Ö‡;Iøñô^TòQþY/ìhô]dP¤¶,d€õÀj,ÄUiYÀÑlV•»#hæ—WXoKRÏ*€ÌøvŸ‹Bh€Ù é©@‘13îè¨ôðóÚCÍJ')™ÿ¡M¡^“Ç%@”¢¶‘ÿZð>7fÝ”mÁé|\»IÒŽ¶ ii°áoÙ½Kµ é€H¹Àž“%Œø¢sæ©ÎŸ8ßBYö$Ê&œñ ',§û𠜠­µpgÉîGÜ<.ï××nÜ…êš&ÞÏaºŽ5¸÷tk¦¶ ñÁ]4íZöx+•ëøöùÂêV5ÿ(ÅÍu=j^ßÑ>ÊZŒC0} ¬ñõ¡;àA˜_¬P+³²È#WXyùÅRΔ28¾µ•#íÌç#Ì5·$S3Œ£Y3ĸ9^¥Ô!‘Çòž­Â¥;Ǽh?ãÚ~´‹ÕÔ.5¦<¯¯:ü˜·1ÛûË{nè?-w\à€A¯y=PLrûŸ’ž¿8CËÅå‹ÿÕ„³×jp—Á}{ƒ4û´Äëg>ŒÚc0½F¥dQX$.õé—Ë“i€® endstream endobj 384 0 obj << /Length 2177 /Filter /FlateDecode >> stream xÚXmÛ¸þž_ák?Tb­Þ_ò¥Í¡MºEzwȹ¸—ʵi›ˆ$úDi7›_ßgf(¯¼Prùb‘Ãáh4|晡£Õq­Þ¾ˆüóûí‹›7q¹ŠË0‰ólµ=¬â( «*[•QÆYµÚîW¿ézÇIüx¿Nã@÷÷F?¬Ûþ ›óU‡už'´9Zm’"Lª\¶ýtZ'eðøïwëMVæÁ¯´ד4xÿö4c¿$nAðm)ãä©äáìa “ë¤ T¯EzV;~\çãàèå'à '¯Ö›VõâË ÜG'5\¿l°òÔnÀŽA“oôiqfY!ŸÖªO¦%ãc å" ó‘œÒ9a;Fô[{Y=K${„º3š^UäÁ¡·´2Q!ï»Vw¤=8Ùkòdá¸k´Ì^ûµ^žª5Ý,9ªv†|ˆªÀéßGÝí´ ×›¢¬ƒÛAägøË÷0JoŒJŽ6ä5õª;ú!{{Œíœ} i™Ò|2P‚Esì´wq]pð3Pœ7i 7ÕíU¿§Y= ‚‚Ð 8R^PjLV&Áöä··Êt¢á†^wÇá$rò›¤„ÉJ0IÓ†ŽbÁ+2’åÀ ÙͬFõÈ:îø½ãCÖ½èpl àÆ;@g)B"i=tãDugÇsá—XyÞ¯ñ£zcG'‚§ ‹ÖÜQŸcN«þ‚ò$õcà<ô~A4¦D’wôÚoì™Ý´Ð@\^BšUÁÑšî( €k+£{9çG/WnWáì–©?Dq±3Ø}^­N>,N$zºÆú,—Ø’ìnôÛÈ÷^5Í£·b l4R»ÝØ Œhv®‰ªàÄ(ÉÁ_·Þ†jÜ"M‹C™¥_Ja'ìŠÁs¿sïwè{¦ f$GòàÉ3PÊà8û(÷Ó+±tô^ÃŽÝÞ‘XÚ©f1wzÕjñ­':ËËàC”G´eÐÙnsV¤4ô|ÜùYÏQ’DeŽŽ—íC²þIx…Ltå…èÊ Ñ-ø‡ã0›g 6…oqÈz(8y^_#yV-Ò¼–+'“'"¡Ç»ˆ˜¹èÝà4¯wɳ OÊ>Ùš”ŒœiÜv¢ÂÏX@»Šƒ—ìíæÊ݉XsEÕI–€1‰n’, Ƴ<éí´’½Œ¢HD–•„VžV*8³Ý û \i,e/©NÌ}Ÿõ>\Š9G•#80aˆhF5K*Ÿ¾Èð´®åÀIKµ€Þ”¢•É[ÝR@xÜÃ}ÓóQ@ƒ£Ëo»:ŠJÀŒ‡5FˆõbΑ~]’…K^€ôxˆ=o×”^OÎxÜ _PY$hZM.…ˆÇt $¹cì]ì¿¡á ²çÒn¢È:å‚IƒQ_&0ûB™¨}Aæ@ 1/ÉmGäF#¿OÖåÃ+±TŽz^»½„Kñ‚»ø(úXyûúý»Û?´’þ•- Íz“¬Û3G`• (o$ClSb“0 çW77á0Ûîõó^ Þó[b•Öaf«Ì߯¾)«J"Y W-Î/ݳüö_N¦Ñïù• SðGÇ#- ¥ÃØ;¦-jMÆãæà»¿š?ü;òPÊrž¢RÎ/÷Zíç)”FÁÞ¸]£L˸ ãÀÂâ%ä0"Iì0 éx}%a,@»Äú#M¤4UB•˜ŒZ”Ô®·œ'u*"3ÎÚ»¸ ùAëF4ý×þRWYj}úÁDut›å‹INÕ%对ÊarEeÈÙ ïdâÌàÕ™ýæû¶ñý­¡+7¯ö{$’{õèݼI“9’ç_dXd/O€¤&Ù'õj3é\}ÏÑÚc£Cö¼6¶7¥¦^öýù»IϧǶÙб¬v…ìçpLª:,Òzr†JJœ¢¤€¡˜Š#ýFã{*µärê⪷pMuÜï” +æ#Ú4I4®yˆäZô !‹£",ªròÒ…ÇÑt{ÛýM» *I¨va÷ù«_geXdåÕ—–Áß­xÅõ‹|BÈŽzáà§V‘î„òÍy¦iv] % !ß¡9¾B2k„µæEˆˆ•¯ ý½aèô½òtqL¹­!¼2‘êŸxjÿrÊ=9Ýv¨·M# Ž‚#`(räb”†ªÃ²L¼0öV~I·â<T¥M£¦à,ñ]ÆE)Öø²_”Ý”ÄM(@Eá鉗ˆÐ„¿› ¹¨áw SÌíL•öxѰí7B-Í˰¬Òyv¾’CŸV®ýæÆ úŒâ¯=$Ã#ºñ.4–‘þ!ò¹¸·]cÕÞÝ|=!Ë8ŒŸÞ˜Vò–o6ôIzp\Pé·^eâ~¸ýïfºøù¿ásëdbÜô?Þ`úÆÿ-0õgÔœøÛ÷\—º]o|»÷kݳ¿1þ'xx_ h¾ïö‡Ÿ·¯ß½[BN–†ÑMþElRÅnžkÜñRÆ<¢–ùûs¥l_ü›t—þ endstream endobj 394 0 obj << /Length 2098 /Filter /FlateDecode >> stream xÚ­ɲã¶ñþ¾‚åÊªŠ bá6)b—Ç~®™øÅ~ÙÊñ!‰ŠTHjä—¯O/€(i8S“åD Ñhô¾0‰vQ}ûøïWÏ«×2¤ešªèyÉD‰¢0QžH!M=WÑÏñ¸·ãb©Ê$Þt7àRÆçzÜ3pÜ; ݩ߸A,–Féø±åcˇpõ`ÛjÙÔ­ãƒsÝVÝBåñù·(âÝBÆcÝíªîÝfìú—Å/Ïß÷Ki„1Ù5ƒZeðJ‹G[·Cˆ‚˜çŽ¡À‰?Fô—#<’Ç'|W¯µºÖ<®ŒPÆðãbnëÝ©w¿»0—vÉçû8HeoÐÙö‚VŠ2S÷Xþ°ÂùÀ:¹H,ð*’,ç‹_½ïiWnkáâ©Q›Y?íI´·oøü\7 ®L¼fa f9Ö«øÈàÝq¬õ¿ìXw-Ÿý=‘©Ý |<žú6\êZ´¸”ñãH‚-›×&ªñbžÅ¨é"^7ŽAdkøî\ëz;4'·à{Âõ³€nËç^<™$ˆwSÀÙØ–AýÉß÷}wÚíycù°rëÓnW·»Y—"¦âtfŒáÓd8mÀûž!v` ÝúF®…Ñ&RUÕ¬ aÒ, i‰$“¸ë=iÞûtnäà7<%Où§y’i.t’‡÷v@w;Ç–ND>ñØ—ƒõd\Ãâ †r±íš†£8hx,EVH¯ÐÔ;@;Œýiƒþ4|~œÁN–ÄЉ—K×Zð¢%ò¿‰=ýéØË#@›,p£È7©P ©RÈsÃho¥,EÇÔŠã·è·&3ñŸþðøWH~ïZbìáÑð2Œî0ð9Z³n7Í©Z‹:9¼ŒÁTjtoè<ßÚ /~ø‰ì4cÍe  ”!Y|Ý9j(÷]eÜ®ëÖö/œ,ÉñÃë–aˆu\Oé˜P^Pwâ ‰A‹YAgñëE¡Èµo²qçS.Ñõ•ë„*AåüP;N¤ DùA 3Y.O|Àë{‹©nºsE0ä´[î•É1s¿»Þ—J‘iu«”ïË/V/P”)|óüðÏ דHB“B•&2ËF§Ñæððó/ITÁ!¨X貈΄zˆ´ÈJ¼ÖD?=ü‘;š»ì—Q)ÑRÚ¿~´ã~õê7ÈÄsZÎ ¡àN2yŸÎu0òý :i1™dm‡}¿™£ *JÕ…*…ÄDõCE™D ÁýÿP”Ir¨]Å¢ VÔÁ_?%ÍUèU“Ùóò¾ Àz\ä·“qÏ€=t–¼º IÜb^œ­jJ‹Ò\ªè¼#©’_žEºLÁ ÊÿI?Ðöˆt´òrò£Ù(-D¢/¼QïSä¾™…Å;5ê´ÚÝÞ( m Ü4·ÜiR$òNdziË„ø¬º¦gê–¬kғ͹®Q)ª7}7tÛ‘·¡¦ÏÜb_²êQæ³µ¦ZˆÕg¾Á‚°HeÐìqÿrh„ûuÖAÓR䲨ØñÏå--”¼£·¶ãGé]ú#ªŠ×LöàW“!ÁBŠNM?SäóÆžZß¶q¿ ¡,?fELÔ²„¦¦;ïЪ «À¾ &q½!Â!­ï/W][±µ›UØCM¾úi €wd×ÅÇh»<¹æ [ÇÐr¥¸‘vÛõ³AžAåH?ÏÚr—êy¦ôÒ¿ÃÀSêÒ8ón}ÂxR¾‡EHU\‹#†Ç§ï?ª@Øïi˜‚UÛ¼@ŸõË)I`(@YšÞY÷»¿½y|Z†VéÒhax»~k7îó‚Õ|$XYõ°8Úà®áÝ{ê>ý4EQ¼‚›Vlóß|*pÃÔé5:BSoÁÕ4N­m^Lv¸£ 4ƒá¢ó_n²š±>R‡ ¨2\=Ü0t=ý@ÈËøfÂÁZA©Ò£]?ʹâ¾ûêðOƒÖ¹oäø2³¼~ÅFQ*;ÚÁøtѺw½Û¢ÓöãÏgÖM̧1ÌBIÙ?Ô:WŠÔ5À74ºàâÖ¬Òwš½nuœÌA—,5‰smØôîˆÁZùGGNµ}«ªß×Ì–„ˇ Íbr¾Ó½|ͪñ=;ù|ï¬Ä×-Þ‚ÖÚñºÁÖ–ü6'5Å­5ž©éε‰·ÎŽ4Åá©çF®ª‚{×ÔÎã£ã ±Š€·O¼Àæà-°cwþä Ù·Ã@€€ÇvùñŸ>ÔxÔÍÒF—uo/y[BKtIÜY “ðà¯ÆŸ,9–Cîcz³k8¿›† Üí½¦P±L¤ÈLI£1i5ïÄ‹e‘ú¦, þ±†EvpE”ià/e%ÒÀo©Ê©Ýgž’ÿ ×t¶ ñwÛwä³¾¡êw/~üöážO2ß8_­VçóY6á¯À`k±£GÞ¯ 69Ûsh¯È§`.úÌau8r)Ù«ÕÍ_l µþÐnüßC’Y¥ï®nDQ#Jd° ümº1Í»¸¥ ¾W¥™á4@*ÿ.*ë@žýôÊeæÝOH¸ðáãñ) 1 þ=R½ÿi2‰*K éÊ…*EQøt›Ýà@‹ûo¨T… endstream endobj 402 0 obj << /Length 1918 /Filter /FlateDecode >> stream xڥ˒Û6잯Щ#ϬhQ/Jé)í¤Ût6ÎöÐI{ÐZ´ÅVW’“úï  l¹Ú&Ó^DAÄS¡wðBïþUÈã7O¯¶ßÉÔ“RiyO{O†‘ÈóÄS¡2ɽ§ÊûàOµÞq$ý}ß4ý&Rþ'Óm¤ ¬éÆi8í&Ów¯7¿=ý°ý.Ž<ãXD²€#-·öXm‚T¦þWD¼ …Ê©ØIû?ö PÓéøÑ7Qî릺œœ44¶ýȘ]9êñáèr•÷ïðx/Y, Uˆ$ÉèàªÔmŒ"Â]›!é—Í ËêL“g|M4éëLw ·ñŒbö§°£>Z¹Z{“äWô„&ñݘ?쾆®zÂwýdo.Eï´ýÆaæO=V]ý0œiZ’äýib²ÚŒ¨hÐæ/›<² ~WvŽ@3ôûiäMæm.4kO)%²t~Ïc}n›íÚ³'¡H•#«Ì wSïþ5LCæï±ÌEe7ÏuÙå±S)@;x ¸ëT‚º5½n£…Qê$‡Ýª˜Q"²0wTwkœ2¡é(ô_e{lô¸Ê,Í…JGZvÕª#%³«þ¹”(Š™¸i¥‡ô&éÒÈÛšÔamð¢ ì¡I–/µºëÛvŽè0™³wöëès qã­ð`š(ÊÞ¼…çØ›ÃiÐ?tW>7:hæëÙ–CØ^p¨(ÿÐ+v Ä]v3Y!Š,ºP}½¦©D ¬@nŠˆßÀm ¤<›®´öG`_2i4Ỳիï ÃLÄ ;F©WŸµq2¿E]ŽÌ¹Çxõ‰'eZ¿‚éâÊdÝÄ1Œ|ÉR“"³ü¬¥æ"Í“…GìA `ݼ5{›ŒÈV0#ó´ÆÓ¨ ød¦š ˆ§¡ØjiÑNÎðjG³+Z kÙ´`5hL§iõLk³Ã}õ|θã2Éo¶Æ©HVÀ ÅØîÿÙlÁ(uÙÊ@pg{íÈÄÖÚ^MÁâÛ3¨Hú2ö™F†ko.Mô±Ñ¥U0Ü•OWµÍ°|‡Ð“Þ€@à§ûWÞKž‰dqIF÷{⡞øRñw§–C¡÷ý@@ÛšUÛ²-ñlÁÂ+0B°ñÌ CTÌ$ ŸŠtH¥þ;( ʦ±i1V©ÿXobéŸß?ß¼}ƒàýÃÛ—´ ™9mÔÖÞ?@ŠRвÖ•SJG ²RdkçXè+VWX]ù·Zò#^yl\ÀýVð 9¥b(:S£þrŸ´X±h}{r©‚Óñ5WêJ»§;4 ïèâriD²0Š!gu qÃØÕÉ¥òÁÉéH«Tl$`â4N¦Ei¶/G›tìJMŒâë§Å…žÑ%Mçkl¯±"-«”ŀъ£LCF€#–?Œ÷Cy¬9(Áôq`_ÐãHÆ ÈŸ;3aU”ÊüV%9«¨li¸"–vQ=ë´ÁÊ«·Xeì oXƒ*%çT¿ ö GŽ„vË(EŽRÜÑ\_"ì™êþt¨iÅV§ ÑöW^Î ×Rs¨ãº¾PÒ—¨ÓŒ«‡8×Ã$L°±æøqZ(SÎì~4¶\¨?¢3ŒÌf`,®„!U Ó@Y*ýF£Î“ÌÓŒ½½hä]8¤­«vÀå?„X›=!VpgÂÌå¿dOF$ºTg†æMæB›¼[]¼)M>×”©%:‚MqvùÚ–a‰³è>x!$<Ü[c‚W*;˜ŽR…änjÎŽd¢ôxGê˜_=uW¢ ãE¬ÝíÈòÁ†žçî£" =Fª\X8¯IךÎå¬Á©³r'Rr6‹”õ'´Œ¾óXäEìA‚ˆ¹}ü5ti/’W„(sa›¬e‚\dqêW¬¬{¿tr” ¸øž¬>{r²8y(»ƒÆŠZpÛ9Jå7mã;ÌMØB F»$§¸ˆ(CÙ&kAöŽ–æ&'h¥¶\8¡ÆîšgEuMõ X2/r‚qõ{-àE ÉñEâDg˜³ Lnœ´á=û¡om•¶üJÀOÿ¬¨"¬E‹¹x®§é8¾ÞB3Piqè{òRçö¸å^„É—±I—@`›Šâmùûöõ2¨ÕâBê?Õ®(´åÜÂŽ¯kåzŸ/«: Ç"TŸëvè.ÿ¥á‰ÿcÃ#ÃK׆ðÿÒð¤BjÙòèkGC£ŸFs¿AÿLì¹—b¡¸ês`…~/ö9çQñ}0ùçŸpöÔ8 E"oú'kûÐe×ïË£À½VäÉ ‘©â‹ÕQˆ0œMÞFO¡úx:ã¢ÎO¤<ÉðžÆÇïy€nIú&FÎM<ºõí«›Pï–ì*þK"Á¢¾ÒTNr„9´º?i—®a®<IJj–…„.tÚŸ> stream xÚ¥XY“ܶ~ß_1oæT40<ü¶.%Φ,G‰¶*q)ª –Äì°Ì!Æ<¼ÚŸ>¹¢,«2C 4»}|Íx÷¸‹w?ÜÄþùýýÍ·‘ùNæBIîî;+Qé.¥i±»¯wï£lRéèmï{sÞ’\GÓ`­Ø¸ÿðÐ;)E©µBñî 2¡ ͧߞö*žßü¸?d*NfàÁxê­Å¡Žêf›®yalh:<5Úþh*; Qet²¼ç?±Lûaäã•ë{;\ö8áº:ðw¼jPFJ¦"M3/Ô_þñîí¡m~Á×x1FûÑs\½Ý/žŒ_<>4„¿£BêÉ5á„;¾Øà.cã:l°íñ°%šýxiMgF×?ï ê™ÌYó¤ÈAÙóÙt5ˆÞy [\…%ÒÀÏ'´mÃÔŒ¶fâÑõ<`‹Ywiý1ÖG¦·[²͹içS°ðS3žx´¸cœÎŠÒÄï>ò@GýÔu{ b?òá0Ùžö?˜±Â…“ÏŽ¤­Áç9Ñ þ›Ø¤ñò áeh¢ü<»ÞSw9¡ûU „¼ó,º+¤I™¶uÈåÉŸ¢›Äº¨'9~µσåsÓÍúr}0 ]:º•Eµ ŽràGÖ@"x¶¶›º˜Ÿ›ãÔ‡I0B;ðAô1\°¿¡œ®ð!*!²S‘¤YˆÊ$:Ë}L ¢ú ‰ÄPÀèëÁ$øÔg‚\ Ø‘{*ƒhG3µ#OÐÚøD#©´D³yBØþIÒ*Å!1—WÈÞÔr6ÍùÒúñHô ™_÷_E›.Äô"Ńûb Y $Ÿº‡“›Z_ øxÁ—’zíôJ¼sHmB©”_­¾ÆMÞMà¥#Õ¼”8zãö”³73`©E ùýê2)EnëíH‚sýñ±„„7¦§TN&ùíeÕZò|¢¬ŒE¬ôZÛäk´½ßCëQ?ˤñ;š¢W'Lašç©È•üJÍG‚³4r‹¶îñÙ«jMÏø0 ºéöÑõ¢Î/µ/J‘ååZùôk”ÿž4]èIe%\ýå‚×› "+— '¥\*¬’‚Æ'×nÈÔgHx³D>â*üð„ô[ûSŽŸgk‚38yèAB¶ ¥/Æ*¸”œ¬Ù‚·©R¨L¯Òåv©JÏ…þO[z ºîøuA£Õ<Øæ© (ÒpäðG™2¼yü+È…Œ&ð†91ÔL#KQ9„<. ¤¸'Ì¢¦÷[gQ #‡õ2\åƒÁ²„2ˬ·jš @Š+Ûÿ²«J}ÇÁ2–qP×€#P•ÅùÉ ³Ô@ñ¹Ív<­-–ÀÀ¯Ð3å Ц·­®r½tПÿÙ,@¿ÃX$rÎqÏ_æËõùµfòÎk‡`$B?Œ%à*©ÖP«2m5µ†š#Ám ç£Étl„’a=>çCWEÛMÁ0éÜȃ¹ŽÐþºŠÆMþ yV™PD$ Ù’æQOʬÓXsë‡É‹º? øîö\•B¶³…NŠj6$»Ž×‡É9Ï ã“ ^ù.Òû ­½ë^¥QoKH¡ç%딇Öbvv \;˜xÛ‘Ñãèv`jëÈà02ž2‡ Á ¬Ö<¥ ™×óápÆ!‚¸”ÆŠ{Ï8áÏ•‘jÂp3æKÜDÐa¤œQ£÷ßuÖ/ ‘^ÛQÇús@0ñõº3݃ p8‰s´ÃȱÝxÌ > stream xÚ½]oÛÈñÝ¿‚BÑv?¹Ë+ú8w>çâ"u„+‚\€0mII%çþúÎì,eI¡D; ê‡h9;;;ßdxtñèâŒø}9;ûû/JFB°ÔÍn"!-K­,LhÍчøÃåÇÉÔ3ü›ˆ˜M¦‚+_Vwë·tÜæ®ójž·„YT]Þæ*Ï¾ä ‚ýÁ ¯Z·°çOtE¶‚ 1ù8{}öóììÏ3¼ñH+š™4²B²D¹h^ž}øÈ£콎8S©‹¾zÌ2RÚ0¡ðÜ*zwöï=Ö¥Q’¦¸:FÐ-SÊ|CC')3RžD#Èòû²x ³c#.™s:J¬d„ó6zûëû7—o'Séx|S7ev‘6çu‰6ApQ¨›HÅjüÁ…Éðù‹®›ö§ÉT ‰'¤‹Á’`ÆÍ>šO¡)‘,YwЖ=EÃÛ<'„wù¼+êÊ[˜ÔÑܽ\_œÁïTh¦µ!AlÀ#z8œV&žá-÷wxGœ#Þ¾ûꔡê<¡KBØ×ãF÷((@ÉDX(˜ÊYYW·´Ñ-ó°ØÖHÇ-Ûá¶ÿÝgkª4㉈¦Ú1p§UWûQõ͆™LãU¶ºÿoNØåzÕw«œÂn‘uYˆ¨¼kQ"9³IrbqÅ4`œD'Ðèe'ñ„ 2N0gC¢»¼?³ŠÌŽ‹‚œ¶ Ž6 dô*¬ç5yVT-AʺÉ{JYE«º 2‘ìÚçh=¿]b¤Ý_½ $3.›ØHˆ¿ ¡E:‰ŒólŽg–ôTßÐ/°^âJøpGHF?mN ™›uµ}P™p×Ô·MV‚ó9-ÆC‚ “ô!u5u‚%v;èðâ>«n=Yˆe™“ɮĠ¢dœIɸpf–IÕ‡ÙõG ö„¿xר$<{ùj(´ƒ½È¼ÍõGÈ`Ò©ÁØÌ ¨·&‘#qa@úÛØ‚:`ñaÆiì s$¸´uLé`ˆÙ²ÀB”Bå¸óõ`ª8³Õªö¹5ìÝS ¢ŸŸé.8`µ Œàm× WîÒ—@0zE· GB]‚»†Fé+|¼ÈW­—"ßOœ |9Ÿfú›+}ê²Ûg;ì8Ÿìš6Üý -¿çóÈ6OîAŒj#&™A’Gy¦JûuY¬rªÌ›rÜæt´&`ÝË×êìö6›«í³+Xy®‘}`ƒ…”f·]˜VÐ"Ûà&™„¬!¤‰ß­?·]Ñ­ƒ“[ãi)D‚çvýyZ‚ƶ~\b3Œ§*šB‚IÇû‡À®j'b¡°ø[æz¾Êëâ$´Û j!TªànqZ ¡¬eÚ%ß—æB q ^–qû²°¯þ}(.ŽQvi®ãÆS›*w\µÃ>ÍÁ=îs^òC÷¿:¿Â±tì¼8tÿï3<|TrÈÇñBïãj£Ö«W㌨#´lÒGR&4Ú k"İĪÈhl=¿‡R9÷ "ìt˦^ß.û‡]¾yU!u+Bñ¡ ò{›‹vŠï»‰_BŒo%~|³®;¡qR˜Ÿ…QL¹£ã3زÇ`Dôe-®öe‘}"ò‹ÒK‚:*µá¹Ä×^yëEÁ…ò ìí¾t@ÑTü‰¬ò ŸôNw<ÕÂÂt—^o<Äê=„ß5~Îû‚YŽ ]¤¬ÛŽà›Èü¯¸ú¼Ê D³“OEèj:Õ†™p>˜Q‹Dwá½.¾ÑÀ¶,9A ‚1a‰w¸^<Ƀxpb{:Ág?Ó:ìíq¤©üËQxüÜ3 ë,Üýø‚ˆÃ̊IJ ù=C7• tÅ_¸€ëP%·Eç½^$ÀXä7ÙzÕô~†µç ~? úœÕÌÙÍ;îÿ†©‚!*qj7,.XʉQK•>ÅR0p¨8Ãw~Þáø.óy’ïŒjjºÉ5¸Î1R1k7¹ƒ ÎÅcr ‘,ªE1™@õ/÷™®g€òÄÄŠ³4IÇ\\™t\qî¨cSÈô»¬yÈÇ8ÍEV¦c>–˜§f7bJFÄeßÁl@QÍ;ß4P¶Ó¨ö­FôiÌ8?? Î-ùÿ9HEú5?’•CJ”‰g%KœÛ'ðrqŠZö©|/j4S$(}¶q¢@ìú7½ë×z·_ÂçyÝ4yhÝêj°ü7!øÝ¼+þrènüÿð@¥Ã‹\7€ÿz¥·º> stream xÚ¥Ùrã6òÝ_Á·¡ªFðÊÛìîx²¹7«ÔÖÖdªB‰„„‡†¤Æöß§/P¢LÛ©X/l4@£ï†|gïøÎ‡_¾ÿX߬nƒØ /ãÐYïœÀ½,SNê^ 2g]:ÝëŸË(‰Ýº],ÃÔ-uÕ#"q;Ý ¥·ƒù²3WW‹,p½Åvt×Í+K³7ƒýЙfÏðpÐÞµ¥Ò¿új´ì¾ïÚÓ±ç©vÇßNWÅrñiý Ü`(O©„™¤ó`ÎïO›~0Ãi0mØ®tl©Ðg¶Â,tMcSTg †îÌp0²N[Ü÷À#bIÖör”Zž<ÿ-@¹ïÞŒ,žaxÛv£øÚ¦Ä{ú9mù™{› üêÇþ7ÿLrž6;Æ$X@lŠ^3j×éÏ'Ýl ‰E'4€/*Ø' ëçî/½î,MÕ·Lt(P}"Ã9ùÒ‰Qä¶Gá¹N >\ð€3!óV<‚…¦c‚‰ïƲÇËi¾,blXYƒ²z}¦êäËñöÍ¿íq0µéu‰×úÝ »;<¿èXÖ‰ÉÐDpü‰GÄÊóÓ¶§mdš©×$^€P¼AIó†mg Ô½å„5¬H K¢ÑY@2ˆÏ2µ°ÁÌöÔmM÷]‰ï…aþøÚdò‘r·±»aåÁ‰d‚ód°€1õ±Ò5ˆNUTWŽ«&AI†C1ð)…VÙ¨ÀΘ-Øi?ÑS, ïÐk| 2Cë8Q±©È !XùNàt±øùÃó‘È™æX&Hövß=û—–'së÷EzÞfà@á_;+¸™LˆhÉ È¼´n®ÖþÖES‚Ù½™³Ó¦¨Q·JqˆS‘xšº”4O ½öšïÐ…à^ À½n†X«< Ãñ«ÕªÞh¯½‡ˆ[þÞžºÜßk»ýj –Ø6ƒn†U­’•ï0a7ËÓÕmèUE·×ÞïÇýDˆ×~‘gžŠFØ/œ±A LC‘Q:Ú5Á—צ9;FgR‰Þ“Eá£EØÒ÷œ/–ÂÍä:¦( $€c×Ú4<è9¦²#&Êý÷Àx#«À™v§Šá;ŒDµû¶ˆ‚KVp¤• ²¨¨MÓ.‹­)çÌä:¡¥ÓÃXÜ ÎL©Û´„È0¶Cz+—$É –”B([ýt (þýw%?¦nÿP×òõ–‡Ç¢“#ÀVŸÌAnÃ9¤Úº€å÷oq¸ÈFÏxöŒ2H_vÜÄn*³éÌ©гtˆ³ì& ÏîßÉ©{)Fš¹ˆCºõ!Äðƒs¥>'lŠoúœìñkãƒÝBЦ9žÉ‹ýÐfèíiß5EòÔFòí­.­±çS32&Š0%öÛÎlH¡˜HH.¬RœæãÑktn2›'ã!Ò¥žº ˆPÄ]"ÎN>3aìùyä,Uê…Šyüxû ê¿ v=üÁñÞÅo±„"3w”üÌ„}ÇšT3ÈÅûõÍg z…¶8wTšz‰:Ûúæã'ß)aÄåEyæÜeíD*ö A•óß›ÿ\í‘f° fÑ$}n O½(Ší¡’Ü‹ÃðU{Ø»¼¼Åõ]ü¹rþ:¤^Å‹ŠÅ>ÖÎûí V"ß}OzܨŠxZX¢n0éúh .Õ YG¡ýI5ßy¼RMaæÅYò:5½b{——·ø;jŠ gˆ#GA÷•Æ×>ÄB‡1¯½„¦D5TX’vê–Εzg]>¥+ð¥$qÄpãçîe`Sù¬®R/Kb'Ê/÷ã¿©«„bÝkö°wù {\_æ™–8Jc/%‘vn±F¥Š´Ð`J8m+ݦԌ LMAbÛî|aþð@W5㦠j]4rvgh6/œû&,¥aV”¨ÒÒ7f`ÈèÜÿŠ3&ª ÈGÔ¤ÀjJ#ʦêâÞÔ˜S)!¢2p 7.D¤áÙd<=Û§Sâo»?ЬÃÈýM±= [Ö!<)aÜÿ¶c‹¥ ‹±L«ô˜Ga'ÐZÓiér’ ¾ïͦ’㨠ƒ~˦ö§ ‹$süÁ¸´=¯Èï‘I¨s}àaið%ds²Ù™õ#ÑÈgœ³â WýëL㪠¦€HñýþžU"èãnñ ‡ëauY_™ud•†CŒ½Ä\¯ÿ¶d‹.óˆ”HÖ±¼©z²éý´Á÷!{Pk æKQÃp3¾@Œì$å2u6Œ¬mù+{ûxovTÂÜöÛöDŠ–óu垟—ˆ qX"}bÇèœø- \%ÒÝØ{#ò\êöB½ cã,±ÊÉ=''•ÅP€òRó_£~@=JZÉÃÁ¸Â‘*E x)¦½6£ f0šÑíœ>d/eIÆ*Rå!€ß·¨yžÔ§|ö…‚hvW4x;a²eÌæ’þØ¡’I·`™½.ÿZáºLb/L“iåºþę՛ùIåºîWÃN©ý¹(Ú™{]®ÆPúlUBæQÙ+‹×0„Üäg/dÉØKRõdUôš=ì]^Þâú.Ï$Ú Ærqª[sÏ 'Û|LT<Æ¡ƒTiÐòV²»t=›"·¤¨ªH¼g²X’[êÚnóÉä6ãL”ê.²Zšâ{¦¥üÑ” \Æa<ªx¶Àeœ¹MEO^„æ—$ý×ï5^ÆSÞFçm#8Ã`ÑÕ?„&‰{jJŠ©~›áCu”&î×ßþ?‹ÙÊäú‡> stream xÚÍ[[o»~ׯ`Ñ—“‡pIÎðV§Í9AÚ´@¤@Û ky-+–µ†$ÇI}¿¡VN|ÕÊZHÂ]-—ûq8—o† 1+£ˆ½²Ðå²CSB›”OŒ6«è²"oTŠ­UÖ8‹ §¬ xÓ²dÒˆËø*’'2‹'Q¦`ð(C lŠ&øcÑé1’¼Eh奨"—®Qz$½•_ aa”yc!cðÒÅá"cXèSŒ 3€®$ƒEfçT²@/P1¥"j•8²’¯¤`¥s-NH&ÉÚ°K*›Ò9«l#˜ŒÊ„ 1¤–zÊvöI.Håèä‚UNAæU4bŒaey/Š ËÊBÑ­‘Ù0Df÷À ®0%C[“ð9Ñg#ÚÏb-&;ºa dX„µ2œh%Ë¢;¸b±¥(W¤ÌÃ&GGG£ê÷ËFU¯æóv5ªÞ_¯Êýß§óóQõK»8i ÌÓ|ªþVýVýúÑ–›Qõ®¯ÔGX¬¦hEt} QX į} ô{¥ŽŽTõ^Um?´ªz­~Z^˼?mçÚm5½P?ÿ<Ÿ%¯‹ )hÏuÕÐÖ¾ˆøˆ¢ÕbÜp ÚŠH¤Ct}ù òIgqt&k—ÄÏ¡u¡/¢pDì´ 2bñé¬cê (‹:ZñãYMÄ}¥ ²¤‹ I{ *Îë”zË(ˆÈf-®ÅÁ´|)|ª6¢-ì‡7þïpÜðâq‰µDV—¢v^4)hDÇ~âò¬*#28Ø»…˜`iðH¶/¢CÈÈÃ7‚bˆ'rr¢J:} é­åñÊbVŠ(ihX—Îþ Ú@±Ðd cSÐ\ÀÁú½‰[5ÙêC€1F—Hž½ì`ø&¸`Üð ÂS&f-lH”íÓës EC=‡§n¯£OOø¥­¯ÕG 2ö;UýëßÿQë$ÒèXͯf³O›ÎoÚùªŒûÀn—×Þ¥ÜÝXñ4TnðVõvÑŽß7@¬ª·¯ß¨êCóu¥>ÝÂÛzÒŒª_1x3_-…Èë2Õe{µ7Ë’=”ŸþÑœLë_Ú¯ªÇCˆC‚u¤ŒY¿­BIÒRºñ.ñqIX’ä+ë6•öÓƒËñüA*•ý.ÿ Çò{&Ð:I) <>R/ö!Pº%-+Z½::*_¨^•5¨ÞWÿ|÷›üýélµºüSU]__ëz5¿¼€.›ÙlÚ,ô颺<ûv1{ñˆÖô€€`1Þ„{$WžÀ³ßærÕ\žÕófr5Ÿ@—&ÓÕÙÕ±ž¶k /OÚëù¬­O–Õó1‹‹±¬<ƒhÀrÚ!ò°ãìΘ'‹öêr©'m;™5zÜ^¬éŸ¶‹«‹·í!šžöp¿³+}flÏÎ › 0áG, ‰EÚXB|ÀÒnäsÍ.ñ=³¿ÛÏìâ’¤øë¶3¿˜º6¯ÛÔ=O¦kmׯ'Ì´‡×Õú1Ügmá5C„µ‚…µ8€"%÷p¸OWîôÝìèï`¡—¤š@Çên‘0ºè$ý×äŸÀ²¨¿Â% †ÃÖ’…opJ¾ŽI½˜MűÝÎ ¾ˆã÷saù‡ïîBW‹¦9ÅRÁyž4ÏwA%5–ªŒ?ÀËsvZj#%uN»![>肊۩þ|ºh/Öÿø‡õO{¥]Ýþ†D‚ò[©·eD)‹<Ê’ÿýOÀ™u*ƒ@ ˆ%/‡°Cx]nL÷/õÕø|VÏOt=Öóÿ>ûŒŠ_–J}ªÓ "æò» ©7l&—£Äâ̘ëìþO4@âß&\õЬ·;¯ƒeå·†úu&YD^%Ã’‚o¿Î&HÀx”?™oQåç†é|?Lç}Ãt¶û±á~! ‰RA|éƒÂ9z–+¿/u=ŸÁç|©Ͳ©ã³êrÑ~Æ—ÕÅåt|æîªWÞE½òë ê®3û~‘7ér¿Îf=ù½ò©êÄ öQ6î®úÈ^Äê#±ú®út¬.w¬.¯YlìÅÞnç¼¢”MŠŒ¥€ì_ªHX2¤÷d·Â~ì;œ I¶å˜Úu|N6!¤Øÿ8gª¿A•Ÿ¨ô &d4'©êIÏÝ„·ÞoØ=´Û“æÇÀ~Y75n^ΦÇ„‰àžAoÑš¢ä² q8˜°?Ù™ëíîtîR2ÄGw7Êìn¬²©·yâ¬ldîe¹öžã—=½½,W6‹¥ZÓµvH‹Ý(—B+›l:î”7nµY?da•=\€'ÙØnúø›,üdÉlÀmÚ˜eóÞ‹Jý©§Tî:]ŒýaˆîÚâÝÎOÓ©;û²=çûuæ ÿÔ¯³ÃRû¾ a!{v¦q÷ ƒ¥°«Ã ÌÞÆ½,ã=Kg¿§¥»µeË^ÿº¥®å®õ]º6vmêÚÎSPç)¨ºñ¨ºñ¨ºñ¨ºñ¨Í!QTù|uÞ,C‰T€Ë¦h‡XÍlr>½¸ZÔÉ XðrX 9tc[K°Ý Þk©‡PΚùôRŒÅG¥|+lŒnÒ—e&>‘.ŸÔã³iÔzàiåC‡$! ‚mEr2½¸˜ŽÍ>Ÿ’öÖm8ïÊ.gO™3¤ù$lØ !ç4 ½Ý†ä¼]NÛ™ÒÍ"““¼$X,Ž=drÂÞ,†” —J9mpð¥è¿ɸnsº›¦qØ!M»Ý¹Ky,HÜc[Ä·J?&&oí$?7K¹Lƒw;¦ñ@–Â]VÁ]VÁ]VÑí€3ó Ù‚Ôí|9µ]öûlŠÚÈQm'uì‡ë«úxÖ yºÉ‘áŽ.Êí¢Ï) 0™œ°6¡œÙÔƒTÀÓîX.ŽÝ~=Åw?Cæõl©ÛŤ¯µ¥²© UÊZz¶˜ à]Nö¯.úd5f ¤4LrFšæw­‚Œþ ré¤J†Iøò+`.R%s:ømE²ø½°ý? %¯³ endstream endobj 478 0 obj << /Length 2358 /Filter /FlateDecode >> stream xÚ¥ÙnÜÈñ]_Aäe)`§ÅfóÜ<Ù‹¬½½ë8J€À6ža†0Y–•¯O]¤†#ÚòZzû¨®®«ëšÀ»ñïÅE ßç×W¿èØÓZåqz×{O¡Ê²ÈK­t”y×…÷Λr¸Ü„qì·{üFþPÖN]n"ú×—Ú?”=ïW¶Ƚt˶á3Ìpp‚¬q¼3ö®à¥²áï›—ÿyõë%“Ë,ôŸ½~õƒ ¨msfþh«Ë×N6:RQ”0±7å§Ë0õ› €ÛÎá(ñ Ô ¶¬xj·€-õÛq`@"‹àÊ~(›Ž; èD{K¸]³8ƒy¯å…Sö{Æû>ˆ$øBÉ×ÝxÒ´‚¦ñ×!7ýµv×µ=¢Ïƒ™mšÏúïˆÕ¶ÛÞu|oÁ+Ä|EØpÅ zKè_-WµÑªoy$ögÈ>Vˆ<ÚÎÖn B%Ë€/Gµ;žðc«FÇSÒ)Âdá…’«_B³xå \“Æ“ûþ‰a–žÀ¨±Š%VY<Çž¿®á÷E„~Ç7ÐñÙêls#¶"žé™Š PZƒië3‘v°³´(Xê \g˜/¥ÏðaiÄç’ ¿ÞTåGÒUZ~Èô¿`È=ê‹£{÷ñÛâa« ‡0¥*œüí»·S4Ä?°Fø·Ñ üßÇpŒÞ´ÝÝ2<.^ít`—dÍS|¼sýUÓ~),F*ν(5*‡€òµ@ÅJ½#È;Iœ¨ ¾/*æ*Ã'á˜xyÅ9/ÁZò»T†ÜÈrž”™'µAílsU»¢´Í×ë“Bž ÂzR]`S”="éX%iôźà)8ffÇñ'êAbj$W}k) ΢ð»ÈÕ¦­ÁɲH$1laG`™†gœp^Š@˜çàwJ¥²RîRî9àl±~-INq™,H ¾–NÕ«]U9 ØcÏÙ&,[^Ç¿ëÜ ¡ÿ†½‚lÌ^sû×DÀñþÆÁ= U’ÍÉËÛµôCpŸQŽ·õ·å°Côžs t¶Ç¹r€ô9T)(cÁ&‰=Œ(/ŠBã·˜ Å)¦Ò7ç4@EÛÀë'‡ïyïç“ ö…ó‰»$$¨Ö®s½døM±¦Vs|’«OtÀËÅçÚ9¨)¤ICï•À»Éæb±9.ð²ÉæÓ@ §°Ùpæ†bÝòô‚å“õY¹ý’_“äTúá·wH‹ðø³ª(K͈}¨a– >ÜBÙ,°TÁâà¶ìÝóM;¡&–ª–ûJ ó…rb–D:K 9 üW¶»¡*ÃdòD¡ èyn©-|sC0=vnï@É…àxÙ¢ˆ¹íÅ:ë°T‹´$Òpd×ÖÇs‹²[ïÊmÇ®@oæùÜN åÎuíôü=«§%-S Ž_ªÔaÀ}Àë¼A}JøžÎÑþ¦NÔÛV(²pÅ]¿.^x±´÷ÜÏø³À™¡+¤/[ˆ7ËE…ÌH•ånš8§qYˈèÎ&aÐÛik¦Q.+Ô¶ Ýb‰ð“žPËͼMÿ·_9ns…‹ð|% Nj!|ðÒ’r„aXà^ ,5êìÞvåt{Ù€»µ½Übûû;¾Í‚±“Äâ0Y L`sªä¾n0_Ðã“Ë#ÿ%–úÔD0b™iþÄpš§K]â¼?´cU0ÌZÈ_Á:"óYôà±âšåÏ{m"$lx[¹¿ðâ UؽÂû©1ƒ`!7ŠÄçáÊ}cj o° ç2çÖ„ ¹Q†ŽMX„Ó®ø8 V1´®EmbJð$âý¼¥ïk~%E:dŸAxì¸5 ª¦œÇÒ,„5j|I5Sd/ÿÇ$›³jræˆ{’9ÒÐÊî¤gƆyH]6®êRÇg„)»ò©ùø˜ƒòõ-æ-pfJ¹E0ÿ–!}¾×ÝsË]Ÿé'‹_zÁ»oŸ}~ýŠ×ÆÞ­Ü¨Ö4û²½ÿ¡‚œ,›Wª§_^2! Ç©ü,“.œWŒO¶ç§¿+¹×PðQq‡x › 'œ|©Òó)p3”‘Èd=s,%H8/ j~ÂÁ]2§ß‘éÈBÝZþÙÛÈ|ÇŽ'ÎRúظÚOŒ ,Õ†z­mW Ìm$úE³ÇÓY¦" ææPHHûK/` ðø?aÖX endstream endobj 484 0 obj << /Length 2266 /Filter /FlateDecode >> stream xÚ­YKsã6¾ûWðHUøÈžvj“줲žìØ[98s %Hb-)jIj<þ÷éõ íñ®Ö±Ùnô×¶ŽÖ‘Ž~ºÑò|óÝÆGƨÂ{ݯ"£­ÊseÚ(ãòè~=ÄáëЕ‹!,gs›úxÕµ S÷³ÜÆ]ïË>¨ÙÜÿ-ô»j<>lªþY¤ð–aUîë_ÚÝPµ[¦+yþº™Ù,~þÇ/ÂîEVËÏ}fŸï† ÌSÎ¥¬#ÉO7¡Ü2…[Äm· ³PM*ÿ‹žp²"ÖÖÕ×Ìbþ]ö<¼h›]Ù•u8‘ R†MÛ «]ɴꦴÝñŠu»Û0T °5qß®†™Íã',;4ifŠøã6ðxƒü}?ðÛ#Ì` 7JãÕvÉÔ°)\÷ÆÀÊ:êÖŸ~º‰hÆ+›tÖÆ‹rsûºD·Oìà©6°IãÅòÆ–V¹Ûu-ŠÿZ5 §d'ÓH˜Ø¶µ¬º°êgfŸFɸÇE<ëôÎzO(¹([¥`»j»F2 X`º ËŠT‡)§ª³ÞhÆ1b@¦¢…L¦¼/ÎW»'}÷›rGZÉ;ŸÊ&€±.›¦drYõCW=îÅD0k†Ð+CÏ3_uåv}!±+á|™yÖ­æ¤ÞüL?Ïúnðy\.º¶ï™î!\{8jì]SÖ5³Y`½ÁI ÚÓ‘ÝU`TòÌ©Dœ¨˜Ç—ÿîG›œ‚ŠM5h‘€IïyÎ9ð$Ê!3Ì”¯rñ—)^YçÞ.ãÛzèϼ-²¼˜aÑv`ÇÌ–cÎa¢ò"»€$: €'e‡~³YqðRùXÕ!±ÓêøœØÎDó³Ëe‰I+ÀäF‚ ðy8 áât˜ŸxÞaÎ|*\.4*29Òîxb]:žîœN7¼c¼6(˜g.(’€x<„¼ü®ûJaH#ðõ3ÓøàºHhåúcpüêKUN)Ý”2ŒÍüÔòx‰»I0]Ñ ½Èù‰=Ë~Ϊ ²ž¸ÿ¯SÄh¥ýá”1øƒQB (ÆpÒn3i#vŒ{¡|Àc”ù”¬®07’°¶ž2ÆñJ©2*™Í±¸‘ÂaÞQ™‡µËn1KL¼atCÖþqÞ„-2÷g6>/wn½ÒEÙ*“Še>Âñ÷€¹ ÿ.Õäè¤!ý}„ 5f@üd í&èÊÇÕðé5æ³b{R…‡÷aÁu¥;1EN¦N¨E¥(дübÿ(©ÇÙx×í·X~Ll¡D±Iþë®\ R¥Bª»_? *Áé‰? <‚%j'÷ šh çH]9pÅ £•H;ŸçÓ•O’À‹Oh Þ‹¤.†»Üy@ç'¤új½Åcê‚û¨ Ô'Ù®ƒÍäŽ ¢»fÕ-ùíÔ¸ï0+AŠ€ _á÷?ÜÝ¿›RÝŽÖsþpúQCç8Å ÿ´¯ E6²åÞ‹$[¯ÅË;~9XÎòÎì°ï¶=¿Œ×å£Pa*¤ú¶ï²x›ñÿüÂ=&€JG)¦£üõÒÜJgfL6woÏGÑ’qûðjbb8 쟶Z„·¦%ãœÒÀ/ª,Í$1}zC -ùé_cñ ×Í%¶Ø(9 eÇs(«_JLÖk•Ys]b²I¢’<½*1]#cÜË·E\îEOu7/‘…š!Ë"«s¥­$ª‡Û7Ô·ûæñ†j„»æè&æ&Gnz¹€°Ìdì•~‚œk²ì:?]!cÜ ‰ÈÿO„É¡´*¤ëü•Ü6ÕãÄÄ,˜ÓvÌM¨)C\Kò8µ‘ËEiXR7ÚÉ­Hžc]"Z´å''}%îžê=“»©ÃÅãflá l… õ¾jof’4Ï©ÌÇWìzÌ—ÝÍð;‡zæ9ûÈ:/êít¥AºFVãr•Ì~ýjãðNÈN hÄj|b6¾Ù!Oyûi†:¶Ð¨^éŒÂØGÃty/+(¯‘F<©…†Ä±?7¼$—ßž¸gn`ÏÚ^´ãȆ(Ýk?UØçtizlSáË¡å„)Ü'c ‡Ê~Øq]ŽÅ&P¨C-ôQâ¼Ór}PRk>•ÐÉrý©¬ G­Ú=WMþª²ôð/à·­Û\TÅ‘-7ÃðWëx€n˜YzÀ-j‘Q˜Ï»ÌŸtî€;ö©îá*;xg5¥ÉsåLA5 Á,ùÏØ³I‡!-ŸÅ endstream endobj 492 0 obj << /Length 2353 /Filter /FlateDecode >> stream xÚ¥YKsã6¾ûWðHWE4ñàë°‡¸j“lj×µ»ãT` ’XC‘’Šã¿ýEyh{§ìƒ4º¿þ§Ñ.J£Ÿ¯RùÞÞ_Ýü¤²H©¤Ê2Ýo#•ê¤,mT¤*Q¶Œî7Ñçx¼ÖEü|¬ÛÝõÃý¯7?=ïbÊÄ9 Hºw¬r9jž((ˆFr½²Eòãˆ#B¥ˆÇ½gi‹Søûx½‚_ßsC·eÍÞµ›îÀ²at}#ÇÞûA†ëxÚÌW¡ó2ÉÓòÍ•ª<1ª *ïÚAFß»;D+£«ÄfY´R6±6—-B LíZ×<õ€µ2~ª›†å£û‚Fy–ÿ‘féÐÔ»ýµ.ã±yfé¡ëe˜­µh†ÖIž«·ÍÈe² 2Ö?„e(cQ￞êÞoX¾íz1„­Õ¦HŠ*¿´6¾Ý¸ºX•ÏL¶ªˆŸö­À†®EËPØ]«¸õ\FÛoëîîW2g x,ç1óø4ø ¸M‘æñ/nãî›ÿ“v´ÿVš.H>_ÖÐðÛ{×piã`m£ãÊàGQö<‘Téø¥$‹AÎî‡EÕ7Ò–æ¸úº…9vçþ ë ~­3Ù.vDZîZ.»æÐ "ž‡Ñ`T7Ök×à>£xïpÑЧ‘œ cËMý…ö­©Á¸”:2a3p3:](uÃâ*ëvë{ö͆¡U½…$(h¼”§CE…Ö ;”ਅïKHÑY’V6‚ÀK´©xêÏ¿=\¯2eãDþ®W*5iü G3e*÷AÍÉÓnŽ®êC×>߀+õg½cW¿¿úz…1•F*RÚ&Ye•IT^EëÃÕç‡4Ú@lHbª2z"ÍCd,ök¢OWÿy1FQ E–”ƾ5¨‰p}9†Í«$ÓúCc[Þâ¥-od‡,³‰.Ìï{nc2+¡:“@â#ùX×t»gnD—>ÔƒcÇ’P¦@ÅŽ§¾%?ÃööŒÿ›ðòù_ÿdù±g^{>2¨sÒkÏ3Ð&äë ± óÔ`ÀZR#V2˜…wþ©^ãð_¸Lã@IÕ2R^:|òkòvyŒ ,P8PâeD ”ãbaGÃbgÈ‚ëy]Ãeq9híÚÅ„÷„ vänÖÈ.Z¤€A®9[H Ÿ‚}Õ=dQ[þ:þì0^!+Ë6 vââØ¯Ïš`(Ú€¬%Q+WM„I[¾Ž6ˆŸâgÂ)úž‰½œÖ·‡¬Qd·ÿm‘j¦IšÙ‰jv<2t0~ðBX˜i¢¢ƒP…Q8m øÜ†D&,æ®JHe x8ÜP q>¸`$ÒY| Tj}mTŒ›Wdñp:‚…PïT±äqu€ýÙéÿç#ȰBP¹}`ÁdDM¼D¨‰®â;t½ŒQÕü؃ÿ1yìºq{w俉¢¾ÆDL•'en>ÆDLl¢üùÈÁ–÷‡ø&b²"© qoBA]åräèNÄ£«‚b[Ơ‰KtãÁ‚wìµ\«9è1©6,y$Ç:kð˜ÅyÌ#‡D#¸ƒ9[ŒQwBFšpX-&Ðéò Ôı¡ØvíjîI({œÁ‹ø‚ ðb¤/¨q¦/Fú‚ò ¡d@[èS{dp|mv¼ò(+bð‚ ·KÀQÁ-6(Ì&Æ .=• ›k–,e=a]¡§BÔ¨eÌ‘s.”€9Ž£ ÔPξȼèDùÓ"Fó0 ô0ßÅõ1ñ<6pG)YC gÚH¼fÌs"–Ëo ¤"é¡`!{àWÄètxS‘AÊoV•Ë0±|›%ç¸êzb~¦<_» ºv—tí^Y ê¼Q(ŸÂÇN+¿œtéÚ6{•´Ùð9ÒE(¦ ¹¹ÆÅYÿâÛµ§åØ`uxàÀR ×"âšÙMDNã—ÞWL¢ß~_Y¥ c]ï-gàúºƒK´0â®Ý]~µRîr½ùÜ“ÎUVá½f’׊4¼÷€(0qÆ7––.êê"%‘´}ñDޝ§^Ó×»šÐÒj#‹r`êÉ¢eÆ$p“xï!«ÒEPù }ùD~èZ÷Øx±ÎV‰±úҺŠ$j²åï<¬¿‹C@v¬‡øñ]ñã°ê/rwVnI¼²Û0—èñ"-/&¯q­ó$KõÇ8„N+b@á#ØòþßÁ!T™…¿fTÍ¿–y°aJ¡P¦ ß‹ÊZ˜4¹x¾æ@Å…q§›*^aÆRÈ:xì( G=Î׊EÞðò®aÓ₳ؘ¸UŒwî£Üz¼Ö`‹£WÛ´¸@×¼Èå6…-´(7.´„ˆƒ zfÉÖ x[^| ›i£Ëâ•.1åªx™€ I@©é®]€íÏ·q”&×ndÚŽ¿ÁP®mj<'߯–ë,Á´¯'¹ÖcM8‹[CƒóNlNky÷L)£ÚŽº  qõ@Ž“†ììñáæl¡¿hÄ+™ã­ûöµ–ak™¾íÆ¥­Æ¤2Àb!OÓ«¹ëé`³\xHš†˜Þ‰@Dàßoü… è-ÝpKºáVÕ ¯K/‰ÆÅ½]•%ä€ ªMJ+1á2W4ûÃÍc endstream endobj 498 0 obj << /Length 2104 /Filter /FlateDecode >> stream xÚÅYÝã6Ÿ¿Âoëµj}Ëî€ëâÚmч^wúpØ.°G31êØYÛétÐþH}$qÆ3‹ídq/‰LK$EþHQt™ÝeeöýUÿ¿½¾úú;*3JI%%Ë®o3Z2bŒÈtI &»^gïòºßºqUðJäM‡ÿ2ß®˜Î÷íÔìZÞüVRi‘úþôûa$«Bñ*¿Þ¸°fín-,‰ŒÆ@]$L} Øo=—‡3¹¿Z‚2Ð`ܸ[Ⱥ[7Ý]˜ ‹Þ_ÿ›)¨ B¨ ï„™`¹]Ñ|·zdøg³µS¤£ƒ"tŽCÒÖM›Þó_#‚¶c=47žäÖaîÿß¡T0#ÉÚ¿|•½£9“ñe°1¨ó !J áÕ :™™Nmó»×§m¢I›… vjÐ\Tå“§0ú­”%nø§_V†æ×ðH˧µÍ™z¤ìW¸Hço7Í50ùÚ6°µoìèî¼oîñÇæűüú¨ÃÛ7E"u'PyœšzŒË÷¤ç8Sy£‡(”øc%En›ÖÞ´iÆlÐÈ€  XgÀ‡ åQ \¹ *2U„­ J™Ì_÷Û­íÖEÛtÈEKô(§`ÄáÖÖ.²š°bŒP¥¯!þ•öÈjaYÛò€wîQ¬TÜ~~óߟ~ø¹ðÞ5iH…%( ['êx¶¶ž« ¯Ž aY²à¯£€sM;…Ѻÿ] CHûIñÕ6­¹}H«]\œÂvv°*µí µû®Æ-nŽËÔàß!ßL›0  ƒÁœú ’Ds¬‹Íö]’мhð“ÈGã__}¼Bt#ƙ愞IÍ«hVo¯Þ½/³5¼µ¯Lvï§n3NT…ËÚìíÕBZœkÀ´"F Ï«„©^‘Û¦uÅrÈ Œ]D*/%©(›KíÀþK@eøR'#½ æŒÂÄDL@@nL8êoÿmÛÊÂ;`¯‰â2úO¾È-:܃Gv¸Ûo]@f„ÅaÖ¦ ãk2ßî’m5qá]Œ¦ˆª¦›QæÞ¸v÷*GWc X‚Ùý¦©‘À‹‹YÑ=îÚt¼„´Žäû ÊÑKñN „`f™´Ò¤”‹Ð,6 é’£–†ñG¡˜GU&™Âç>}È}É/º„#šÎ7|Ì‹gIã˜)c6"õü|Cš?ÝÑ_>s å¶oÛàÂiGXBÌ,¡‰ p#ÜD°@I ÏÍÍG‰á4™¢yÁ\Òw©Ò<`úaц˜Ã´¢hºÝ~Zâ'8)?áG—¸K“–Ó ×¤b*“P)Ie^–^%ŠÏ‹«ê¹ô”"•— HRRÎŦüøâ†H0ý h‹¶ ž £ …ä÷¥¨”¤$ …8yÆÔos©FRÓ¹Ô'Smb •lsTY†ež„Ùuþ OÈ}ݺ~jÖ‘ÖC 0„¡Ý6]_غY‡u`ì½ëêèF.åÜb"E~ŠÞPr¤ø Ä|>t †ºÀ·ü¬Ð=„Ûú‚‘»¶P+>ì-¯ô´ú¬àEvKaĈD” C˜~aq!ɘô¼JÍb%w€a„Ð: £e­¨„,Z'Žg„|¢ÁV슼Ss­ÎíÊ1ÐD/¹‰C1rpy·˜\Á•pl¥9>8 K™ûSõöU<V4U—ᦀt,–¤KN˜:xÕÚÏV(bté(UœHYÍ]Bnüâ1óñ‚1ÅÔØöÓGŠØC \ÌÙö_olwç¯ûìä¾Ñºt·7±ZÐ1·„‰¨éÌ•Hô—!˜´Ã¥^ÓÅ_ÜÈݼMýŽË$¦îf!-É’€§¸Tp¢ñ—e%˜ NEçiÅijÉPW[ú2b ƒq5;ºiŒƒ ž×®K† B ’8VFZ¿, „9ó¼„6Ï&`- •›ËˆÕX Î¥&C<ª(°ÒªfÃTb%F!dKw—º"pQ w¦Ž]“g}o.öC¼܆U~מâ5™E©ílû0ºO„$ÔG”ÆT+$w ÉíɡУôqÆÓ0Ü:»Òþêo£J`GK(™ÃaÑl£!=…4Û¾ ÷FO';LÞþø4 ÌVYÂÍÍßdn]e®Ãp²¿.¸J$×.¶1m]÷ûèú‚S™î©0 ‡Á‡bÿ*tÔ°ŒŒ"ñÑc&Ø›Ñòð7ó3f ~õ;ßòëÛþî!}!¬4‹%5k{¸^ªt½Œ0 DFøŽ}ç¾xÖ¿¹ Änú~§Á.ÂViHô³Ò~*§“`ïòdûT‘TÍCì¯ç7µ¬6g¾þ2ùiŠa„;ÿ\´\-¤ò›E븄èG²ÎÒÙLVJg1Méx z”¦tLS 4± ­ï' n×6¸ÇåÙ™ và `©""Bˈ6&þþ6iªšækb׈öü»S8öøÍ¡Çïߦ®> cW_`Ë62<ÚÄä'ˆôíiÔi“¡eÔîÝ<,}wh·ŸÜúæ‹Æ¸¸ùèi$€ù˜¤yA¿ÁÛ®~l2¨†žþ,â×F“á0˜ — nÚÏÎøâø…ŸÂ‡ˆTÿ}æŸ šzü?Y¢æ8 Á®.¢‹›@ÁÛ§­ƒo °ð€BâÑ:øøzÓ°âÆŽn}@÷{;mÚ‡¦ÿÐÔ1<ÛÚ«XKìwñÓÜ0Ùr ‡4†CEX,ƒ¨˜M‚ì¤ äò endstream endobj 510 0 obj << /Length 2279 /Filter /FlateDecode >> stream xÚµYëoܸÿî¿Bè—j/O$E=Ü'äâ4M9’ª•(¯P==j½?¾3J»ÚÈë’úƒEŽHjž¿™ázÎã9WgÞÑóùæì§K:œ³X)álr‡ûŠIá;¡Ç÷#g“9ŸÝÿ¬~ß¼™výt)Ål‹`*Œà•Y[Ô=®†sÕá"!˜TÓ¢ŸWk)wí?[­}©Ü¯Öeñ¯•]oBwÛ&õŠ»)’vDê†ÛÛÕMÛw´?)›Z³#ææò¬¥Ïb8k3_ü¿åQVž/žò2'CÙÓÉímÛ¬DäÞUÒ[AŸ'Hy0¢w“ì zý¨ìÇK&°ŠYìsg-|æ{Và/OËÌY$GiÖÕ’Ä<` Æ5(aÓÒº££"MËÖëªÉt¹tž/™ȃóøÒió•?.šÎ:{¹9ûzÆî9ÜÊcB: ™âÜI«³Ï¿{NïÞ8“qäÜ™••#Yã®Òùxörÿùç„’,œ%¹ ÏÖI¥ñ«àD‚³0”0åúÁI®x_óC'0‚ªïb‹ÀŽŒà,Ê æl}㚨aT™uÈnØv}Ñ}ÑÔä«U¹¸po¼ |"š@Ó Ðaæ\ßDSøx4½ÒR¯”ç6}‘éõ‡Ig(ò!_8Ñe·è„ÂûÄ{é]ÆS“_½úå·H-$%‹ö|° Çú!˜srì?VkÅ•ûæEãÈ ¿DÞl~ñqn¥Äwß¼|¶˜^!Åìq—|]†Ç”Û¤ÜïuÛÙc:s•'ó#½€0Œ\Ñtn j.íhkÒŒ¦ "HUXSCVjè™ttJoçUro–;©Ü±D\Œ¹²Ø–pJ„îkt‰Ðº<­w]ö0$óÕ»ÖÅuZäôÆX÷ãPyÓ à@J$&Vñ_SØÅVÈU<&“cnÉa[•uì`@ æÇÂp¿àÈ`@i¡xìhUS—Dìwm3ÜìÆ‰¦÷ï_ýööõ{ª­Ñ  P2ê6OÒ§²¿Íå§kéÙÿb%À¸Eݬ“µ¥úǬP*xª¼`xªà’…ñ#o¯Ï:5”¢päûdhóû¯W³|ÿf³™Í¯û/?©?`Œæê·Ëþ–<ì0œòü ÏùÅõÐÏÎû`Î;¤¼¸=¦|š³ð¼lº¡ ÄaräŽ×ýuRÍ*Œëþ¢íg”W¯?ݶ?¶*àñøÓU BÛÞ¦ªŠGŒr…˜Mò¡$ÚÝNÛ·)C„Ñ@¹Ä”@2õ <‡NӉݔìý•êhÔQ0Q`áqN¹ GÈ¢ARj,Á"Â@Qš,aÞom¦Ã%Ö1íöïwfÅõÛŶº{¨ÝÛ"Å©Aûž^¤‡{Ho©)Rž˜ÀžûsÊì#>ßø%d÷¨½³ÛôWØ7e±m‹¡Zâê@™PfD‡ |Ê ¥o5½º) ª¢ípZØgBäÒ®¼Ûc¯ŒSÓÑžÎîé(od‹E‘)7À{G…ã˜D‚c7MUÄ­RŒÕ’)6`lôhöPùãOÌITÒÑ0Ó] ¥%™Œ–šRžÝéJãH!ók…Ç/$´Æöm14žæN€ï;ù$Yhr¡OöcåˆX1ÄßÙäÀBk„gAâ¡J}òÛ¯FS°ù‡|5ö4³¯æš‘ FØ /Ü9ø“ЈþðþÂ3ëíל‡¶øq°SÅ‹•7°k{˜Žä´©ðÅPvMû@$‚EéAt×IùÐÙ[Ìb_w¢Ú5Ô™nc›@àŸ„ÛµH2« C“f;mñ"ÙÚ‚J((P¨YJè Êì}!a ôM$¤ýRºæÃâﱉ=ËÀ7g‰0zòÆEì™ëvÍPfn÷Í¥ÕÒÖ + Ñt”\¨…fì0a+]¢¥ìÝ"™ ˆ…½ßy=ìÅõ[šM€ã½ ÄÿÐâàŽ¼™,õ8æÐâ÷ÜCÚbhYç> “ÎÏ—œ&düàîpépªýUÙ9©ÇäÐÌ.ýÅ*%<ì¿ò‹óüÅy~užo?‚GN¥Ê_l‡…lÏÍünßºÏØ@#CèN ¤ƒ¬yº`wâ¡zâ¶îÄÝ÷¢â9€Õ^­ö~‘&ð–bï ¥L¡¥°ìâ-ÇáÍJÕZ13ì> stream xÚ­XKsÛ6¾ûWpz¢fDo¹¹nâ6=m¢ÉLÆÎ–(›S‘tHÊI¦¾»H‹*mK¶."¹öñíB4¸ hpvDŸy~;bð¤ ˜Ž‰2,ˆ'†Š`^]~¥Áß”“ßíÔ"àÊÆ ¼¯‚OGý:;:~ÇTÀ1Jñ`¶ X,ˆÒ&ˆ)­ Z—áEZd“†dxZi¹ˆVy RÁã°ºkóªœ|½?z;¦MB¨2‚¦“˜Ä2qÐÞŸjƒ¿|s²õŒƒ:;+*&‘b*¤”züµŸÑÒ‹ WSÀgÿãÔ1D^oÄ$‘R;íïö»ªÿ3¡{¨gV=;ì ÿóK¢^âÙ ”[9›$<¬/²åÞ›ðÞÔÙ âàûøspa\TÏzJ€°^¾ÄÎfüã|_2Á9l tJÕƒx „Ïøy¿3RŽF¤ò°ñúùü%vUÿéËù^a"A½Ò=áÙìãK óL_zòš¹ï~ÛlÞæ÷޲~b£÷ Q h7¡AŒ¸«÷ž©Xüt‘C¦ê-µ£VÕ„CQéòøâuÄCpI?-ŠÚ渽Ó'¡Zl轞&D>”Ö^×°ÅæÐ”spf@£|ªÃD6쯷 Ò*§ù&k WTãaCaÏÎ¥!œéa²?Öe Û•ÝzŽý3¹Ï¾û&ò]^ŽªšÆvÉcÕMº««»‘4'®¾9‘T½.%³9‡ºð°v[8@Zwݤö`+bÇa1¸¼ áéWf1# lŠªâmPÏ&1g¡ §ÚµDÚk,,.W¹½¹¦¢ÎÝÿ(‡Ë›±Êf¬öÙ‰©SÔg'Ê6ÒÇr¿®kÔ"eHl¶úñK:e_}ùJË›îozëy6K ô±z:IW-ÌRÔl³·ê/];·ýO%d á\A’$þŸ¦s TþÔDìX endstream endobj 520 0 obj << /Length 2172 /Filter /FlateDecode >> stream xÚ½Y[Û¶~ß_¡GˆX^E©@N/)Z AObà<¤yÐÊ´-D–¶’œdÑ?fÈ‘lyµ›lvÓKâe†3óñ›!Í£]Ä£_¯øÅóÇõÕw/•Ž„`¹12Zo#!9S",Lè,Zo¢·ñ_\ØÕ»õïÓD˜%g³ËôøÑI‰c¿{)ÌlHÊ$OÇ1qÃÛ.Œ»•±l–$MY}ïú%‘©`–z)–fL=j®½¿¬¯þ¾ÐÈ#IÙTÞb¥mT®Þ¾ãÑú~Ày}ô#‘bi޳êèÍÕÉ{3]Ò(–K9÷^¼î‡µ™aš<ýd½Y΄s½eáµF‰0)ËS /šiÞï ¡  )Í`OZ,ƒe™ô²,—ºBd <{µ™fÜŠ¹ZòÄH"4&¬}¿JT.ãf%m|<¬d_¯xw<4Û-:¤¢ÜGI+à•=5aþµß7#?á÷MÑ7 ÿ$ÖÊø§¢ ×ç£h2¸^ršé¥%„(¿°`„ Ë;¥'• \¥¡Uâ'xÜ?ý'‡6|îÜ^üê±çP|ª” }O]½÷bëjðI(%yÉÀ 2à„õþõ[¿l>wû°¯úÐSnÉ7¡%ôðIé«2`TtZ/Hø¢%oAŒuqLÛ½­×˜n—V¹ÁÄ]Ø;_™1Žý3 ä E#-Ëó§Œ"µLAGY6'j<¸M0\¢ ÒÈò¹7ÖPªÍ¦¦wÏTˆ†¢D7îÃ×X!³‰³R1rLò5~x½ÕMÕ—C2£ÚT8ú’E4uÕõDŽiDx(Þû`äDâà ^‚ýTWë‹]1““ÆÍXrÀÏmhý×À±œ7EšC$óH[ø|ZÞV1¢4*~8ó'/b€ÿ §,¸¸¡g »¹ )i¢&h÷äƒÏ=5P´ýW:…ÚžgÄX§P†0¦"U#-öÕu}!‰c'‡€ÀÓ2Ÿ“¦ °âsŠïé¦ÁYå1n=Æák1 õ›àR*’Rõi8vg2gyÞûk:ÐS{·´æ²í:דµÍ¦jvè¸Ìý}tM njа©:WõíØÝÂ[X(†Àžj{E³f~ÖBC1^×÷EÎÆ3û¼~Á/%#)2Íã=n¶ÐÓј)RϰG´„7rB~ðµm}›¬0vè–}>nºÃô¡Úx×@K}µk*Ì­eáO}Ã8ƒrðRQ>“h*|z7 ¹Ñ¿qÔö–ö3î²n…—׿^Áe6ÛëÐò.ÌÙ†Rh²‰ryp˜§Ÿ†d'^+®ÃéÆ[í‰ld¨yý8â §ŒTV×pnêŠS9–˜Õpb¹o^$&e»¹iI¡x!ÑÆW( §–øæ"äÿÛ{:·P‡5E}Û‡ýà?éYW°—vÍÁ…‡Ö°CÝä¨iZv‘ë‘f2ï…ÐAε*noÈkØÚ.Ŭl›ІàáŸÆãŠ|À3§®P‡€ìè`†Ó$ŠsªŽúæ‹…†©¤AÓ68ÓõûÁ´oãþ½+ºr¿xÈ™„–Çœí‡Å£[’Kf•™‡tM¤|0´äúºÝÝb .Ò~Ó7î1œÈ ‡2à‹ þÖºÔwªûa²« |‹‘°8Hõ£ ¯^ý¶x˜Uà6yî^ªN^ЙüÏÕEÒÞýR“Ìõ=G` ‡s¨$Hð›?_/j‡W; îÄÇ(¹¯=û¢Û_®å:ÿRü¹ayj>g.*œù,€B)×äpü(Ë#æïÏ™'ÀÙ »?þòf}Ï]Ù¹½žn\•RÌH3÷ïȰhÄœ•Ñáh>WúÍKÉã3nͪ¹9•¦wnC,K­xÔîâí–.¸2–‚Z)sü´û-+Ô\^”ÎË·j9’¤z¥Š UÕL鶪]ÔC /Ó æYv„0JtЇrŸë'œîÀ©ˆ~þ +Þ™ÀìgQ›s&Ñ­çjGgÜÙrš¥<;»1çPtžQCöÎâýfØÚ5Pabm~*jHêÜW×ÓÈpeà/‘íÙõ Ž …~¿r+œ}OG@xq‰j³ožMÛP"añŒŠþ¡iL]SY8U.`â6å±wc/Õ†}¸4we¨é"½8ÝɤCÕ/VÂΖ¯˜nžÙüÏÃKfìj¯¸ÿa¨»û®Yåù?8Ù©ôeš–p¬÷'±%îÌfSZ]ü»(eœçTgÌÜ]ÑŒ—¨`·óç·ÏhNT“™õi fù¼/³?ž<2¥VÀ+‰ýt9|~æBÜ»¶ŠŒ‰¯»/\›?`ttmBq›9<"•1že°Ò2-áábãü©·dà endstream endobj 525 0 obj << /Length 2154 /Filter /FlateDecode >> stream xÚÅYKsÛȾëWà2 a 0˜¤*‡l%Nyk]å¬uÛlU qD¢„ M«òçÓ/„ ­‹q.â¼ÐÝ3ýõ×=£$ÚDIô÷«äÑï×WoÞ*)yžF×w‘Òyœ¥:²‰Š•vÑõ:úeñïå¯×?¿zó6K'Ÿ¤qnLÑÚ]Ù—ÍðçPã7 =?_šƒps\ú§åJgù"ôÞ/WYj¡Û-W©[tu·YªÅŽÚEÙ®yú¦/ÛÛ%Œl¹_ûv¶wÊÞóònª¦ü:~dõt£+cãB›h¥lìtöÍ­û—mÔÙ©ýyzf?tx—y¶ö7°wU‹*ìCÕµ<×—ÁórÒîƒïÇÏaû`G´Í+¥c­sÖÿÒ#‘ ¾úHæNDqªÌ#×_Ø£*¶…óÓo6¿±ùàª!œ6‹ƒÀèÑAàBò¹œç µ/ÞPÛ±Gt±áÕðŒÝ™žØí Ø]D«4p iøg¢ìo›®b—ö¬V=®ÿÛõÕ§+I¤"e il“"ºm®~ù5‰Ö0ùc”ÄYá¢-m¢,6~VG¯þÁT÷H¡ÍbÍ¢rEz‡Pöaî¸VZÅ™VÓ¸ºÞâÉhíèdØ|ѰõܨÚ*Te-£ÄwÔêø÷Ú5ñråµxä›Qt[?pëó2Ïe]­eÁÿ~üð3…~"ÆÙŠ/{Ž-? (Czѯ7À¶v!ƒ;îôw]ß<ëavÖ«ÜÎx7ÇC΢\'qÀ•w°ea‘Ö'@å@¶»ŒV§ãĪ©Vø Wa{ „F¨¾KÓ©×Ú}3?8håòñð(UÊøÂF»„¬ _ž|ÚóDwÇ¿Gb‡á&"Œ$M1*`è„ èì)Ú˜¸nÔÎÀÄS 0IÙïOŒž„ ‚•àö$<­ÀÓœÃÓ~wxöOÃS;àN`ÙKÀe%vdï×#Lšãºã>ƒ‘,NŠt‚'„ žA‚>•ÉŽÁO>±' À`‹¾Bˆ9ò‹cˆÁ¢o=¤½®˜˜4Y¼ßAlgƒ&þŸø´”¬Y‘ðà7¾ÿß;v×Wm˜q®Íá éÌÆ¹É^™YŠØ@ÂFY™Y  þkµi¢ã¹‹¨MÀÒDmÝΖc+kâ<›âêC/Ž@ ƒÔ%‹ººÇa_WÛŽÜÇ×< Éë}9–r8LÛ¥qJ#à(]‹Èß}Yf`»ph…ÐožD®ÒéILw—eE\$]”BÉ-f·EóšzF·Mcm³ËèF ¹Gºëû8| H¤!o—سO%IøœÎGþðŽÛ]/¡¤3ñ# 9Àß?säB)Јg|=ü‘ïJœë ñH•‚ÝÞ‡}ßÒœ•ˆ×#Ëv”~Úƒ+w=~zSÞTuèy-å˜'¿;ðûy"áÞûº Õç¥Ä¼ÉÇ Z·u9 ~Ôxè!ì!„àÈr¸ø|ÜŸOT-fR6ƒ¢ˆI@PØ‚©^:'®%Bz†ªŸ™r©Z{u÷À¬tWa%©‰¯ v1Ôîõ°ò´§®þ\µ)ýýì‘RŸÎ+­­TW7m#*þï$—å~ÍEHeÙܲæÐ—·~¾~¶Pl?M8z9{®u·ñTÞP ,óeWw½—x½ïÉ“jûT`ŸŠ ‘Ùs€Üúa`q•íBN3ž¡*•9¸}è(K]œ˜üUt¡tJ1@MìŒy–ª”Õ±…Šà"º­‹ÓÂNu“ …­Tš¹å˜$9Þrò¢àÃA©x¢ìn_ó%l4”; ûè(b5mèi‚ pѦ÷L Ç‘K(Û²~*™&Øø¼¤Šä{uÙodýº %‹ ¼Ž‡aµæÆ¶ÄÓ>‘”ã—ì10þ¥ZÍ‘F#×}ƒôQNCÿ°%V;‘€%µ%˜PKMû5ÄqøPÕµ¼‡H¾½—®$âïPýîç®gHAÛ(…Ú!Ë_GJ¸s¡(• ̵Ψ.Øg.¡:Mྟډê!:gë$o½§ýe'·DPšIþL37 ¢Á¹}¤p/Ô`Oj(¯‰^¬ ­I–M¦;!h”Xwf/bgŽ©›z¶Â÷?q·Û‡Ý>ðLX¿$9°RøBõ¨,9¾…`è—R0ha 1ìŒL‘k¶^ÖîZ&ôKHºÑîkÊôrÆ x³/àPzÿSÌýwa.^¹N(2HÇ^}ŠôD_Ø‘"ÐÍ~ÿJ|Šþ÷ÄžPíj/‚8ž…’`€ÂleÅP6X“pGè‡}àÆ¡BNÚΙË÷j¨Äöü"LœüX6ã%:8‚á¿ „ì_kº¹û0ætÀd‘ÇV¿òÊ Vά\ k5¾é€ÓŸdƒK(é`¢øvëoqÓ€oF(»ïJTÞ©Ið᧸ðpTxp|Â`‰?阭HÁ[àY‘sD6Opr ™%ÀU$µ l-íá~K’A5b¼ça«ç?Çï œ»`ͰõoÆ/K¾³Ã>8‡æ"B“*žù%Jjîýÿb;Ê1þ‹¿å'ó31|´FÕÖœ%|^ûaGKœ’5víý€.†ÃµpIå7ítQ1aÉÌ{[•5¿p«cRÀ”8Ë$&Ö©šzâ˜)ÏbDÞ“ø}» c~Ãîñv<¥Kp_•€‚,bç䯮ÜdüŒ+S endstream endobj 532 0 obj << /Length 2114 /Filter /FlateDecode >> stream xÚ½XYÜ6~Ÿ_¡·Õn†¤Dyq bÀk± ØÂnqºëèèˆ=ûë·ª»5–;Çx÷¡[<ªŠÅâÇ:(£}$£ïoä£ï󻛯¾KÒH)Q££»ûHi)UF¹TB¥EtWEoãwRå·?ßýxb.½àR¢H`†¨7›¶#êoïn~»Q0,#)“‹´4$8Ióh×ܼýYFLþÁše} Ò&JDV"[½¾ùgPr¹\ÊÙRÉ]WÛÚÛ—þê;e.6º2É£JEšfÌðüáv“*WîþVÅvªÇg0$ñËíÎã‡?ñü±‡iwì»Û.â7à ÚR¸«ïÛÆµ842ëö8Â2Çi}»gÚ±Û»ñàzTvºÐë4²ëN˘v\0¦p8ާ`¿SÓÜv ½cB_¡*E<ú­Åí&Wyüfp³8»ãè»6Héxvxïkš1W¢Ó> „ì‚&ÞN#ÏlÉJŽ;mñÿH-bM‘ÙŽÛ¶µõÃ0Koüþ¬H„Ø 3Û÷8D5]ØGßÌâ»5Åw]s¬ÝèÄc/°¿ao4pÊ¿ ý]×co}ëªOï€VZ™Ž2U eÌ“î€V™0&YŒ…}Ö®]Ç[2K£ü‹ÍZ õùëÛ##4ÇÞ9n}ðã[­Š{ÛΘÇIXp?†À>0^ÀÀï€À ¯””3r€hÆ‹®ëõ Ò¶•2Þ±±å¥ Zú ª—Ök)¸pÖ~ô èëé².ÕžATû^é<æÿ°Þ>/œx†ÝìÌÕ»ÚnV/…ÿý„ÉlÖ’ ý³ Ó»í<& X¾¡t»ÿoÈW€)3‘+£`ò‰À” C“,­xõ{_ûPëÓõ³Th“™õ³\”i¹X¿µ ­ †LŒ(–¸®Ò¯L’‰2K¾H¼BYy–.uz|Wu!4øˆpnµFDœ¡(ánvGÆmÝíѹóôé| Rgj+ºÐüpÀëpÂæB _v:‰f¬oÀ º,—ëö!N8ÛŸ" †Š)U©¦Ýè* ;WîB´QѸÝTW̱¥UCpšWíIà¯S»=lØWn!y)²æc4ˆ ,>ß‚é* %œkG. !sý4ÊTHpËFæ¢Y×<™Ìg%f!&~MgVyí`×;²_wԵߥ_}½%º\˜…? aØ+æؘÃef…ÁÆ’HÿQPk$iú4çóÛäݸ¶õGÇøjÂŒF§æ2 ÓiJHÀaDÍ&øm‡“ ÌñÄŸ}oîPŒ!mv©¿çï8ó6Ìô°†°ÞÁÚ=!Sæœ*Á¢ýÔ†ÊË`äœÊà°û¸s®xJ›ìÅs·mÅc¬‘~8ÔM#ÅáYìŠ2´EÈD9”Âáv÷|´|§1ðtûÍ•HÃ10Û,æÄޱ©²} eþ÷ÙÄN‡N¬þP¹¹?[ï¦ÚŽné-ö¶ßûvö’`¸­ÝúÚ~¦$ÓáQapé¹m{ ®,8Q0ËäÚqí`Î%ÚÍs1àz^FÚ´lw‚Ž/ù?ºÏœë0t`&î-j¬–G Q’f§ÒGƒSÛ$àd²3‘@¯ sþ7Ù/ÇÜï6Q¨ê½Ý¹«­ 0& Pk¡²üïôǦþ~+a·€ð©q’H¡Ê'–‰%´á`0AY×¢½VçôYVC ]ÂfËž3Ø`] fÝ+e£ŒÈzš)Œ8%Y4t%ñ)@vñeV…²Cæj¹ê•¼G©l†úO]&Á1—)³Ñ^ ™ëGlŒqK‡: BÖ@¹äDTxÓ!H¹Œ|.,T|Öç'%û|ø²ÏOŠàóadöù˜ïäIü‚"-NTV¯‡@ÅYNG¾åqZ„‚È•OILâ.ñ;oÛ~Xs9ûP€´'ŸséÊs𘬒§ÅL²ˆB^"“ú|?YPC3§jç›Ï,Xæg’—o‚Ä_vTšÿà;¶‚Ì–Π‘*ØÅ¨5Ý4ã?왲ø2œlxéIOtвÏGnœžáP ¹jI Þ¡,[òQZ†:Yò”zÝDBÉòº…¨¯žêy"àãy§v6—ê¾%Œ(œàN‡‹­Zþ’ŸÀfÆO¦]_ Ï›†k8¤±ü!—_ËÇ.ÁDbáâr •ð=+Kç0ˆ®åâ¤V·šiúP)TžÞõÂkÅ­5;—¬¼}8S¥fTÄö³`¼è”öžÞˆ±>j7ÇstÁì÷( nfYœDy)à–B 2BáÅE• Èzþ rÏAÝ endstream endobj 541 0 obj << /Length 1964 /Filter /FlateDecode >> stream xÚ­]Û6ò=¿Â¸‡@bE¢¨¯öi{—ôR¤Û Ùà®HúÀµ¹¶°åˆR÷ößß|Ѳ·Úú¤™áp8œo*YíWÉêû‰|¿»yñúmš¯Ò4®ó\­nîV©Jb­³U™¤qª«ÕÍnõ9úpX«2züñýz£•Š|? [ëÉ¢—&?òÒíz¨å¥mß›Öî{hƃì?2×¶ù’¤zËËýqlzç™cì™8Nƒ“e'+»þõæ‡Õ&-ã<¯á«Aß‚õ<šÁ´­mµJE"Ã_’<ñÖ2òÑniä€)’UºÐüüý‹ÕgbÊc- l+BÒx½©ê:úÉmE\*¾mœÉ©ní|: {ý6SçÆÎÀÈIZƒ|VÿðصÌwé”,‰Ë"p¡,ö`¼œËö´ŽM“ei\–Ol³·Îf´»WëM–Ñ09׸=":2üA9UÔ“´~ôã`޲îLûèÏzR¤xC‘Áô4Iì±m¶p˜l@/àWá'þùá“Eª&—:n 2ªB±ŒìzgYx$øÈW@ü@Let×·m¿†í²Vb vÆíÀQ›¶qö› džïSç€n tK$º#ÄqÚ¿üvIuˆt°(rèhãŽÌªø¿FÏÂé-㛆¿Þ~½k0FhÓ-Áˆß.Å@P§æón躙¢8@6˜‚ié龄´fr[4ÖÜ‘)1,ÒLÙÛ‘“€øp .½Ýö,OyÕ¥¼s“ä¬bH]ªèºIZ üfdhÖ}•UáÌúL§:rÖî¼lî™o@$D`¹wíc€¶V޾y¢ ø¬ŸÆãš¨,—tõˆ‘,S}Ó5­˜Š'#‘4D• §äâ…ÉÓuhS`ö#xÄ ˜~*בëݼ*Öb:œgšKX–f^ÂpGùLÓàQñFª‚7@èYI¾à8ôûÁtÌÒ8&Þš‘ýÆhד7vögxÛø¯eYý÷§^þQ2In?4m‹ASâeoÍ-‡P]ÿtÃä¼k?Ü£ñŠ"zÇÔ]Ï_× Ü»x÷aFJ Û2¢Û!`˜IRN¦º Õ3¥ÎÙÖKu‡wí¨ÓäP1)FгN“èã´ß[új¥ù¶…ú`ãX˜®Z߃Ûre~d6ò=Šë€Ñ¡ÈQ8N+ŽÚ~‡k’‰ïíï–Ôäõ´³äÙe«Èiœ¨xœ@ì4N bÎ9Ú±9¶²GÒ—C6W³re0œs*ê@áü¯S3`â"Ö¸%奵§è”ž¡ˆe6–+W0“¨4×aY×YÆ"J¨Î©Ê£w*]$D&}¸ í®NýŠ)XÐQ9UÇÆÀÎiÐþýËûw@±2Ç;@~v¸3[»ü›“„"VUþ»/K˜ÅÀí¨æ&ØFÃÐÝÐw …z†÷¿‘éRH±$% ý4 Ùx°œ‹<¼/†Â쑨Šc³Ý,ùb¢rŒÎ:ÙN\zXç!âϼ¢ãL!ï3E*^‰SñËGK3š´ê ¸dÁxaìT*N‹’Å\µÍÞQ¢@žcG¨*Š4UÕÑ¿®¯À‹âäùh1µ‘èåXÙ4ÏÒ¸x ~DxGuòô,²Ž®ßü÷ÓÇç§âÏRˆS¸>u ¨KDª~Ú"~ Z£ 5¦e¹ ¾ ÓíÐZšþ~£šƒ-Èt”#£Ø´Þ6ûi°þzEW\ªBd úç÷©gz\®ëèíºR'­O)0(¹\]háåÉ32\xXZ¸´ö’G0ò œ°QÌ#t7xKËDaº"Ѧqž)²©X¬eK³ŒÔÀùm**‚yèè@Y¬ÝÈ„p»Ñd ^¦TÎ9qñn°Rf9MdÙ[œeÆPIO£:ðݶÆÝ/Mˆ—ç ×ò žV(¾¨"F§ªD±=Ÿ‹™$O‹Jž”¸6{·µd5­Ê|ò킹’è$‰Zëöãµ*@«ÿðTŒ á,„ÃYÊ[ Ã"¦?ÒÇCã… bÖôL$”^¶È`x”žm½ Óùó»„Öâð¡„0ÔéCÓ‘¿t|iÏäv˜ŽvvžÙ›ImBsÄë’+ª§Çn}‡þóË*¥}-±€< Õžm_G_ÒLc)Àä|õÍ?p–HyÊÆUžŸÊÒL^n4¦ˆhôÅ^QŸéˆì ÑQœ&Ù±5“·³R J_Û‡†,q; F h„‚7îÌ=iáó Ë¡*pH‘]”ç¥l =µÎðZ¾Â›Â»¯æ¯¢‘ñá‹ÅIî­UˆdÍa¯ÕöÓ›Aga¶ ¸|¢BðY×Atî:ˆÍï*✓ZK÷_Èc¸y#]Ù‰CèöÒÑ&5`Z†P^õ¥”¢](uðÕRG»ÂÁxND„¥¶òcõë„AÏöÊæ_1È×™ ,@m虼kü±=_êúAv€ C†?ø¸ âh2z¶ózšÄuUDoÌ鹤e Õ:D ’dÄ6y^>›…µ>›…µ¼ÃôYWÚ¡èã§|êEü´Å'FóE÷e÷L«*Ö)\"SqUÈl©’ ¦77/þÁAß endstream endobj 548 0 obj << /Length 2562 /Filter /FlateDecode >> stream xÚ­XëÛ6ÿ¾…q_"˧Ÿ/qÓ6½´u’ÑÚ²­«,¹z$Ùÿþf8”üÒzÏ»6°KrHç73œŠÖ#>šÝñ“ö¯;-‰‘à’E‘…B²˜«Ñb{÷á>ZÂä÷#ÎT¾Ø¥Û‘P‹ãúùè×»Ÿïþ9¿ûöŠ€ìŒÅh¾ImX pL·ùrôÁ{ÿÝ~|û~ìi¼¬hÒ*O“ÏérüÇüû»×óY”ÑLËè9²RŒGjò˜…Â\bÂGpNŸ±Ð±`åx>‹½0¯Åe CsAŠg³è¤bͤ–—YD,ˆãÇM+xÀd(€¶šLkȪ?7f'þÕgˆ&̈ ú´øQÈ ¨ÊŠ_§‰±/¸áÞt:™OçÓÉt6›ãt&ðo2þ0›Îá7›M'³Ùd2™ã h&sœÚüøk%Œ·ÁFLGºÇ.‡°Of¾ïŸcŸbŸ"vøÁ² د|z—<ˆoƒ=ˆa£ê±+‡ýÂ>Φ‡Ø§„}Øÿqòë°_´ûµ’€7!‹ÂèFàa#—=x} ¾3kÔ16<¬þ?À_+ùx±0 oÞ€X“:ðæ|ã'×?¾ó€‹à¯•|¼d\¨—䌰è¥PŠ)¡o“3”aJdÐúYH½ ÏkÅ@"5%æ6HdÀ ™=‰äZ1Ãb܉¡¬ˆ’Ùy¸»€äZ1ð.å@™&uÜÛd~…M®ã‰‰#fDx#$œó WK1D°P¿(ì¼€E/EñÓè—”í/`ѽ†…1ïªÂ%€•?Î ÉÅågLÌ¢@]~RAÑ"7YcàI)­M‹&Kò¡•`&x–(¦ ÕÓIå Ó<ŸE/”VRE/rÓç³è¥€Ǩø&·Þ˜ž$òèE¥/¼¨®>{@|t*}›ÊÚåžzôEõ“û=ò¢º€óZ!p‚S+s›"Úhn‘|ôõÔáÄX=ðzº€óZ!‡pr&ƒÛÔËFIðñÔKi>›œ¾”~Çß%œW 9€S &ÂÛ¼†T,xêI4Ÿù““'ÑS(¯q¥€ê=2·A)43<~Æëç+þ.à¼VÈœž/ú6ö|{$SR¾(©=ŸE_*@+.³8­7ºO¹Ööð¬‚ÅÆHk{ [¥éÀ@ãlÿ&[·U:ö• <ÁЮ°-<ÜæÞÉü¸ÄP!~µ+áÑ—[ì}+é¥KšL סBÄ®ÄbÄÒVeµMšÚžwöúTn Ðõ•†jÅÕÁIž­‹-ð•¡×ÔÀ5޽-Úºûšsï~ìÃ0¥Aî’*iP8šƒ©Ú•DK·»Æ‘q˜gEÊÆ~`Œ÷¾*-¯EZ×Y±¦y:,o²]îÎX&M‚€„×Kë>Œ €:^ªÈªÔޏהDmÊõÚòÀþf,<×ÿDÖPò؈! Z:s¼s;RXÀtÜŠWĬÜ5°. fEw^êN9²yšŽâŽÅÛb×¢R#åýËa<;RÁ†^ªº½÷mZÂZVt^[ÛóÀ–\€§)gT”ÆWê蘱âugøÅ}ר¸äo·ä‘0FÓÒ9¨T RÝ4¨Ÿœ*­hè„’á»GÖ·"¯[Q®huK!“# Œ”¤Hò‡:e½è»É|cýHœy–ð–ÀòÆð¦N'<ö‰ëx½Õö’zÖנݸ2QªÔ¯“-åV.ûƒšMÒ ùó”/µAƒKo)Ü,tÛ%QZº$ØM¨)ÊÂÇû·M›*[m/ɲíxÕíµ»q›kjUY×þç±ÑxëA>2Ì€W È÷ßdþùg‘­PŠ{!·!*Õ)ˆÎ.›º©’Môê„õYM´$¯ÒdùàˆÅ"o—VOÊÝ hßòï~„c †Zò|CÓ…AèMòfS¶ë Í¢ÀöÎIeqc\´*Õ‘vÖ®‰Š"ÁÙŸ3ò˜¾Gÿ~ ~C.ë(5©R"ÖínG^Z5Û)AÁ|¯‘ohœÐ’Uúe0 ¯t‘¡3àÔÖ&MkóŽìÉØI¿îò2ƒCÑ—![ÿ{EôEÙVuŠž¦5eªÌmíØUhìl ¢æŽ%ÅÎEž– (cH@~¥¶¡IÑL8 âa‘âHœW¯´3¶Ì@fÜ—u 4ˆ½$î<”ÝÆWDËCïm㻬‡ ìŒ%Á=¢”¶×AÊf9ÛY@5Rni2Éw¨²Ä厯¬ À»<‰…½Ÿ–ÍÆm¯ÐJR-i¤}7î(RP%wäëŠG&¾„‹sb’šˆÎ ÐÙfEé'‹léö›t.Ôd¤ÀüaIϪ-ò^µYÄ­Æ”hÙP£dtjìT¤¬ªäu$rJÈ3Ù>´9³cëêWª#±v®Ö®ˆþev7ú`×È£2Îdtc^S¢Ø'§\ìî ImÒN†EYõj(m¹ m†€UbˆÖ&ò–Ù:k¨k‹ h·e…¥edÓ„«÷Lì;®[Qk%ªÝž}mk¢ƒ,ƒ„š<«Oö/ ¥‹¶3×<õ`ˆh’Ê% È$«ÊZ%VÇ2XEÞ´6bÀé¬@ç\`4ТK)@')°÷QÀÅ·ÓÂn™rcý7Ç¥¦#(+!¡’½±ÉÞQý‚ ɾ7¥4AgJìÚð-Ý)œ{°ªte@ND’{{=ã¨×³Ý¹CàtÄ»H¿ºÖüÄ>öÇg—,ÒAߥ¤Q̧wi_²fC ÓFŒjíÒg‡´¸le*éÚüê< iŸ3pà¥Iå.G/SÌ…­çìº}ú¦Ún ÔØ§“­ Kß–$Ö땎÷eó‘p0E†@œÛÑA„çØ®m­­ˆ‰nj¤[oK™ÆFôÔ-8T¥«Ñàií½+ëÁ7Ûö‰7¡ÌA‘ÎY†ò6ö\þ¤A ên•£—6ãío°À*²æ@ŸT@Ýó€¬Õ—ûÖt½õ·É2íÍ:” 6¡}›Ü×.gì½Ç]Ø ’:oÀ>Á¥«èà5xüð‚Ò'Ðý'¸A÷e^ÿýÓ'иÚ¯^ ½ÅbÃôþMØ•×xå ”¤u×ö(@ûBjòؾøMà> stream xÚ­›moGÇßçSœè›ð‚éÎÎÌ>EÈ$!Ó&W „xH ‘¨T>~ç|~ˆr۳Ƿ‰å%Ž=ûÿeÖ»3ήùÔ¸æìÀÝÿ9@]ƒ :)quÌ:~¸9xûÎ5—úËÊ©ùwñÔ›)C ¤ÿþÜ\üyð´=øõ% ÙelÚç»h¬ÑÚËæíáüêçÃ/?>|¾úz{}yõýá»öÅÁi{G ‚„½¤Üå!p‰š3ÄÆ‚¸¦›'BpFð>M ±Q¡£Çñb”{‡X«HŒ4"Cpéÿ3‹.€¨±˜¥ÏìÛ>«íß×Ëü®Æ÷ýðáëÍÍÕ—Ûþ‡wÃŒ¯­ Œ‘!"‡H 9Ý1êß“CÏøËüôõ_#Ú­´‡¥ŽöÀqìµ?=={>ïÿú'³vöx„Â*¡@!C É@œzŠ“ç/OçÏ_Í/z”y;{}„nùÃño³ó#ïÆØ¬Â lº¯Œ•ØÎ=Û³Wç/gí&Eí›?NN棩²j)àèö™1ÕÁa„¼ÜåüùëéÖyKÒ5æ:Ò‰À öÚoßÿć(D9|2kÏfmÛ·íìLoÇggcPFE(ïA|&Ï kÅä—Ldz3 “QP Ò¶ckW&HBk&ZçÉÄdUT€rX ÊE@á5¯ î~m‡²*BIÀ¾ÎꓬõŸÈJöZ}fE¨!zª•´”°† ûAY bÖR+A!8‰k¨¸Y~(«¢”>ß×)~$z Ik¨TzO-¿Æ ŒŠ P!ø:µ­‡ÖPùN¦úTém{¦¬Š P¢ÍޝS‰0äÍ[ª«æÅÝÏÔj¤2K*P1/BU¡b—T§ó“1áÖY Â)ê^ËSzË !6*8È”>{Bˆ•{Ñ…ðã!(%.[Ë ^+Y=vôÀL8j1{æ 9X —ן®oKî‡æÂkÓ¹‡ŠBV0éaÓ²²ˆ E៦4åB¬\Ž.fžf•k-Ë•œ¢ ‘¼Ù)±‹(äDc…mûò–œìb£¢k â¤õ¹ˆµ ¯¡B®b”×…ê|]£Ä,°ÀˆzFÔé‰Y§ò»ù$Öy ÊuL±N¡FNô1²Ú$f C Ÿußu*3¯5•w\Ç&1 +°¥ëh¾Û‚ìa“,‘ÝÒ(qK§ÄZ%féúuw©SÉù˜!¹°›Ubž¸ =dpQ*iG@‡VÉçœn‰‹ûîõ»>ÖßëéêF*S³Ê¨>?Ö)áºã[;¾¢Ì$P£Ê¨ „Xg£×¢ËCOåÉdP«Ê(kiëbžŽû,÷šŽ9­" œÝÿðÅ:&™'­åæK…•kUYõ¢]lN¯•)úSÓ(²€‰A;‰:åŒÇ©dÑô‹tN«Ê¨K‹¤¨¼“mc³rÌ*‡ ˜3pªTÚ9A)Y9}Fïæ´¿ß1£f•%P1Õ©ó0kCÛ/„¹¿ñ®I¡uP“×±NQ‡I›qŒ»X>æi Ê£è?¥£Þ?ÂFƒÚvq渹0!ÄÊ«éBàøÕ”÷ ŸÕÇ„ÙÔ·awÆâ¢âºówŸìÑè¤'Àꪴgן~|»Ò•ëá‡.¯ú²x÷eÒ]#í5hoò,šåG¤ïè_¿Ý¼¿ý¾xÑàcJ«ñ¾쮀oiU+ßhié®^¡Ëê?f+{ endstream endobj 560 0 obj << /Length 2458 /Filter /FlateDecode >> stream xÚÍYÛ’Û¸}Ÿ¯PåÅT*âA‚©”íÝÛk;Ž=›ì–½UË‘8ky‘y±=ŸÓhŽ©OE©äE¸7îÓT°Ø.‚ÅùYpOùñL  b!„òc¡±~¨Åº<{ÿ[°Ø`ðÅ"ðUbŸíÔr¡¢È7F¢^,ÞýãìÉÅÙw?b©~¢µ\\\¡šøQ"q }òb³xï=Ý¥Mºî²f¹’"I¼×ýºÈê.ßdËß.^œýpqC©c_˜d%Æ—ÚÜ¥¦‡~Fǵ‘‘òU¤jcŒÑwj3€CÚ:y08RÍ™ØCÃê<¦]o+ÜE YXÃÀâøD°†˜(xÿï UèyŸðÿ…ªæ¡Ÿçvˆ¤™ÕŸÆs¥`/üunG­ýh²ßWÆï‡fœ1⎠’¦Ä‰.H&p'î¸Ïø†â“ÝÐÓÿºÝ¿Z®â 0G4àéãäÁÁ‹„Ñ'Â]h_‹„7ý'áÇG_FàËoÝÜ»~ðû"Øao‰šâþ¸Kœ ÷óã¸ë$òc•<wÎâÀˆc5¼³ 8• ÄCÔ=+†âÓƒÿå˜}óþ­«ùÛrnz}õGU“cÿ\ÍÉ%Åòxzyÿ¢G“¨c—g öÃßç‘Ë3Ò—‰úψ.‘Ï@+‹üOap’ó¾·ðš?#\xü¿ðd§ Ys!$¾B¾²¥~¬§ñ¡Dxä”§}Í1Þ‡ðׯó’Ý-ã[’9¤MÆ„ ­\ Vu±4ÒK/ è‘ñ¤ï‰o® µy™·ÝrêêÕW\~ZFRän®—JxCZÖr_^qùýëÇ\i³}V­37žVnq·Ëœ”ºi²»d§ÀäÛ=T^]ŽlQE8©hã1ÿkíYÆù6yzø=Ç6i—’ù´;ü|‘o«2«ÈÓtÐQá•)’J[£ƒS¹îÛ®.W›ìC Â*ÛpoÛ¥]f×Hïs^Ü{‰"öœ€}SÛ&Îßò2éõ­= tð`zäý¤ËÖŒ™40ã”õ$_I% ßd…=ðþn¬Þwy]9 |Í Szm›´d±äq2ëÿMxO»G_Ò¯;K3•ÒàØsj¯‹§lIŒQ^×d´YŒ«®÷VN]ÔÛkîj³´Y/¥ñvÜN‹mÝäÝ®´ï›»·ü ‚ ·n]WtÛ¾![¦S‹Ø{]wv*á™vnû´›S‘,ëáÒ1_Pw [Ó/yéP°ó`ÀB‚r“C-•5$Ó@–ííõÜ•m滚K)Ý„ÊIl6ƒpL¹ygÀmJj|Z:#‹`YY7×\o÷éšqÑÞóŽûìÞ(wOíÊO¤§Ý(Šô•Ô`ÙË)õ}*¬Ý8û_xÛ¦î«M;ô¦×>n S65ÙãŽ[ÃFnÞtEÝ[g„æ!úb EÃŒûó«Y_Š(¿fyE(Ýî!´8"4ÙŸ¸IQò…Ïõ—ÞYÑf@Ì+ !@ùÍ3úêê½|þ†ÚÄ#èõÑü ¹E ÓCäwRŠÏ-¸˜çEÎ\ Èwì[‡Å/è‹E%NÚf\ms:¨Z‡ ZÐöe™¹5½)Ž“a™ áÊÞj{ˆ$uˆe¨¹ŸY¾ G66wKXbøò2¯jW]ç›vˆöá`ôÞÜeÚ9]ÏÖI­ÃÕ¢Q_¶YÃÇ&wƒ$†Õ}ÚÀ¾û"uÛçÊ-5òç4e.¡p½·¢%㥌pª*Cl¤èË wÚr›˜r´Îv¤7Ùåtµ@l÷…õs×nye"†¶ìB¨Ïm:¼ÂàøóK¯Ÿ_:•€äåÞb‰Nì½NÁ46<ä ]§½….±(^ó˜µ]ôTuç6I›Æ1u2÷ü¶¨g5ÝfU†Ë ²• *]ÑãnJû¸¬Šw¥û©îÿ£3êåÛ°ƒ†¾¿ÜÒq¼ ÄШ hòHüï kûêåœ_H‹¶fA;„†‚ ßJeߊèå9@_û<êk{îuëÚ¹ÔRŠiÉøqëí±„>ãëÕ‘A8 ïû0êû? ÆÜÑK?úF.ìû7à2#¿™CH +=ò¹ 8—#gEH}‰oøßÊ‚þÝsfúÿíî/ب†‰™œÙZN“ó?í`T"8dÙ­KI‰ 6[G ßžŸ-Þ#ION2V×é;¾JÍ­ÚæK¢–‹¯a£í¸fS-²o¸9µÚï,oàð Y´Ž¿.ÝÎÇ™+‰±—£ävJs8œbÂíÀ`;‡ï|.Ðz ¾•¼IGÞÞñgl_]ê¾#b±çÖáÓÃý¤íà°è¤ä•Q6Y×7wº\¾fŠD‰-2Ó–«”ècÍ7à t—ÕÁìôKÊ5vn¨`6Ç›/ñJ„œvÆ+1à*Æ-fôdÈÍž“®ŠÒHln3IjYΉ©W¶5Q•Ü’T¥¥=І0¥(—ã’Ê!`a(广ÿùW›ZM ÕþÅ*`F ”q€Ë©5#ú7QôÐ endstream endobj 566 0 obj << /Length 2146 /Filter /FlateDecode >> stream xÚ­Y[³Û¶~?¿‚Ó—R3JÜHð©ã¤‰ãÄî8õ™ôg¦<Äš"^|¬ßoR‰'çEàb¯ß.¨(ØQðò.úç/wÏ(àç†I$\°4’Áæp÷ÓÏQ°ÅÚwAÄdj‚'»óH°XÓ{eðî/ïïþò ×àÀR­Epÿp¡˜ŒLD‚é¤mðSøÕ>k²M—7«57‰ _ŠjÅÃzýbSlW?ßw÷õý…@"ÖLA¢85LhsK"lWL©xY ‘póEynTør…HTTK2y#‘H‘N?ÛHBÎ)6 K”qB½ C¯¥O5‹£¼Ü–2«Š*¿a1#™âês-6•Î[l"Üë9á¸N™àrîuÞo¼t×,×2Š™ÆÛk¸}á³sX7»â7TŽ Kcó<*'~ñAòý¬Ê8UŠxTùÔ.jŒtŠ…™jü÷YžŠi¡–u3ÇŽ»€ñ{¾œc£RÆmØ9õGÄøî¶é4,žÇtÚ0£½šoæÕŒ˜Qc´¼É»}QWKæÆ0®®æos|㘥"™èÝ›Õn ³Ûø‰¢$yýöq'Ã7³ê‹˜Åé9o÷yµIx*³sRÿÚ È4‚H{ôšM›ˆ¥fäþÕ©íòÛ¾@ÉŸGw‘"½toçÓ†3ÃÇÛÔå2R Žyê€î³BÜÏFÌd<:ï~ßä7ð"•,ŽÓ©ú/g3%¾ ›—åisÓÝÚæÏ¢³6À`•=ùŸó1°ô\RïWF„ÍéØÕÇ}V-¥F¾Êoçx›”EpžgýmÑvÅö¶êˆ=£ž§´êD k<@þ{¾›PŒGñYuBǦ^.° ]aã«YÅ5ƒ]Ưں\S+ÀäÃDv¥!ìÚZ…Æ;õµM"d«b"òà䯜䔧¢,Û.|_õ]}Èоfeé=¹©«¶ØæM¾õ[ÚÉ{e]íœtXëj·æ4¡î»]S÷G+fÀäJ:Ì{Ú*¬R-Ǻ¬w'G"Ø%»‡§aþ„°ñÖº&÷¯­{柠eyº|ƒ6;øQÖK¸n{Z_YÆÉÀXÏI¹¦Å Áùg"»÷•OK þ"A0¶Z+…¯*Gª±­qÃ'â^7Ûö Ìcƒf|µNo^»å÷W E!MŠ]U7C““¶T=«MGòY‚wGgÁ†¸å¹“<šÊ _‘Ch·q!Iƒº‡5º‹•1vIBc‡¾(·$D‚Dw[Ù§â@ÇõG(‹Öje±÷æ´¿þˆk#ƒd½7#£ËÎI]Ê%±k ›GD¬Ý3Ûnýš6PÆÈò–Ù¸C8:ò>ó0ðÀÊB§¤ó¤–¾Íä03Ès;·¤"ô!ÜÞ1 Ù ÁsÜ3J馇b·'³ù阎4ɬ}Š]_÷-)%” '¬µý†Ü¼÷³¢ë3:”ü•¦6¢Qt¸5ßœädLiBd¸…ï®x<9Š3šLa ˆ 5y™\ie¡Þ„[¿Ò™6ZäÄ’ça.u&úƒ w7ðÅö>íqÀæ½›æÛÝ4Hª=€&¶> stream xÚ­ÙŽãÆñ}¿B0C÷M¶ƒpŽMlÄ€ȃíŽÄ2‘¨‰He=Ÿª®¾¤iíì8~ØU±Y]÷Éa«§[ýõ{ã÷›_}”튳Ú2ËW›GEݶjÕ0]kѬ6»ÕÕOL3ü7÷ÿá_³šÉ;€BŽÝ‘ºóÒ‡'O±5k-Â-wýwëŸ7ß<÷\ÖZÙW,‰b"H;²x‰|õ‘ëçµÕZ 2@S´ukÑü8>Oýú^]ÉÚ_hò d“ î9üo§çó²¾—LWË©ïç £jmm¸Q¯ï×Õfð\~b\æ…F8Öl9>£Üt0Îô{:ÂoS—~GÝä¡ó(§nÚ®i ç}?=­yµ ³Ó¬ÈUÝJ €ª•2$˜“H SÍýöˆ4%P ðzð¬—ãÃ(¢ž§ ÑðU7y`‡oÚªŸéq:. Šù_üϳÉeÇg”=ƒ’|¢j©Lp¢ŒŒ¦–kÐQèêûó~Ÿ÷H»KíǧéÐOk Ƙý™±ùŒû0BDÍôŒÓ¨Ž'üåÕެð ÄݹŸ¶=½ßuKΑ1B§ú !Ò/)ˆ)èÈûßãä©`‘…Ì ,…ª9”Ÿ “ÇSÛ†¹’cjÛ¶ WÝXIX.¹ @Éí*Cû=榪¸Wî’ÀJúÒZ òɉ˽üäß¿(¼ –ã!Aº¥W¶fF¾O½MQ=(=HûJ=IêÝ¡ 5˜¼hCP! NæñðÔ¢xC¨›sý¨TS‹Fy+ibûè‚J·>Bðñp‚Oû…€nêö/óˆ!¦…¥+˜J0^H´/3•ú|$%Vš òžv%”©e*î_ÆSt:«µÑ9ÿ?Å”&ðs.4¦ê»-&Ü@¢†`Cs£[„mjq»è[Å­÷'Bóy»íçy¤‹þÆSç=œ÷î¡'LêôZ0t.Tç_|te°’b‹§6\U? (ôË÷·§b=:/ ÁV ÑÊÐøàÈ×´üå0> ½k‘pºÿMÚŒƒo7îÿV/Á«o‹%mm¸úU%æÊ±¼fLä9Xv,ÔðOp,‰~#è$¯•}³ü5o×[[a®ÊƒhZWŠ`PUÍÝÁÇ‘ä-¸æ*ŽBuS±p(_8t,Ê¥B›PYáõ ] Kléð"4 õÁ5Öp´ï}^èÁõ½¶zˆMǹdÄ«(ûÿ<ܾí_ ¥Xeþż½å_Y+­UýUT¸÷NÙ°æj “* 黌…ó¸œ]ïü4ôE®¢©Ey,±”µµ±ÃÝc;V=8¼Fæñ€bì Ga×DŒñ^ÆÑ«©[~5ªú „ñp9ÒðI¡çgÈ[ŠÀÞ¢uû^Ep|¥ˆ>>b¥®þ†ãÝ]™tûÛŒ3º½è÷7" æÓÆðßfÂÐì¢„ÐØ8ûyÝOd q»½Ÿãajʶ¥4™ã@ ²5n@7 £ЕÐÿ¤!Éi?ŒÓñ¾ÛŽ~"?u‹Üèe£ûý èTJ ¯¶¶a—´áÝÁw~OÏ®XÁï|~põR3cö”º‰€¤¿‰sPwQ'8Tõ¡-ÒQWê9w÷‡n!ˆ¶ìÉ•×Bû€‡æ.}[[Ìr!ØÙ~Á†Ñ€t‚žœ ýïür8ôpwÛíAxmahBc9 =rš>¥¯eò!Â2AXƒ#8q 0ºy&£lÇŽ6Tx;/ÔYÀQ§:z<Ñî6:‘™wÞ³(49ÇçLpEÈåÔ×ËUB òÃV­oœçðøȇj"¸ÿ¥;Ð’·kS=ù!Î_÷Ü1>}}±§-Yˆ•†Ð÷á ( –ˆð²]q¡B4*CGƒ•ŒhT£QƒkêZÉ2LL2"ëŠÁÆVø¹¨ÈÄ1`Lü &ªxψ$+²ÖmÄPId«= Só&ž2‘iŠÔTâ sX^£@m¢&“ e¦ÿa4•02•¶&¶™Ý‚½U-lN8C(Y“'ä Ô:y!ói¢Æ“< Á’μ!Š%슱K®‘ Ì, p“%"1‰R~6lt-uŠ I¨ÄŽ5¡µÑYÔÈ¥m²šL LQˆ Ù$j‚%³%£H›‚[—xð$D4«BÎlÓ5[Î%ÁóT¹É‰„b%ÜÌ_,IyÀL â$;KÊAسJ½aª,í²hÌR"¿–ªCST#ÏaS²07…•>œB¤ ÷x %Ј'£$)£<æ£$¥*y\fÅ*e„²) t$fxÁ¬>ˆÈ"O\™g¿MFi³(O×T¦§y]ãøE8‹dÖÄ­M1 ™_¬UÉ€Ü\%+QËÌšI™й²¥»&Òi–&«9ÉîQvžw­W!,‹I§^—8î3‚\uueì, .sUæE2 gÅJ•ZÉØë”.YªI•J¤¨l1¨݇.ËZŠK–U¸¬\·!ºäiRÔñ(Y;y30ºÔoE!/*¹äÙ”¬jI»6”˜*µ:‡ÎS8–™âGîêÁÖû®‰Tá²JݦéÅ$7ó4›€›ÓµØ‘ŒGp O×”Š×b´6j·Kk.j"_›¸¨üëÆa޽鸯RmÁ˜Z¾w§z§#²ùDLnìµu‰_þU"®¡t™WÄ·Çýùà?Âpÿtpã4i]pȧS??ÓÇÄiç1`´§à-Ž‹íå> stream xÚ­]sã¶ñÝ¿BO 5#±ÀÏvú`û|—K.—kÏm.™),R'¡T}ú÷Ý/ТM·™Ü=È\,‹öŽ÷‹hñæ"’ïÕíÅŸ_«d¡TX$‰^Ün*ÒažÇ‹,R¡ŠóÅm¹øÜ-uœ–k“%k+šº­Âå:Éup»œëʪ«Û{¥Û2vðÓv_·nm7uÙ3¢–¯m;{·\ë<¨†z³T€YÁTžuX”—Üew¿Zþrûb­â0ŽS–ó²o‰"è Ðõ©èMó)@GØbœ–p!ú¶öäo›J wÕQhßÌ~¨>ì<݇Πô±êºÝu³¢Þâž w{»„“Ÿ:ضD þµÌñ"B\zÊÀÀÄ)é Ø™8Lq€ì²0Y®•Ұᲈw@kÜ}½±pÖ†ïyãÚ~èlÝ. Æý©¸©d‰-ÀZ‡*Íx;2ƒÞ±˜Û"° «nëº=O˜v¯ZÒ'a‡®ªxEÕõÞµkyæØ‚Ùð*ŒBݺ?°Qlj³*…“ã=Ýzrµ Ëɇ†ë4=;1®ëÁ`cºmy–ì•ÁÁñ·¤oô¨Kålð8Óïܱ)>ö‚DÛ¦«3úüêtž„in@4i½åüâæöâ· ÓÑB-âÔ„Jç‹}.W‹ÍþâÓ/Ñ¢„I8\hŠ|ñ@¤û… Ó—5‹gÿn§i˜«xEa‘‹ulkV0Ø lU˜dj‹~z*Hj³Hò4Ì`Å—¥ ÀZ¯ÄÈ®­ÝÏZl›ƒ­ËÍmÜ~±ÆhÊOÀ¨b8?ìªnöþU ;‰ç2Bct˜fÅW9¢1ih²?r¦Ãoà£-#lˆ ,O‡&2S5>±ó4/‚Ç F–Z½zê Œ´pÐÔ=yî®ü€ mWò$z~Ë ý?òQÌuju½ÂÑ«ÕÍê5Žñ÷×—B ›º-áz¼uµÃÎbL„# ö³eèÕŠçnxȱƯy|DZ¯qt–œ/Š8*èÑhjÓØ’..RÁåŠg¯xJØêàZÆMïæ.o²Ž G­8æíÁÛ!DÛ1Hì'diÿ¸3êžá]ZdÐë[Ö!¦Z70@ÚüÏ’r@cáœàÿä¯!ƒ ’$3Nþ­ãgŶ„]Ga&«H}çˆ ÀÖñ÷þh;Ë&Iœ§cÞK}ÖJ'<õ&ÌL w¬ÍKÆ<€BxÉ£vç,ϱÛP¡ƒ}„ÑÃÂ!ñ»j®üIfJùD«à'qt ¨æSË.`wöÎï#,û¾¾kª”ô5†ø=Ÿ{`”×5€".u Ϥœ69§0l…YIL±³çÎŽ™Ô|´‚êEÊ%Õ0›TßÂN•-Ñÿ¡“,ù +f³RHÍ Q=â|‚é…ÄsÐŽÅ=Ã,}Þfôå‚ÑRÒ$E  ‘ò=ÉC¥6TcӨƔ§Õ‹MtÄETŒM×q®Ti¨bíi°b˜c‡ŒÝ[ÝŽ‰2Ã1Í ‹PgKÉ æ*c‚ËF‚ŽÑ&ÔYüÔôî+ôÙ³ÒY*vê~xÀ-•êr¯„eÏr¿z¢_ۨl÷Œ&U÷lm” ãÿwwØuÄžæoslŠP=RÌ·]¾Ý…² .î«t»È*Φ]×Óf7ù=­¸Ê2ÒŠÎt¨uüe]oí<ô„È+ÒÉôJžõ„q˜BWò…W«ã(TÐö~ ñ¡´ó<ŠÿbK;l>ƒØõv@sæx©½!á„BñR‘±šŒ{L“ñÛ ’YYGÞÇ(©Œ/{×*MÂTM½©…>ù®nmwâl<—ÌŠ1íò _(I!òl»Ån€ Gʱ¬()láÚÖÓHîŸÆÅÙD#µs!oo˜É Ïc:ÏÓyÆéÜØuްE0ž Ã÷È 3*Dø»FÆ’¦²Â¿¾> ØŒ“×Ü‚^ó^n8å™Nbu*±:õš‘×=Tåï{¬Lå±òÇãÀ ÆwÈþ=Dž¿ZÉâlùݽ¸À?Þ\,>AA±Ló[7! (jØÇ+7¾æ1¾×ˆJ5ààE"$,ÄTʾñÖ‘cwí¿¶9õ5½½DP3Ø“%ÅüÖ\ÀEZ)hg®ÚÉ]ÄQäßdaMÁ.GX~qԨ˵X#¤ìp<vì.lêèiLb~µ÷»uý0¼ ¹m$¥}µžü·£¼ŒÍ0 >©M×W`…%ü—Ü®TS-þs€jçKŽWŸ‡ªíéýIþ=“]tFç„/´˜/J/& ³¼^:,ü3øawÚ7sY BnžýÁ}§öCP+²|ºï7|d,ÆìñÜK…¢Nßî «{’✢† ŠøR(#Ç¥£ñ´E%.CÅ ÖÜUË´=¶lÒžžs†Ò7MÝQåyCê†ÚœŽAâëtBü_LñË endstream endobj 586 0 obj << /Length 2302 /Filter /FlateDecode >> stream xÚµYKãÆ¾Ï¯à-`¦Í~’tNñÆkØIœÇ ðac ”Ô#K‘Z’Úñ >U]Ý©á2–9̰ŸUÕU_=º•D»(‰~¸K.¾ß­î¾yÏuÄ9˵Ñê)â‰`Y¦¢4Q,Kx´ÚFãöóÉÖ{ÿ(…‰ÿpU¹v×Å=¾óíý£’:þÏý¯«Ÿ¾y/Å„.ŒgØ:Š­™ò6Œëa…ýü\óJæïWwŸï84“ˆÒ£Xªy´9Ü}ü5‰¶0ùS”0™gѳ[zˆd–±LkhWч»Ο–­˜’9Éñ÷S<õWN®“Äïšú{ Ÿ,îä󒪜å‰ùÝ’^h3H*s¦síuj?ÏðK´q+Ó\]åËLίr•œ¥*r=î_Õ _#™Pz¾Æ°\š)ß¾µvDyÂD’ýí¯d¹óê)éG®2&—Ð`J™[4)4“*_F“@‹«ü6M.Á7hr̷닾»]•‡æþ0¾øÛŠ|áX´ÅÁö¶ínÐñMhå x‰\FÇ@ ¢Ùm:^‚oÐñ˜ïºiæ‚B.œba›k–§rÊa?j9ã)Ÿó’ŽLú_Yƒ­Ó¸¡ÿ}×·Å‘æ[{¬ÊMÑÛn!·Ò¹aJ§‹˜i ÝdòEøz“Oø^7ù"l½É'lßôæy“_÷f·d…ì5Ìÿ ™` çË@!ã,ãâ6(,Á7@aÌ·-êí(,Á6@aÌö«½ÿ€5Í©êËcåk?ßSRÅ/ ÜŒcì­_‡ëhµ1ŽÐtXw €¼ÅàýcñˆÇ‚£L|ÏGt8¾Ì5-ˆ+uRê¤sD5ß—»Sk½ÁyíÎCð_?ÜEÝ9±'P œá-ó§Bc}á¦I²ƒyÒÍvLÜ´4ˆ9µõlº Ú°H•ݱ*ºÉ™ÂEY‹LfN£8ð¶Fq6Ø££nóDß~©šÚÝi ‹úbÑóûçã´"çNšÅ_3®p¼ñÛVÄ%8øüþŒösˆÁN=UƒÎjôDYQ“Rº?`ÔR³<‰^;‹kÀ–»w£_'9Slˆ[m]Ö;êÓ ÑÙ¾‡ÑŽzî|ãé¢.ª—®ôÓˆDËv ÅÌ8¹ð ‰e§¶E_<ÌÉYøT Àp)~ɃÑ?&FÄ‘‰b”ñ™ÖÂíWs:¶ý†y”§À~5XVl·%ÒÄ0îŸúYº¨(r3DE×)ZKMk)(`§|¢ïzdã¡ĉît öê=%'“ äì—{­ã¢:!Q AB£svvF†ŒatFæn)0È嵉 2qÀ!3›C¦ÛGÉ›}Z©{Azñ½ôüqDÍeüÔºÊ)±-\ÜÓøü &†Âôd¤Š?œÆÛ¦`ª›¢´Ô9ußÌ©2 k }t¨œÜEAj[ÿ¨[´Íɹ¨šÁes‚Q«dÈRnþu˜ä.6'Ù/{‹‘œc¶Cª’!IÂ(åcE·u»Nmgwó˜’ÑiDÈÉE@ÆQƒõÍè³=3ì®iµÃu05´Fz‚ÞP>C¤ÄXÂãàÛ’Ÿ‹1˜wˆc[úÇEOÝeV\A{:‹êïýjŸˆy¨ræ¤=§V(甆ëý¾AeQ 0å°p‚«™¹(›ö$õ9H@[Åa¬ ‹MkšÔñóÞåpbZ†èÆF ¼Ò8›¦mmçK€zë Bæ9V×{O qˆ#‡8д%¹ì ¾‹ªÜÕ >-ÊÙšç1¦> BШ} ÿ}:liâBB5ÜÎ&¤oI¿äx§u$ƒÓ‚Òy÷G/E9›Z‹A‰ÜÎ]S mQîœs÷½]iä®F8‰¨̰õ¿"•O/4ò¼/C<Á…³gÃu¯µ?¦{¦2W Ž"’ô)F†X*‡´­!öBÛþVJ_^ã¢ý°}\›HÌa%_àl[q¡r¼‡Þ-€hãKInú1A€7eÏ{nùª'¡Yjr÷Ζ)yýiI§àÍé2|MílÊ÷ÚÓ¤¶"ɼ…HXªõ”÷­QI%•À–.Ð5¤Ý„:šîKøõ¥6ÂN.ÔÓe„B‚óŸ6½0Hà™bÚXäèÄ÷•ùª&w¥|ª’jŸóÄØ°\- øl=%¨¸è’Š ö®ô†ÑåÞøùû_~|÷j£O`LíQ?P&¿Ç¬öŒ;–5>›l܃nˆQãß1sÁ~;ÇúîOß=à÷Ýß±ÿ?ÎYÒ{*Ë½Ž Ž}ã¹ï}ÍøÔT…}òS,#½*WezVe÷í´2äø8Ì£ÇT2-ü/U"¬Pÿž[ endstream endobj 475 0 obj << /Type /ObjStm /N 100 /First 876 /Length 2084 /Filter /FlateDecode >> stream xÚ½Zm·þ®_ÁÉ.gÈáKqà$p›¢-ÛÚþ Óm!gÉ8Imúïû %]$­¥Ój·|^îîìp8ópÞ¨Ø8b1ALHÉGÜfÂkÆ+ð¼˜HŒk4Qž{“|Æ•LŽ ÉbJ))†\}f 2x2D 9ò¤Lƒâ IÎ&â½>p$p- I+à-Ç“V\ ¼b2Ìžð b±ÄáÇLâ²sÁÀŽ)` g—0ÀW%€˜Èx—ãD\6ŠðÄïA÷X“¯ó°ð‚ÉðQ„Šñ±(Ÿd|&|Å`XÜçüDÒ:¬DTŸ>ÂX#+•Ûë\ Uª®…ñU„,¢zHÚIÂò“¨²±*¯ZNy"ƒ}×%’Ç^o’~ ‰)1¦ÑžF(Zɘ†” Õª¢ ¤eP"ƒo2Ñ%Ø:‚g€ÑY‚‘Tp¨.zUxGU=f fÁëõsa ¹ 1E€@йòÁüÎC’HX NÙ$&gŠÄà¸$ï |¨2ù bRý$"xI°¼‰*U ¨TqÊÀ@{©ÀÆ‚•¦‚ù1{vàKÀDv•oƈ@<«AÓÐÀ›˜à’WV¹Î õeÑ¥À9fý 4¹~†EÅÁZŠÃcŽ ±*>`ÓäînÒ|oÞ‡ä°åÞ˜æÿü&!›AÄÙ‚I›ÇÇ“o¾©Ä¯—‹µ¹»3Ík€‘1gýì5TèAº»†`H½ÁWÍOËÙÛvmÞ›æÇï_›æ]ûëÚ<3|÷ßÏ-^L?¶“æ;0oë•M?Ÿ4oÚÕró4kWu£×GmæÓo—¿š÷*³±ºÙr€Ðåf›>€ž¶ä¯‹%8¾¯DER¢× *ݤùvùôÐ>UÖîC󧿇æ;ÜÀe|PafXEb#Ì3Û„e†Â6`#a÷Yà to7÷kðlþ2_üÒ¼º»«34¯fëùrѼmþþæýûêçõúóšfz?mVöc»híföh§3»ù¥Y-ZÿKi>O?=ڟן¿†¸·I¼5hÖM]Á-D¶ œë ˜Êï!qÅXcP¸/qÆrè`,ó@Œ!úœÇÖN˦ªù¼áܳá88뜾/6iX ÉB^¼…GÙ«ª¦·¦ùãòÝÒ@Ë_ÍæëÖ~ÜÌË…ó_›c`ÿ_g‚.1WbøRKð©×ØëÀD'ÆÃ®á÷[W¸c¼âz¯„ŽñâÎA¤1H»,×€lŒI"¶`*Ië…/XqºšmÚÇ¿ýùЊ}e¡z³—‰…eÄνš @&Ͱ7-bÕeYµÕ Øt ¦B=ÀtL¼rxL´ùÇS7Ú”8LûhSÆ“g¸p¤ûàã!H  >gÀ4]ÌWóOËO‰†ÀéÚþ™ç>°0‘Õtó·Àò’4.vP•ú *uQ…tÐ&$k× ê;§9 2ì4^°r§ÓDÄ´¬P‘´ªØ^Ãî:Ðû ¦hkæNÁ:Ò Ä¶ Èyù²ÏØÜë¿çˆ–,çÄXçXžò.X¢pQ õôþ±µ4ž$Ñ-ÌØ[Íÿ)y„f-ÔàaãY¥ì}© ã‰Ù R³ƒPë7±8²é) ¶•½3µ³;éØn«áu ÐÙVÄC·UÓc Rk]”ÕWätHÅé¼ü¼\M¦ŽNC=r¸cbänØ;š,ÔqC]wÆxcÄ`ᮃ¤¡’FMä‚$$rˆÙFÒÎtŽê;«8oH¬çþiÞ>wLÙŸÛàì>à Ò1û[ r°`¿ƒc¹uÁ¾SRh‹«Ç‚ÅwÈ[j7mÌŒ¼«8m,F›!ˆG$Ì5D'K‰^öø2b4ö¡–0’EZÓƒ‘&@IE.—ùtCø%Å ñ6ùó1Ù”üuÄ âˆdi´­6J¦¨ Ã2†[G£}Ùí5î®;xúqá)H<Òsˆ|‰/×(è”1s#vÅæ¨Mhønx4ÆIÚ†EnD‰¯/xJN,iˉ0®DÈ sÝ#/´>Mæ«å¢¤{¾ m¦ga¼ö#PB^æÈyŒ˜E{È  |–%ë3_”å§ùÇÍSk;Á4¸¾ã˜x׎Бä:âÚ’ 74.GˆÌ¡Ó®Ðca"ȸ A ÀŽ,(A°|ç’‡Ù@ÔÏ®©]‰‹‚«Ö.ê97¯CîEÏ>ò ‡žÝœQø#¬^ú”‡ÄœPÓ×ÓÏ᪺U!±[HˆjÙÅ9IcÇ·€nr6E=Û…×B±ÂPˆ— ˆ1» ÚcÓÓ㽦ƒM_âôT@E{ÀæŠðõ€6!õ/ï=gBü é:bÒÀÒ ç ‡ÉÛ¹|3Tcª1 Ü»Qzáˆ8 ™ÐS}¬&x—‰÷F@å@FÕëaC`%§®?ˆýüA’Ž’û ýˆX¼%ílëA‰v߈ÖàÇá:â ýDd>Âԑ©Xðü†q3Ì ¹[˜¤r‹AtŠc:fB- Ž„‚CKªj©N„δڶ.±ÓÍ}’Éü…ü00ìø:b­R¢ƒŽ,n¶j×—å0Ôª»²2[V”µ“­ç\µæô÷JÈï Ø¥¤ÒwI¬8ý±V²[ŒÙ#Æz”êÏT”ç@ÖÇå³$[ôHõ÷ñÿX„üP Ò endstream endobj 591 0 obj << /Length 2756 /Filter /FlateDecode >> stream xÚ­YKsãÆ¾ëWð¶dÕr2o œòÁ8±ËN%eUù°öKB"’`pµò¯Ï×Óˆ °\i¥ƒ4ƒyôôôk¾nÊÙíLÎþ~%Sû¿+…VÎÔLI-B°³L*al6[í®Þý!gkLþ4“Âäav—îfÞ +st·³_¯þ}õíõÕ_~0D.s5»¾™©Ì ©ÕÌç¹È@ôz={7ÿ¹j»ÅÒi7¯o¸Ý×ë²åîªnš²=Ôûuµ¿å¡®æöwéä7o¿}Kíwo¿G£è﯋?®ºúÛõɬöBªðw8•ƒ2°„rù%r¦EòG$l®„Öá%$¸ÀM À‹$¼È2w‹/&1pæýe¹ð2\0 é…Î`Áˆ€…Ñ$þ H¦pܵ_-–Êen.SkÑBçÑÖUóUú”¤ý´«Øõô57o¾y³X…eohÛþ¸ÝÒò7SÖÒ è¹·›P¦…òáußÑ—ÄcS«§Å£.Šg$”4öíEé<÷jÒñZ¸W²o…ËŸ$7-ýlñ<ÙŽžyÍ A9D§_GRÎ"²ØK’r©U_âgS’úî¢xž{¹ ùXƒ¸n_G>Ö ¯‚|Ìk9Ú÷åóÜËMÈÇxX`þ¢×âËIº…š—·eÓòàM½ÝÖ4~GÀÚ‡AêÑ!V « Šœš¢"S¥]Ë{ÆŒ¹\(m)šž#f€Õb‰#×i<òuÜ¿ï1æàNà`pb÷ž×!œ6[jD°~¶Tp|̺jÛ‚HÝÓ¿× fãÅѺyÁŸM¹:6mõÎ+yhWì÷eƒ3­ ,AZ?ð•E¾@³á‰zÏÛH–›Db[Þt<»ª·Ç]:²jÓÊM‘f \ò_F¦[$W/ö«²íšb‹+;’Äq·©¶%ϰ0Ñ©÷i’¸Í4Õí†Uç{¾hŠø:Yk =ˆ¥ãA ÞU¹_l/bŠÍ(#«ì™ýÄ!>§å¨|êt¼c¤|± ’'ªíéð‰¶ì­zÊR7"7®7;ŠnSƹì×.T~\•R‘W¸SÃÈsìTîDæIè-ÝÂB#eSž­NÉB¼fŸ1ÄÅÇh9D‡¯GÝ¢ßnÀk‘ØÏà„ˆ½>²E+¼O #â½Bø¾^äPyYt»r¿0Š´îÛ›‡Ìª8øaá N¬Š÷dG4ßVqBKîªnÿKe?–k~ßÀ(ió&Z"p†Ó—*ƒÛrÛmÚOˆ›×kj¯ÿW´Ëû_~&}Bц­Zþ>¶1>Q—²,joÉ_É«yÞÛj8viaS¦I¾õ†k0¥¤‘m}{ß“Is|Ep°™2öþvXú=!ïûɸÃüÐô§4]UïyT@-à gT@ãIL¨è¸·+>V»ª-ÏØVÿrXN2Zmع’‹a‹±Ô‡È΄×d¹0ª÷™eͱ½™Ò¤†Ùɬ_JÀn›¹0¸­1ôèdãC‡óÁ-¬¢Þ°,…ù4Z#ŒîÛj OJ,ý†z1»jÕ¥× ÷Å3žÃ%Fo+„M/k¢*AoE:LÉ]™ "Iüñ èÜGÁƸO2™0e¨™—óßAõä6/ŒLp»T>Rë³P3­D¤/=Ï_“›©}T á9$~v×üɨ$¯Û®úsRíÊ{a¤¾ìå22Ð{9c™Á®àxÿ)ŸtZx•] ¨65øÍq?DùrMÁ /Ùƒåó5}"ùž,µAêϼ„ú¿ŠZêKö«& ɶ/¤*1^ónis9ÿ®Ø® èã¶è&oénsýbÇÁÓBÁüdÙדú2âÄIWûecjTâ0'Ñf:¸˜Wê³ÁM 'Ý3ƒÛÒçGJh*—Â7Uý²ì„è¤ qdSÄ A¨¦>Þnj²cbŽSÎ(p™×Ü /Ù|¨ tf&´&walKzÒ–~¨¢Dðèò¡HsK€¶Çô‰€7¥„Öês^ú°‚áÔ#ô–é§sõÑÏÑ8•4¬ÿ<‘T€‚?cd¤(²ª)Ø•™¶Q‰LëTY¦ŠªZÖ…! #Ï|›C0ÄvQ)^›Ieü:}EãèŸöæ—/„Äk¾ÂÝ|~,/¥Jˆ÷T®îçú–“5th1æhèß±éõÅl/R½‘ÎÓ6?Êáéû¡%¹°Mí°º¯‡¡Ëu*Ý}$GO{ ïŶÂ5LL^é«lUWž‘…±O1bªéûÒnêL”˜à·.¸'Õ˜ŒÊ €˜‹Gm°`<Ö¾-Ä|×—qfÊj¶Uùád4ÕÑb/ª½æ{@Î\ òôT0åÊ õ£z⨘mÎ|±­1ªºlÞDÄRlcÁÇCöǬÌ!óªÓ@ŸNÝ -# €tñÇ}š*¹¯€›D¤‹y$¨›ê¶ÚÇ_°´ƒ!´±äÒWòÎ+3±X¤í(ÀÐ÷CÙGs1p²DTô+$©Jù'`m„ í^mKDMû¹Ç=‡¨ÂóÀ6n’[o'Zó-4Vp³.oŠã¶ã¹=ñ'ý”0ùœf8*»È œfà…KÚtX•xˆ¿…Ð@,Ö¡FíA%<çåF~ 9Á 6WRÉÒøùéaãZB ~:Çÿsl»êæþ 8P`ˆ#\MðÉÛÌP¬dô xˆK´½Øóh'Ù¤BÃC ÇC 9Hüë0Z‚·çÿ§Vƒ endstream endobj 601 0 obj << /Length 2872 /Filter /FlateDecode >> stream xÚÅZYÛÈ~Ÿ_!ìCÀFmöÁ+A²›õˆ‘3@Ø~ ¤‰0%jIÊãɯO]-‘Êž™Ý /bwu±:¾ªj*ž­gñ쇫XžßÞ^½z­“™ÖªH3»½›éب_6»¾-«oòêûÛ«_¯4 Ç3=s6Vyagif”K’Ùr{õîC<[Á GÙ"ŸÝëvfUZàkõìŸWÿ`k/ì¬S XÎe’“z:ÞåØôŒSi|Ü$œH£Ñå.ú×un"OâœÛ$U¸FR-×$kSS‰†fÑXȾ€Ö5õA,Õ¢¥^ë¨Y”‹ú  x¾ŽÈ4­X¡ox‚{êÕ5÷¶M'K:ßÊþ3›¿_ö%®u3¥ýJyul¹ŽÞkëиÑM&ê5`< ž—@úÀ › IÎØ‘ÓÚTÁ¤Atû)é*.ŠÀq¿©jÏ €)td pz²æÓn ÑâaŽKih¬H?z½Ø°š´K”=Ó’œ 䥓 'í¢uÅÂÞñ@ûØaF“r/dPö7`Îêè—Ú—pÝy_ó”wlÈÛ0¥óäö@9tLy œ9´L=ÁY7R\Â[oýºlWìì…¦U„½Eí·ÜÀË ðp@À°——LDöG/{&Ü5íAÞD÷%Od'l×3n¼ýáê±/ÊBS4¹éûý_½Z·Íaß©uÓ¬kÀjÒAà)aÙl™ùÕ~ó°­ç.²\?D†GaÁ*Í‹±s²•e3)£‡|óÀÇR…uÌž_ϵ6IôBJ.K¢?ð£9ô'Ú!h4¿ù7À>Aݽohýie§¬Ki‡ 1X:ËŒ,©´,ú¦úÜZ™oKö­|Ýç¥ç/œÿ–›ðœÛ(Š #m­€)¶{0°_Ð>¤H)DÀÐ}µòܧYK“Â<·Ç¼1˜7†¨J¹ÝÈЪꖭ亮.·Ûr \N3 NmôNªÙ ¸¬6)(ðCß-Ûõ{z`˜‘IbÞûC]¶LÁS!0wžIƒ31c8 °†À¼ó}µìÔÔ~l‹±÷ ×·7þ5+u ˆ",-„²•@¾kz¦´àómµì)eaød@Xy}µ—èqàGaÑ;¸n«’ß@á&<»ÃР?œF\1Þ˜4ÊeÛt0V@F|\z‡C¯À °×cÉ ‰1‘åKnäÑšÏ.˜Úr À‰h7‚IhÈ^“ÇX -@áÊ­¯á”C> ¬|$ì‘™´ÏVmö¨SVoò¡Ã²öMžÓMí[$ ¦i [ÝPÌ*DgHëü¯bb2ähëy'HªC;‰]Tõ̺-?ÒúóB”èä5”r¡äÇäöI»ðüáöíT໵‹ãè»\ÇC­šku-)’aë^4 Í¡ô:&‰’ú“wøÝTV`²\9}L¨þ2…lи ,˜OM¤•ËŽØÿÝ…yrˆÂ‡^.1ºâŽÑ|ð¹©ÖI㌅ò";3IÊÀMÎI¯Á*£Ù "°H ¡çAåy>V2QžcµÀOs\4âIÎèMŒØHF±~¡_õ“5ÆIúGÕe×y2°t˜ßÛTó77%šø'©À–zhÈvÜAk¢F+EIŒYj[}–éyáC½b®SfîPõåγߡÕÕGBÕºÚœÐ"Hlë E»“2‰MLfäAÙcäM —m¢ÏfÑsÕAôÅqæüXû!Ê—kNDeú© ¯b¿mÜ eéÂ2˜Î¯˜À‰4H/9éz,f—1»| æÄ¢òðx„c4ºrëù5ö>4j>4ÒNéìΚthÐ#¤4YH¢m,½FH°’¤‹`˜„èT’<² “K~`œ…ù¸s×ÂîQ Mû‘Iáá…Zü¥ é2—8ÈÔðså©pñ܇™KÎ?±KÊŽ1—Оgñ(!n8Å ìY©ÜL'ìØö‘ Ò´ A†ýJÞB—§’È£}®'z¬tœ©œŒcCt¾ç>»Ã£DÏ%œàÞLmB' l ÿª^Žo¦N É‹Iž¦™))NΙª$-¦4óXŠæ™R,ENl©¥ ²3Àä¸jމŠ€ öŽ)Ú™} -ÎáFÚË4WqÂp \ž´/£œI;Œê© ]2/÷,o}Éœ_3Ùñœ—LÖ}ÁdGNG¥ä(âþYB>;òÿÎ/ ¤ÆS£/XAV(gõ`ì~—ŒÀ~Í’§cÌ“b©ù ö³âóaK¿¶ÎmŠ_É– gK¯ÍªV(Gµ› j×Vœ±ÏÓ»ýzOçÊ>GGõž?Í–ìÿ%\ôN,\ôÓ¤ø ÌãÏZÏÉEÇ+?ÚßÍÔª©*\òg=7"›|éɨ$Ö/1’¯¬·lZ¨2åJš‹D¹ÒÄrSêY).·~Å…ÖŠ¡ ¼+é‹^œL§ƒÊ”B>aw–©”’íÑ%0ÖƒØÖƒE&vÎv>jCCvQðu7¥–k¢" WÅÄßðssú\î™ fªZä3ï¸sʈ¦jKJß3a-5*Í27L`+s¡ÌÒéÆ$§o}µ[öáõfËLrÁ€´æÀsØ(Î/yÂÝ©¨ÊÅ\÷á³Ùqo,'—»ó4•(H¼t[Ä£e/ÏpÑ…ºÅÉé£d˜vʤ¡ø¥Qlú¯Âã6]¨L3”n:µ5À6à¢ï)± Â9â£oõáß:MT§_úV—ÓÉøk}†Ùœ£J éuŒÒ³¨gaƒE A€ÀÅa¼µ*ÕÉðó‡=V-öxù@Ô3ÿì˜*wÜÖ„×uÔ=l·«²æ‘Ó,UÂׂ£7š90×t£tüªîùÖ¿·.¦ 8ÁœÅ-µKïÃ[kƒ‡é蛑¸/~ÍñrÄà –¸’)ÎUõ_ÿWßÉ endstream endobj 611 0 obj << /Length 2553 /Filter /FlateDecode >> stream xÚÅYëã¶ÿ~…Ñ/Ñ·ŠDR¢Ôà>\¯¹RÒ Zæ®ÕZ’«Çí-úÏw^´-÷@~1_ÃáÌpæ7C9ÛY‹o3/íÊk5Øô1ÊTÕÅÿU…Ca"DßÅØÜª*KëLQLU¥ÄÔãÞƒïS6)²´ªóÏÙİMô§mbÔæ‚êY›hõµ×Š*¶³k{¿ãÙ-"ͯtØ_s{<<µýìðêq¶nÛÚù´Å"ûlçû '«äé|ÚpÞŽ˜u[)ˆ` f€X0Âó~ôÀÝEÒ ÝÁ$zA¿‰ð„6õéKVU2ºÙS×&›Çöƒ îGÿïÅ÷Më'"½Uòö¦RÉ0"'Ò~š]ß„íÏ_©.ÁÈgyš ?—ÛŠƒM––¶Œ\êúÀ[mk¸ÖzmûØý ÂI²Ÿ"’U)xcD°ë°zålßqìÿá˜B—õ—ñÔžoc š©¨Ó¨4«O°÷¥‰=zs5Uñ¿•¿ø"ñ‹¯?æ$6-À׿Hz}-}ÊAþ3˜1E£¿ÒNÜ4-, Ð#ÑMžìÝ̘¥@Æ¢Të°œ–í4·ó2·CˆUf„IÓKD/M}è5ÃSã'¦qýŽ;S€¡Û±]:¦»@.!EY°Óö;Ï è¡'5! –‰D…Å8t‚í½ä+׈¼y2¦´)®ðåïŠjT–q3¢¢)“e"äçYZVÉä:à+õ‘.¨ÛG t³ž-€ddœ~Š lÍ ÐL†Ž‰‡ÄÀ=­ †`0Øl†[•@¢EÌrØJ2™¦v{ð<5Ü6$‚qidGçzÊ]r3R0UX Ž†K#DÓÐIoöc7q—䆖âÛ.OB‹Iƒz{‡4ïÑO…`1w¶äí>¸l…E5Ä áñ} SL[XÓ•¿ÆjÖ&Ç`*åMQ%;7;îMžà¼†\r˜žƒÔçÁ‡„v–Y7q{â&ûZ™?3äÎpò´”‚’Ý|ø„ðX(ܦÛõ o½¨Ô©°c­Œ†b•Á5:§[Äœ;ò s;ÏtI0ãxˆ#Ù’]°Nv-ä±³€Î*ÀJY½þCðñõš×.…!@7õÅ皬RB?Ø0ósô‚ñòwB1p‹i;bV¬œ(¥@Rè¡ãpHîê\#é´8ÔÑ1u¬¤~$¿åÝ<µm‡Ãððijð܃0p‚£01ÜÏÀ,"í2Q¦Ï$5˜ +޶#¢[òËË©2qBü¨BÛâ•]06W!3è5 b Ä=,"(¤W|çb–*°¥z­’§0}{·ãç9X¤ÃÚÐC‹nÌ“;˜Ò‹^HOYïrŸ Îýq’øž@¼ŒHøÇ¥ŸAYwPß<_Ͻ#½žàîàòAF<´Ö—µ O,ÓBQHƒPcêÍö}»[H¹ ¥ÃÒõ²‹ô ½´«/•Wq!õ ‹#3r¤ø£9@à<á· %.ØëðÄËRÖb]ÕË.kG¼bH"oD³¡¿Ýº‰hVú↑Oð Ea_düf3â×Yìüôà ü@™Ë´…™ÿH `ÖÓUò=È‚è}õi“j)×yêé’a%±I¸®zdA~‹(¶Gì­èþLœYùÆÚà-îyê?ÎÚ"MG×€¿ÈrHìp¹äÎl¨žxth»–-×_á1×Pèíé±{J1‰'°æ“Ñc7ðIOô»ã•ðL4™Ze\#¯ÃØ/Mòº'œ>N£ûL"¼20×R6™¸ósà`ÀON™ÊX©¬=¯ÛÉïO²ÉÕßlHôȶôL0¹PqÇK#¤é¡Ã(À§%$ ß¶¯Íç:©¤~˵‘ªïo…¹Eÿ§;.äBLýOT™UŒ”¸>Í‚n\·‘ìëýóiÃ:9ÀÒ #4.}Ïp¨ ˜d]<ì0zBÃÛ‡J+#…•[¸¬ð.•g%m®x½¿)à±u[Øuñ/®Qm9¤qæè°ììùqxN«yU¥ÿp3&ͳð·b¶"úþîÅ# endstream endobj 622 0 obj << /Length 2655 /Filter /FlateDecode >> stream xڵˎä¶ñ¾_ÑðI LsE‘%>$ˆÄ@‚lênN·l=Æ’zÇó÷©ÕRf×dO"‹Åb±^¬*Å›Ó&Þüð.–ïŸïß½ÿ^§­U‘¦Éæþa£“XYk6.ÖJÛ|sÜü;úG×øí.q:z,û­ŽÊƾÔ=ðw<N=ž·‰‹žëîä[?V†6|óèèaÍ;Ê^¨ºv¨Ž¾÷GÆ;†ïñMH lmºvûŸû¿nvÚ©4-àkߌùÄ}Ö¸¨¬kO8ªÑ8Ì£ª½Y+ëêÔ6¾Ý{£Úî\–G÷aqì}uÄN{fP%$GÜúüXà`YêZÏkÃ倫gâ:^ò ÒdQ©6±|jR$pj «nܾ§ÙG*½N_â: ‘ü–õ }ÏÜÐÂ0\’.'3Iw…1’±I4”Œºa âøÐÕ—¦ý<‰þÛzÆžn6ðüP¶¼ãã6MAñÏB´¥Ä0dŽ6$—.A¸§°Q9â×DOg07¸Ô™ÁÃe?ŒÕxAµc”‡Ã¥A”K=í®dt†4iüÂ}- ØÊ@µ?úöàïÖ8;VbmÀ [< ™si°A²8`p.á#Zˆgȱ–ÛƒìÁ+âq)ˆ÷ÇÑžÈÄî+wlc|ë°‡‡äa4@ÀÁmì±§SŸÚ¯¼§Ì;ë$I ñh°$|»G“Ü—ûª®Øµˆ,÷ÕHÒ ü§1[!š "@K&;½…üeÓ„vOñhµ&\û.K…×Äš{)óäê÷8„#ÐKq‚îÊÑs„! Aô81âBœ b›Çk  ¤g^%Ó¡g”û«n•d,P@xÿ½qóèk e Ø%FDbe™ò2Tg‰2Æl²Y -C1²°*ÉÒ%÷g2÷TG½/‡®m!êèÄ  4z|¬+2£4ŽP§äO]ö'rtX æ¡›¦qýóìb[ÖÏCÕžIn¬kÿzôFkТ‹B\1·â)0¨Ú£Ç†cg<Ïäü4-5ž£l«¡aÛäHM›ŽÕÃnMgs/ŽuT1Ƹ‚˜uûÁ÷lMGÆäˆ KÁ[ŸŽPÀw`ʽ+Oe…&eb‡.Îá 3N®wŽ5ßyÅuÙË %èÔó˜ÄÊC0Ì-ê= ÑäµÝ¡náq•• Ⱥ¯ŸY€À íY>‚¸ˆŽo3<Ìõ3#õþßrÚÛ­Iµ$ŽâÀCLqi`ÚþÀ†‡ËpðWvpËé…ÁH4a`Nö?Q„Pò2 ÁeJCÀÕ}Â6úú>Ó2ðµÂíà)ÂZÕ¾=ç_.yÑB‡±äÐdl5ÕéL)¯N¹ N(By\únxLº¢G/§plaî-äP!³.[IÄ@Ý“x$ÉCÊV(uì–´¥0é…5ol#ñ_«iÎÞ„¬LGp8œÃ0Âs'îîX!p82ÌÏßÚÃy½Í¢ºú•.\WgV†”'¼ŠÔ­uøàáôHzEÀàG5åÑ3"Aç’€uíîÕ–,AÂ|àg<1ógÜ1˜—¼ã«O½†§>ÉÊÆ…9?¥ƒTanÂëTÒ8ÒJªíFöÃ[ ­ b Äÿ"(zãTU ‡vc!ß( ƒ¾ÆÀ¼Ê­VFƒàgøwk;¥Sûös“ë¹Kz+ç~Þ’¹èküdüqáó ×6%N7 ¢#ª¤°7ª[PJ•6y@xM`Ne¨ÁÙqÕ0™wËöÝíGȂ۔Cp—ºæwbøZ2+°'@-SE&üÏýŒÿ¥ÌœŠ³â³J@Y&[UþkJ˜ðE «ÄS•äù-ñäíÄÿg /þb6ÊzÁ7aîrc¢o×NÍU–ê øt°8»˜ÓÝ¥¤¾Qiîï_+äbå`7¥ !W­\%QynÂU¾]÷m8©(ð“÷¥Œë5L¬}–÷7ªÇe5É‚°RY]SMbAáÙÛT“ý1Õ¤oT͂Δsn“äp9áë'AKÁH ç26WG¢JôÍqKî‘ ò¥ÒÄ~ŠûD˜åŽÃš³©BgŸµ«.gÿ_A˾սß`W "»L¥rÊÁ¼æb¸¹dLVœ àÁÅ ­ÂABÜ -Lç”KØ`c—0êÓÙ÷~5Ë0”ÃÆKØ_FÔ+1 qÜt@—˜fXÔ| µD‰æˆÜd“Ô¾g ÊJKh„Hÿ'UËß)µæé<õ[¹äöÊÄÙ oݾ¸*™JïôÖÖlŠ?µ2¥µþ"Që¥ui´.B <;Y¼1$ÛA’E]$Ëš†“ ÌÞ¯I¦õîààÂw¿]Êk) ¥¬”WRXì©âe¨¹Ù J¿vÙ¤D˜ŠÎ—;X=Ô%V™ÂÏÃ'ºÓPGU¿—^ŠáyŠ‹Ò‚ѵ—Å53É×´Ç*Ë®¹ö𤠕™É—¤þ_Ø-ô»Õ ®4³o³Û"žºŸØbÏ¡€G)¿­u~骩b A/}[Q©ŒÊ¥w‰é‡e‹Ûäî¦úC¥¨€xæ@ö}÷+µ+dÏ‘3Ó–ñ„™îzÎÚi5/Ô·ü{ÉØx½`sÑq‰5oµÙ©Y ¢%=¯+m¼Ô™¦[bçŒYE‰Cùý§¹€¢mØ£Xmkí…µÉæ©Ë„¥r:v䪓˜ ÁFšjíµÄ5òâÚ§sÇ‚peÆÇÀë½:)¡ÌE?Àù*t.öKW;^Ëî)p\蹫´“k,¥B3q³Èý](ûîr:w—ñ5ì¹T—}”áúƒe­Sò3·Æþö\)>›Ç¥ RîŽÀç©¢V }ܦ §¾ò!Ä ”‘º…\a:ëŸåÀ÷fRôú‹J{v¯ÿ/.Shû²õk–(@ð§ò؇šÙð_eC¦°“þ:L&¹³ˆÆ¡•®¯ê¹$aº´ „ðÁ:„¶é/ûFç9”X $'K6môé»ûwÿÄι endstream endobj 628 0 obj << /Length 2690 /Filter /FlateDecode >> stream xÚÕYKoÜF¾ûWÌ‘Zì0$»ù²áCìµ $686‹$j¦¥á†Ã‘IŽýû|õ ‡µ,1°ØƒÄîêêêêzWO´ºYE«7O"ý¾¸|òÝë8]ÅqX¦i²º¼^ÅQ…]åQƶX]nW¿CçÜÅÚÆe0n/ÖIšÃÍÝE‘áÅ:mp¹«{ÁØÚ~誺½Ú °}õÇERŽP’(è]Û+½O;מöÕ[×Õí¶u?T-íš;un}ñûåà}ÛÐÚLØkªÁm/Ö¦ˆƒ¡ú³ú'†eгÁÀÝm½©ÚoÀl-ä\·îånSS´¶­† —É¢(x}J‡‹8èdiÓz'4sÓq <>1 êÐ…z8ßËÃjÕVÍ]ÏwL”!H©«Î¢µC'_Z(‚ÃíçÖÄU»nÜGÚçÁ ÖqnRbí0̸´,;'ƒ׎¤÷õÍNÕCÓ]E!écšI°âª½Žˆ0ÕÁR[uw… ‡îdYðÞm{"|U·Ä¾*[ù—Û«UœqG0‡ƒ~GêÖkØ|Û¸®jË ©[WÝè¤?tƒ“[èå°Ç_+óM¥’NW`{›ÎÝV­ª#‚+ÑÏ@÷þÄÜ;ÝJ¼yX"Š0†4a÷éeXµ[…ítñØn™ZsÇL¨•» àõ¸S|F¿EiÔ“_éh8tŒã;òj¼ó ˜T×ÄÙù]ö\“i17òéÜÇÚ}ÙZKãÞ¬ÔowtÝ»¥ÈSõºÝp¨7@Ísˆùš=îí¨:fà¯~¾”Ñç8ÍîqÊ~?_¾z÷øöÜwQì!ßdcü¯¾ÿVЇhuN[·EL¡àsØ«I2Uo’"æ õ^-Ÿ×¿¯cÚ%:ÆHÏ2ž–¯;¸È’¼Æ“~IœéØ õšÐÃ'… Ù# |DŒƒ7OiçúÄÐ<ðŸø=îÇ‹¬P`B›ŽÂpø!rì ™‘8Ó´\ró=E~`ÚéŽv¼£¤b³³ì£XÕ #¾{–¶Uñåh¸ Ú×ƒÓ "s,âuícö¶B<…R uÛŒƒ0"7öw² dÄLdœ^椡¤°cT6¬è\-ÎDÐý﹕o4LaŸF!=ºæƒ<êíw0W ¡QÉêè99GÊ;™œDâhb¿8 Ú§–;’éÝep’‹#IL¤ÚÐ-v‚Iw¤/˜ë]è ÿæ¬o¬çCš;Õu:3­,Å šß½N̼pIâ,,L£Ä¤gYÜaž§#†—JÚ$1^øhÄ&Ìb3¢íø˜IÂ2ÏF¤—Ð1i<¢HHÆ=ë–ªž£ø‡Üò“˜Ç»·bÈÖ œžå¾Šu#1Ä–+.Žì™ÛQ–tN–$£Æê§)9·©wƒ¬°"¸êÀ™ÈNæko†]/HÕímÃVàoi‡in?«ki«ËϪ!º #›/EôiW7ÎËZFIñ˜¢ÒrBÙU5²4¨8ëµ2™9 MUR”VÓXÓ*ÀRGÑèFä”–˜Äz¼Éë,±kÃ,É–÷;éù)aT»&.è(*§dòæò½ NødgT‡#”È"±–:Å1™JÀoŽ®×ýlƒ´2(š°A>œ)=úˆÓ02éc–b£/°[”éµÈŽŒ’>~x™•2e`0ú$Í ½*À§«brìÝö´ÍÇQdÃøt5¯ñ–¡-óƒšÈPŒt{·!#è‡7b}`ú§.bíM­…ýÚTþ.cŒî‡ N±xÝ‚í©N@¾F Ä€ÝÊe­¨—í#È6ꦺjt«Èë;å–¡b÷2*Ž·RMh©Cy½CU©@»•œø/ŽŒ‰’ îæØÍê-‚4çõJMÍG¼±KÕ“ÈWBÕL¾_¨X3àÒXÄD¸,Bƒ¨£Ôz‰rþ†®EÊÐíÖG3&rw ¦|Æ®^PëÇpDxìG„*ó±ö0Y˜ãl*AJc¦FŒÚ+oØStdž8SYj¼ÉHÅúȲÑvvµð–Ï9ÎÏ´ €D¼L¤6ŠÌéV¹F6KT –”0G ®%¦ãáÓD8•Öjâ''!|ûc=ˆIÑLZ5Št¤²jèê Ç"›âb:ÖM}ÕÕǽà_wîÃѵ›;™ŠKlЬöÐ0rÎ7û“ÙÈðÁ´'²ZçØeˆf+°éÒ _šárMBè{'Ý.XåŠjFë&R[«?k–A¸÷:OÅ­t¦]s ‡9-:]1ùLêdM šw¸ëåN÷îé9‡*-Œˆ“·þ€?kUÊDÌß¹Ý`ªv3!Ä3»a°„ dŸJ‡D6Ræè„/böPC1’ØâÖé+K»Õx.øYd’Á"kX¤AÙ4† rû”dñtkê4²¬¨ Âæ@Ûfæ@ð-¥XpØn(ÙhÑd`*õ?0¸°÷•ÔóJÏ”Æo9´ÐÇZf•BÅŸh´Ÿ9•öfžDë£'©¢ ÷ ô¥÷º®ö¾Î\©o˜H“L»c¿e"äÚ¤·f!U¼“|(ç'zÉ+~o‹ µ¬5õòVïD * ¡-'~íÀG[_r\Î5Ýyëí’Å4îÕ(¨ÜÍÔ$´ÞÚ" ‹Sù1oeà(óVF Ò¿#3v5Ê%E«Æ®ÿÐh–ïŸ2“iXÆðSSÊ?udY^^ó0Ê&Fþ¥(1úœ2be5²ve‘erÁZDê{ãõªÐþ3¤Bz/ñ4L ‡3âÉ×JŸL>ùøy&@ßÁN’¥ç+¢#†IiÎt¹ ”¢j›ªÿãK}£/Ai°^//EŸûN- Íl­„ìg—‹´ž²úÖhA µÉÿxÈEaŽåu^Kµç*ô²?Ýõyì!„:ÏóURà"Ê×[EKÉîr4µ,“œ_EÂ$>;nÉ=‘!¾Â4±Ÿã>¡;÷ÑXúT ³Ïι¿WÒG¸!>ùøÓÅßv¯6¢G%?³þ9‘5£uc™Ù?[è´„K‚«u…Y‚…EŒ«>ûK¨ɾÎþò/³?û­ìÏü?Øß9÷)jop_ŒiùG÷yÛø ¸‡¢3П³ÿ‹ïÔМq¿ñrŸeÅ#ÞcÃ$Rï)¿©÷dÿKïA ó{rõ߇^23½2<÷Š A·=5ôzÍX&N\s±.ÙKèuÑ~þÝ"B’4ßž3t¼étÒ3ß™Âð2ªGÒ°ˆãñ¹Íuþç68Q4•No=zÄ(£÷M$T³°ˆå¹yˆÞr5Çâ'ËÏVòda®±P·&ò,Uü|5=`˜éGc¥Ý0fQ«;/æýï¼PFvf»çœž~-.ìôîó£G*%pË/“Jq_*Ó+Ž_$œ9 š’æyý»6¶8µŒô$Í’²cõÁéõ«‹>„±ä÷™âôPLhòà -ËÏ6Åø&jËåË1/—ÃåosqQ„–êŤD„Ðüd’Ò«Ë'z”H† endstream endobj 638 0 obj << /Length 3355 /Filter /FlateDecode >> stream xÚí]sã¶ñÝ¿‚o¥f,ñA¼›<4iœ¦½›¹^o&×I2SZ¢m&”äT|×_ß]¤ úJdÇ“äÅIp±Øï]¬œD·Q}u‘¸ëçï/^\Ñ4¢”diÊ¢÷7MÑZD*¡„ ½ŸG߯_æ³ SñÝdÊyϪ¼iìpuc¯9^h¼˜Ð¸üØ®ëÂÞ—nÚ"Ÿ’¸ÎÛ¢›ÒÖåÇÉ÷ïÿñâŠñ!F,e„Q\ÞØ9#¬I•è¦\ÚÕÝ?#êŬ]Õ> ÅOë²*¯ër½@Ñ”IA”–Ñ” "„´°nj˜W,geÑ„“ áiÚ-|Ä“Tö¸åË9,/Sƒq]Ty[Zí GLaN³¾nÚ²]·åjB‚ª κ%Þ…°ÈH’èn™LÓ4‰?¯óeÏXX¯*–·í]sZ#$Ó=^ï`gép£†¬\fDj­ Ü$q»ºŸL‡UµºýZYQÂ6›û.á"¸xB¨’ýⵃžWÍ G@Vä7Èg]Ìíƒ#ˆÁ›<Ë«ÙÙd6 `j?£*4œªÊ»•ÅÚüAHÜßAP »kM‰bx›~è¸Ìd|—ãåûKó ÍH†_0I¸äö‹·õwIš„yNÕm÷onÉ@sA!"`—é҄„G §Y4Ì5™R©ÂÀS´g§‰i/ª»¼²C sI˜”ã…ÝD1œHXÆ;ú,RB¹ÞHU‡¸/Uœ¨Œzxw3³¨ØLÃ4Q`ŸÌëϨ«D` 0ÄC(.6MI"JV+;ï?p‰5R 69pe`hÆ{|FCxI¢”ŠýŒsO¯A S˜úd¥RÀ ´hã-çc`àDû°gÊ"Ÿ8Š6!6“ŒÊCȧ €¼­WàÄèȃ¶H€?ÄþChUÂ3ûY{)õû‘¹„%}ƒÛv„®Ëì ²§§ªÅA±èóÈh£©":c¹Ùd\Á‡Õ_ìð’od5Hæ´—ˆY hÏH¡1’ÕGÁ²´wÌ_ìð*œYz"fÖ€hP- ÏT€JwúÓ€<¢Q¾ K2å7äQ³Ô1؃$ÈÌDUG&dÂNöaˆÝU;iÔþ(ó–(y9I¨¤¹>ü áê/"–ød^Ä9²¼ ãQ–Wê#P“‰ôéVïB%ä8ÃÚ‡xœŽò&w˜6ñsíNÚ26|¸»ÅŽh‘Q5Ü ¯B[ÀøZ£äÒ'à ž°hŠé–¯ã ¤`YüÜÃÿ]HpŸŒ>«ÔcA܈=FW[,xÚ –d©#|LîpÛ™R°0bd0*9x‘ÁŸšó´šÃOÐþÛkÎVÄ8Òœ @߈ ‚·ê×!X ²!aƒ²êY8zÝL¦)ëˆWO˜îÆehé9ÝPêÆ“öäØöpWÔEh;æ&éXg„Ï0ž* Ô(î'Ý\Óh0ë2´ž$Ù†iWå´¥ƒ«aÅ[Í®¶²Ðø­›¿¿„PÎ~ÉŠ¦Z•d®Î”hï™Š× ü{m*LEm_˜ŠÌtEBaÍk§³¢Áº'åXTÒ}ÁfØoôvÁ“š(‰ï.xN¹H\Å£R¥på[›‰°Ïᦵ7ù=Œï«Ovb»²×û¼nKW_ƒÛ¢*…Ùk´ôóMå7HLÍ´çJ]4¶˜»wˆšÅ$ÄQ¬Ã®¨¿ÿšÈŽÑD~vMœ2ÁM! ¼p÷Ëy9Ë ‡ñöf½œYªâð¡u£Ü–+{ûó$Ŋ躰·ì›î³Â.2[-Ïër™ïª8Wˆbl¯¶SS 6ÚÀ=Ÿ5&m¦u4˜,?ƒ JÁŒxR{ŽY{ËÞ„åFþƒY½ÚBJô&y´3­ ¤:¼Í”{ëY–fq>[çê ÞÌ‹ï*–X¢ÆÛri¯Ž5 ì®Þ\TöþÆJÎèàÃ2v=¸ï„#;¤rÓ¼ªö©¼ÃHgß„åošÅ_·ˆƒ’ž Á­AM©8±·+ØNýP6…ùLÇ_/ík»K˜P|Ì÷UaŸÞ–Öž¹I†$0§)fp^$€j<ÓÂÁ»¯.¢oÍdM¨›`Ï»¶|zëÓ †$&£óŸîã? 1Í`ÖþȆB†=„ÉvÁd§ÀôÕ‘‡£’ÌÛðiÛ„|eãz4¤òJ8áqI¿ui,†¡g`Ôº#|0<Õ2oÐ4AgOxó½ÙÉ(½7fX$q€UlèŸYƒ0± y0Ù~²Š½dÕIïÌvSÎ9x²pžß>ß¹P‘‚“”Ç/”- Ìê/¡ÝU8‡ÒŒ‹v ~¡ÉÑ‘›µ)Yj‰ˆ$"^7QR㿆IæAáávÑ ÑbiüÍDÓØÀ6ˆK;µ³ßö®_ÖCÀŸ»%Qs’ Î,^tgéàø|Ó/ópe3(©FEmìÈdiÈ`mVžÁú,¸žW—ÿ- è!­äGI+?IZ}˜¿Ä€zúv‰Ͱ# žm…!72¹—•]üÎÄÐ.ÇnöÌØÍ~ÿì'›Y¥Ò™z3(kóLíà·¶áò~‹Ÿó[Jz˜ßœ$\œ™ßüøÍßìLêÝ6à1Ls¦è’o:AR¿$¨âŒd›ÂÃqé)ÝQÔI¯¼¯ÂxCØÍ avëM’{»Óa3ýƒÓËF‰QI{žbç%P‰czF·­Møœ©ì´:$ÛI½ô¼;?ƒŸ™zS®Lc`^¡žf¶nVÒáàá£ÀÊÝY» ƒei&À&¹µ] ¬M„n>ÀÒŒ™æH™ j9†w E’ùIÔ¦¾ ̦ªsi[Éf«º/|AäP.oݼ•}ï‰4Æ):^5My]¹G¦Ö£úZOcŸÚD¾Äw(;P›^ÊÍÌ@;¨!^úTi˜¹Hç ±(qgá™Ëí{S!…÷yUÙ'ÿ+ê±}sš¤™À_®ÛÚ´dŽã´+¤Þ¬j´ÂBæֵ}Ub¹¡+‹¸þ?|Á×zQ8X–wøØÍKˆìyQã—:níC éÔÕW˜ulr‹lâ‰Çkn/}àožu”•7—óÜ~¾…ªÔÖP +~8´Ô®çHC­Tïsð]ïs´õ9c{d¾óhL˜s¥§9X2}–`£¸:|4Ù‘GcêÈ-ˆ³œñN•YvìáØS1¡?ë™°ûpÌc‚µºà7 þ„‹Ü#yü ÕGÊ>ÛvHÞÖñ3£rkÓW r@Î ÛÕê.û åXE IyfZŸRÈCÀ[ÄrÀÿzb¥ÇkocÛçϤNâœê´%Yà¤LŒG ïëb“yæB‘°ø‡F2›“ûû†ý_@¬ë@¿¯W×ùuY•ƃ²Îw7!•$Ù‘*ú[jhÀ7X:ª?JÃÑqàtIV^8Îìé†~«ë6/Íј‰]äx³ªª• .›—.êâ ¤òضTëZ ÏÐÓžú„Íѽ>é)Bû›}ŽhžŠ (·â¤nŸÔ;³WÚÔ"‰- üG*Øï'¶D8°î”&»ç ðã± œ´×]Fö,ãõ`èzñåû‹Ÿ.¨;qg,#Ü:“Êž-.¾ý>‰æðRK"”ŽÌÔLå„j ɪèßÿ²?Aõ[Â7Ðé~ú6Ôa€¨™é¼i×bò nhü*¸¬uÁÀª³*ã³ÔEõ8ºø U‘?Ž&>KET‡»JùiµðÇì*eâ´H‰Ä£ˆÓîŒè{[I¥ƒ|Ã6 *¶OGKù,uTžì/±Ô©ù>Ñ}HϤ£çhIÿ:ŠlÅfQSöÝËb‘¾Éà÷§æÏ23W[v¿IaŸåUU8ü×ÔÙ‹òöΆÿâfÏò¥KÏ…&J ¿PëŠÚ6CÂ6“@ÕÂÓM0äHEÓ– [7)S½ZtÕvWkŸçmîzdQ0áBš$¨¯Dv½ìšÐxÊÒNaÓøÃ›×vp³ªöt#uõ|”mcëÆÍÇ>¼¾½›pzüW°,cLËÀ:0­ã›âÁîó:¿­óû»ÆÞ;:¸TÐ>3…sTy}[˜K¸)—Í}iþ €hh£¶[ã›òÇÒ•ÙçeÞ-w[tÓò6T1Ÿͬ.xbÀHá £Ž;9uQT}ÙÁ;Ó§ÈÆíolãµîÚöþå‹Å’< ®ˆ&YÕ·/ðîŇ7 ¯Gm#éÌ$ÑÒ3Íd2U"1ˆöFÚübp¸GĸøÐKw€$¿Éë×÷vü:_Þ®R]QW™Ü¯¹½,“+7Ù޹ÕDõ-Tþ—¦} öÀ©ßZD5È$F4j-rîM‚Xõÿêäí| endstream endobj 642 0 obj << /Length 2904 /Filter /FlateDecode >> stream xÚ­ZÝoã6Ï_aø¥ Z3")RÔ"Y`Û»-Z\»Ý<Ð8ÆV]eÙ'É›Í3R–ZùÚ›_þf8œ/)ÝÌÒÙÏ'©ÿÿñòäì#W3ÎY¡”˜]^Ïx*˜1Ù,O9ã™™]®f¿'í®.»Ó…TEr½i©Q6ËÍéB˜dU574´Â ]$ÿþíÔ8mKAXpºúR­J °òãÄÙw>û(ó±ì„£@Hû×nK …œ ¦`įó|<¢&™Ð:,Zžª4Ù4}Ùô1Š2g©æañN. i?ÏÝmEò9]dFHìÜc'÷‚/ifUu=í®ênËU˜k5œ\Iƒv»­«¥í« H©¡±Í5ýwÕz[{zÝ=‰Î.{@à†œ^±Ø!þ\6ekëúþÔ`g!S•t} xà\DQ âôÔZnÚïPJò’wí²¤-µ=7¨Ø¿«PLjœ”dc[@žú?q(ðîGøyìL4ãj8’ï&Ž`!…†;幆C–þ¢LÆT&Ãïa¸™TÉç H¤ŒG…[îw‚l;&9;$mIfÓÓ\óÁ,‡;foÞ!ª“¿_žüïe‘Îø`b´LˆÙr}òûŸéls LfvçV®ÝJ-ñÔ³Ï'ÿ"{% Œ³")â-fE–1°Wœ£îr+¡„ØvRÆÆÒ_#×)¿Z§¢PJcX{¼å˜SÉR#gš,•“DÒ™`…)‘È àO˜·P¤+2>Mv¦Š›§š‰¤Â“Zyí'1¿,ÄýK·Ž¡çÌèbš„ai>…oFQ- cÂ[Ö½U=þ…;?¯ŠgàéÓrWEö#ór?{Rð/Û8n1ü-šûÁR =M¯+Ñ „6"› £m’{~þ´&b¶¡xÛà:jÝUh˜§öÝ(¤~? Z•çf þ¶\y?%a%ÜïC? S ©Ä°ioobÛrðz{OnÈäEryjxbÑeyR_c +.âHÛ–%5ÿH¹rÊüÙ´Ý»ÓE.9Œpøáôd×Û¶_ôMœ.ÙÍÑÃÉAòýát%Ä%›&*5¥àMXŠûAH¢8ÇÓYx)Œéä¡À‰”2 aQ( îô(–8›‚º«x1†BP !AaÖÛÞ…i‹².C NSÏ„ÃuÆt>œÖy‘ô„Ò!ÓYrf@aD>†Ñ†Êà†E´biÍ”| / r×[Šu„ºª``ÃF!¼Ë 8¸Ÿ8p7Æ]QìXút$ŒBк¢6Ý5÷àÁS #Ê>d7Ãbôq¢ö÷`¡2‘`º„ÿhT  îüh‘-µ®ñŸãwý#LJS@DÊS¸5—®:²ãpÕ÷bpdîð§2‘›"øÜx‘`›’*7ˆü¡Â8MϓꚆmC9…å8ã"?œòô äöÈa軎†ÆQ! ‡GÃfû,:°vÅkÑ2(O$b0#[Ö;JBqnCú ¤NFtl¤û×;øØðæÚˆò¶ª}wL(š®üâNÏ'E*SãÖõƈH€è4 +@Æ}8âb¸ðÕ:j_Xþ|Xtk;Ùp*ÍW3z¸²¶‡´àj×C¦KYsØá0Á|d7À½ŠD×."5S_ñÀ:àðX[Gí7,SƒwY*ö …ú§Fž\Ì×vµiËþ»½™Ó ìu1ÿ¸©«›fCVï7ZóÍ_ÝÓè'»½µe=ÛD©43\ìýÞñðCã7ËÁ¶*Ÿ—¸>á®vvjHc£œÂ™jnö^­/·„´Ù­¯Êöb.çïFJÞ'hºßP÷GþŠò³älÝàöÉŸÓjL ».Çùåh ô Ø#U£‘ʧ¢p™E™år¨—'QykVìÅ=÷™iHª= A¸%[cÅà¹Ò¢ËAýå“¡Õ<œ5,È l-„’ɶ¥ZÀµÚ$W;°9Îb%Ð÷à²uõµß¡„qlMåªUYÓdåiYšv™/ö!bÊjÿ̾l†3¡ˆƒ3ÿtµµ{zÈE‚5Ï™RÅ!趬m_¹ø«Dç%² +2¶ºq4úëMëÔÔ¶¼¢ïO ù)Æá´]C¥Äa”;Ž öaUâ¦ô£áéUÃoE;xD_b¬àj…ÍPqŒXg§‚)ø% ?ö–µí:j†àôI% í¥îJ&iòºïÞO lQ4Eß¾³Y–áqW+I}9 ÈNߣ[q4G‡‡ý»ª®c€o÷±®+Kåîx “ül×kßÄòœ»D)Ò-èݨs½ÙµÔr|–u¶õη<™m‹e»­«änÚ@Œ*x8OõNº1x²•òƒtÞ…NZKµ¸áŒ€:f5ûã+´ßC‡â›NÖ¸APvè/m3¬ð­¡D‰ŽN¿\¢~d(eÜq×Ñ S>ôÇcäjT2¢úUµË‰ÊÞj>]ŒáfÎoszyPºÒ†q>E`Bš7§i°@‡ùÿà¾ÿ…ªW(æ.R»’`– õ~ÎÇ%™‚ëϲ·”^LÂIKˆ™‚`r4L/rà_%ÉD¨ÜðØ ÐÀùSuÍò\M€~!‰£ $æ*€ÇA‹B°,ªÎ¤‹âé:ÑÁ–ç]ÙS§5Õêbþ†>áŸO”^…(*“1êVrBæé 'ëdàºrñ`¿ó»¼æ^ò^ÇþßÈzÎI ×v]Õ÷ó4¯ßWÍ?nkˆî.æŒû~ŽëÅØ£’Ê3©$äÙ„¤rÉd^¼­š¤5Þs³í«uÕ•Ìs_vžý-HæbQ¾ï+iNéÒ«GE¤GpÕ„ˆô3v|–67Œú£µ¼œ³Ì 5µÇ•€ãuÙ»Šö©@ƒïLÜaˆ’JFB@Ø ¼0<¨wp**HyûîÊ}²C圡zÎùRCe÷“v‰•‡«Öpü¨¨Ç¯†™ÉåmåGp@rñœŠáŽ ÑßÚv+ôÕrW[¬ëh¶ÉK¡êǯ;dÙ+™o"E-°ÖéËFб]ç?(\ÝÈay '«žúøúíX©QdœI3÷yÚÓoçD˱þ%¢}ðåXó5> ê]¤*“îÓað}W³²ý¦uœ£¬…$YG‹£Syö|½ã"›Ò;Üßš0û+€Î,"õ¾}¾lœ¡ÿáXeYêß»…%`øþ«¹õ endstream endobj 647 0 obj << /Length 2535 /Filter /FlateDecode >> stream xÚ­ZKoÜH¾ûW4|’éJ½U ’f<°;ìf|Y$s»e·°z8’:Žç×/Y,©Õmµì¶sq׃UE²XäGÊ|q³à‹g<üþãòìÕ{aB°Ä¹¸¼^.™szsÁ„v‹ËõâKô• Ý´ÝÅRñ8Ê[üuQ·É.þºüç«÷JŽ70†©ØÂö~å›»,¿Ùtí¯Dº–I×¢']ÕåíÅRÆQ]eÕüv¿ÀABD×uQÔ8pw!]”­éø+¹'–¿ïØŸäHhÄ2KyÕviµÊ&y²@›èã<µ W-–Jjk»X Í4üzòËi•©SOÒˆåŒ+{üt7áÑ:C« /"þ"üxçUBK2š«¯Ã’¼íšüjÛåuÕ¯JÃv+\¶I›tÕeÍ’ÄsÀ²=.ÿOÔRÓ‰Zšèû…1QÚä)í‹Cx"Ò4iGä@°ºQS·¡Ûæ0Ã.–±L¢ßhØ[5Y—ÑÒiY¦Ô¼-¶aUî50nÃsËøÄ`7Ûm[›¬Éà@ Â^z#ªiü„.áØ&¬hQw`b«¾¾ÇA Âöî)QD¯aGn‚2`ú&°mÒþ&L+´agÃÍ9Ý6u¸é&ÜÌú»s#Éu/¹ó–$;P<¡À±,oh:¯ò.O êꊭ7è§M8¼ÍÂnáIMp¼móê­E÷ÖfÀ:›&k{]iGJ"óÔAÚñ­ß㦿rÃ'_O3™¸þQ¤Åí&}{Ι8ŸzA±d Ê@ gOl¹T6a¼ iˆø6¯¾ãÆzrc+4xï`d¿mý *GÿÞàÕÜúºÆF+¸*ߨo»¼ÌÛŒz À¾9¶?ì·5ý¦¡ß…~™þÈK¸XÜÃ?ObfïŠè^´‰ŠüÞù¦¦Ëñ×4ëJ›ž\Gw›º+o7ÞŠú&«²._ÑhÖg-8zOÚ1®³š‘Zï³vR­B ÆÅi÷eN&qü^59¼;©¼¿^ÊDö!ÆEwÞŒq(Äw$¦pËŒqOŽ)œË™˜‚'ŠÁ­ÓËD3“$—,÷Þ•Z«"m[|CØù²Í â»õRòcQIXËÔN„|=©;ìÙ]Ïîãiy8Ý+µJ¸À´«›{0¡§ïÇQÎ-"ì]\ãR8 Ú9s[åß¶~ÏðÐC±6Ôób{EôGMÅ!¨á*Pnh\÷Sa`pŠØAcn²âá4šé55x%cÆå`ð¸/ûŽmJ‘Ëžz?ô ¥sµ%x¥­#¯Œ ”'þΚv&!»Å¹)Œ´Ä¼§@=Ñ ÊÑõ+!ª5kjæÍû@7vþÁ/f?Òò¶,*iá‘è Ðt}¸©¨sÀ Ñ"÷D™ÑÀd§)a+àÿÍÈɈ—ˆá½XÉÇÔoER‹8 gCøÆ‡DÁ?îãsŒÞ¶£–Ç({Sä¹GžGÇžÈÓ°Á:¼’;nw›‘EO°:Dï¡…ð6Dxkz¬„ÍtE@ Û(!Ž5b_u0î 6ª‹}§¬I±;º:ù;€ß«m^¬ÃÐ&ÐÀuúz75vÊÀW§ !Ý;Æ&‚NäÓŸÀTÐP1ð ·…Ñó_ò5hâY|MjBA܉C"¯f4¡žp¢˜y9ü^,€ÑNŸ¸Ó[ªáE¿=ÿø¯ÿ:†º¶¬¨ýâÑDUŸ¿šSÚé"LjLŽÐ3“?KcòÉ}}¸ü|¨Ÿ¦!ü;«ùsÔ#FÜšõväÚΰž»'<­ñ™o^ßÖœÀ§r0% S¿È?‹!´tfÖ™+ç˜Ñj?´æAÛ‰ršI+ú’¾Ù€ùÍnžpæô#•+_jÙ~½ C)ýy¨d¥q@2ÎDÛ€´Xça"Œ0×û€) §ðj áŸ®„$0tñÑg/8‘Þ¤yx˨PTÓ¾rpEMkp0+²r—¼áˆѰG¨Áˆ—hN?€ÉXÝò _šcEÕn#OÌ6­Ï-hq9YÅ\ÆŠGïR*þõ%¶Þó`o—³a~:˜¤«™ý”éeŸÁMˆ9ãIüHÚ0i'n}]7”¾‡£š,m©ú¨zˆ£”¤`ë*õê2lP_QÞPSmQFí¦nº"dËXê>g^,mÌô¡…5ð Ûó/0 ½‚ö)÷ñ¯ÄÁØõ¶Z¡!÷$MÀÎ{‰ÄzÈü_âýùƒæ&8†ÏÎ_ü€˜ $TÔ§LTñ€Ô£Ê~`¦ xÿ«Pdi²u¬ãœH$¨· <¬I»_B*/6ÈRV]íË[!Ãðg{ËZYÝå뙤éºÉÀ†ªUN¥ ‘+e@dŠíÎYÁ*\z¤ÄŽ•m=ç¨F%ŠP¢±ƒô²/¹Œó,zPÁÈ·ýÛ•d¼2frˆ¯˜DÌ%Rȳ)Œ‚À“(Ø ëNÁÏ¿ûÉ_~ÕäÛ’ ÃH¹ÉŒuþëÆéü< ¡2†à@â!ôä-Ž‚ ‚ ÷h.VÊ„Ž_’Ëœ¼Åqž!%í¿Äͤ2ÒF2¢4’GñÖøÈá9í)Ó{™K`žÇͤøzÇËLþ"5xjí^7 9Çß‹YœýHã¿?øê"’|N÷'P=ø(FêkÄRûª?l¿+§a©>G%`¢5oBtub6ß”öñúsLЍîÜ㵡æì½®¥ÃæÀ¼ ±*D%³Gï÷ÿðš• endstream endobj 651 0 obj << /Length 2458 /Filter /FlateDecode >> stream xÚÝZYoÜF~ׯ ôD;möÉî¬`“µk ëè-É5ÓÒà ’c[ÿ>U]ÍK¢F‡•E°O}²Ž¯Žî®™,¹J²ä‡“,¶œph³„'<ÌZ•ägRåÉzwòëïY²ÅŸ’ŒIg“Ïaë.á¶ðúUòËÉO¾;?yõNZ Á\æxr~™í˜.1Î1 ÔÎ7ɯé‡òKwhüÙJ îê¯Î~?ÿéäíùD ©2Æùs¤˜ª"Yf%0·ŒkwŒH–欻CB9΄°O'°"ÑÌå¹A(lÎôŒ“Lñˆ¿«ø(4¨v8ÊѰ<×G„~"‰û…¶’ÙÌ’ÐâˆÐöùᙆ|ÎðõuÑteWÖ{_ù¹M¹ysú3LóS_–•gûbçßœ²Wûúòåšu_º¸¼)º‚u7×°¼ïN¿½«Á€ÙÓ5X,ŸÈ/–s†_eç˜R÷cÆs–‹[<_ï(ÈFβíÞœ~äÿ áGÑwdßQ}GŸ¾:ѳd^DÉ(&H^u##7öe09އЇ¡…Ž:Çz–Ä‹iÅ´‹ë#iÁô ¹Ñ”å} ½ë!y×C²0óHÏy#¥ ñ*ØÁH=ÌðQ¹iÊïõ«Yr:¦ï“Ù/*+sfy òüˆ²R³Üê¯:>žOb”B°Ü™¯:yŸO¢¿Ê íŽ^"¤µL+9¿Êp AÁœÖ"˜_dLÁ“i–eœ,p¾õhp1Ý+$3¯$ ç×·ôÁœ¸ÓºuÿÁºÞ]Ÿ­DžÂû3h;98ÅüoW{ßÒ° &P_ŸñôPÍd ÒÙFB ¹'+n”iJbû¶ƒìÉÓĺnßö*l"±®ÆVŽdZÿÇÁï×q„ªUM€a&׺¨*¿YÂYÂ] z¶É±¿„±É™É‡Í “Ô&ý¼è@Ì-³ǶØcËÓ¢*¯Ùý¨®Ö—´ s6E¦uWn<­õJµ´å·Lg­kݲ·¬8Ür¹Ps­‡+Ë¢.’÷º]×”‡Ø(—¥ŸÎ´Éà-p7>[9üGåB0i.»›îýÔ‚ŸŽÛ‹&rl«»NÛâ"G´‚Ï ãXžås-ïDpx.觤Es$€«mú¶X£Í¶‹XdÜ= mÚ¨®É!*—Õ¹4ž¡K%¼yœ­Ú¬9 ÈÛû‡¦e²8襥 ½¢;0ÇýZ:!c’DXfÝÀ®ÊOH|ÚR#Ÿ÷ÿ¦–âÁ!ì,ˆ¼ÈÛà¸Öm‹ŽzÛ‰}ÂÅHç"ØÊû= û4·‰¹Jh&µžûMüä²n‚"íÝ™i På¾í ˆBˆrÕK¬$I¦éU¾e~¸´Ù'YŸËÁáé›–xw€A»Ä—’[¯1Ž×UѶ>~0ˆ²,ú±"áTì¥mËÎ7EçÛEYsÐ,sGƒ#W:äò[ÙŒƒ‡í¯âÄ%µ¤• ‘ôÍêov´\î‡ý-¥ô•ƒ‹wvK·à}+¥²t)Œ„AAMUÇŶ ‡vË8UÆ­›²ñ뮺¡Qã+À`C 0¹ëÎØ à€BuY.`m+2xÙjw+¯Rà*1\̃M8YðôÈûxWbï³Ïh<žZaXÐ Udz.OãgtOPÑ0,Ä#ᛥšBs+}O{Orxfáu à9L¯ðX’“ââ™0&™ìz³ÄcŒ sÙÉé|™™èã‚@–9¾$ÏœŒb9z͸ëŸg+·¨ ¹ —{>ÍwK4!k±DsŽÒ”SšWKè†çúøÂX “³ñÚþ83Šû̘?ÎŒö…Í(þ—f”Ï7£¸ÏŒâ…Ìø ÕLù•v|8ó'ÙQ>ó¿c8>ÎŽö…ÃQýͲªú ÂQüfÏϪ+i±tjnÝK†»×Œ¤€«ïø*œMõ²M3-cS%ô ÛTÿÿÛt–¯XÜ™P1©L¬ŠqÉœµø`aÆÄ‚«eDäB§¿ø® T—eéášÚᆆôЙÔ+Ã&¸¹IŽ7·–&èÞœH\gÅAi…ÿy{[o>üçø&×±ö‹¢-×í²»F:ºý›·0Ó«cKE¿Bµ\,äâ›gàMë?i%ÉX 6TK í6~Xì‹ê¦-#=¼ rðŠïu7Sœ …Å¥÷íûýÆû FMÛz‡šš,½ôŠÞÒ(Ôz õáîZW Rš Š`çÊïý*–€ý«jM+XõìŠõ|-x óà†PÇX’êš #±J°nj¼üc¹µ±Ú©r“~˜,ï«Oøº¥Ýðýºî Qàë'/±€„PB£‚šê+ªMYt%wö(»‚™È~xjdKo x{Í-.3›nj¤Á£é%U×éÕA¢ÝÕhwœÅG0m•ê knTfó_°ŒƒÅ—ÛãsxZУ‰¼jäA„óÍï¾`Œ´Áþ ttœ o…N»….zwƒ9p¾"m×% '`‹`,ú¨ßHUÜ‹ bKŽ [Úb¹Áwõ®\/Ýø+rËÓC{(*Œi³±ÖžY8Ó–»2üN‚{øžÚÄXŠ®¤MÿÕÒ–bØÙWøT§ú@ k“òç¢CL*ãÒ˜KfÌZa0s˜Ø{GBZƨǙXü¤‡ðÙ€8l=ä`LûÆ1ŒÆ”¸ 欰 Eø•¤òÔ >„’Áj»­Õ†æG™`Ð;nº@:74§lˆ““ìŒÃi™ŽÒäc}ûùþ¯¢›CÀkªBà4#_Wž¦âoX´ð¹ì¶³×³ôˆ Ì™]AƒÖwÔAË›H’ªep VÇRõTR}LzܺJ¸µLqØïðÏNý½ÜÌ6½=?ù]JP endstream endobj 657 0 obj << /Length 2480 /Filter /FlateDecode >> stream xÚ½ZÝsÛ¸÷_¡ñ5a|¼qúNïš_ïšóL;“ä‘h‹S‰tE:Nþûî DJEQº{"Bû…ÝÅoW¤“§ ütEÃóW žtÂ&Œrb­œʈf2[]}üL'sxùó„ÛɫۺšAbüÙròûÕ¿®Þ=\Ýþ(, 1…õ‡Ç “œ(Î&:މšóÉÇèᵘÞ(®¢2­J?*ýóË:Ég ?^¦ùSµ>QE‹<õ“çtɺʪ¬Èý4]¦«4¯`/›~~øùêï µ¤2D1{ºZMËB­m,a*î#A'œÄ6Þ#!cF8·§“pÆå|¢HlŒFÛZC8Œt,ˆdÆ›¶Cï­Ð 7A/GMŒQ=BŸHâ°ÐV‡á„æ=B[Nx,ú9ƽí°R §ºÒ!”ç®{Ô•šÊÏJS§’8,´°à4!·š¡ÅŽƒÎ¨Éðns½áŶuÑß`™]ûùc¶LIž¬Ò·×ä6™-ÓlÆHõ­ ïçI•êû3¼Ï«Þ”vº ã lŸ&:–— é&Ï»Uö­zY§[“-³²z{ý½ñÓ¼ˆz ëêýQ2wZ‰Å„±„â+†ÔêËX©Éó•îk+õú­4Jæ¶•Ñ´§1 ¶lh•莃¢¯Áðî¶}} ŸÎ¾[[¸4@dÖä(gçeÈSI”ZÅœ¡ƒÔ=HNÅX9¤ǾÉ{R$“"G¨Ði2Û4YæS–CÅE¢¿ÅôÌ‘ãdî4“„ñ€RY:T†Ò¾ 4n1=˜$këôúÍ4JæN3 UPØ‘›~EÆ`ôb]ú…âÑÉOۇ欅[¨¬Ý66q†QòüìÕ:ßñ/ÝÑÆQZVÙ*©cX^ èß—Å“WþûԲȡŠ^q%¨û¶Y‘\ù2C‹.i[J N£ÄÇ7ÝjÿC§@΋7.rÏ ›=I>ï"Ä9TYlCˆÌ÷BÍ…ˆþ½À£…”¥ßÌDYžåO~%D!?Á¤L„ 2NœÓÕ¶m% ¼.á%QÛt·;îʼn&”oÒÇ~x`l¤›Y…O‰~â4q'Ä„÷¡®#‘†HaŽž U›3ÉÊÀ¤,}\Ì2ïvÈÇåò>1$R¶91מèât# ,»“Ò^€Ï»¨ J¬´Gü@iMKxE;„‡ÅƒÂÃé2Ù¾“HcTÜð8Euôb Gé:Ê1ª¿M”{æË¥…äâ'Û°öž†è“îxZ™‚ÁÌ xs@Z ̯[`À9¼j‚o[ïÛ¦íÛºåÛıØ«@«VžýgQ=IUÈM8Jüã)óÙ!÷Óyœ¶’1.Ì’ð¦ÈQz-|ï©Ôï:OŸþ¡Û‹µÝ®ït. f7L·ý]H~‹îž†gV¹do¢1™:#S¾!€‡LCBÆÝaVÏË0qf±Î,8 G¼,üqxꥺË_§ ¢l™ùdº b=pÒœéý“ˆIEœ[Äí`,§ˆA<™ÐÿyŸEÞ¾V©oÔ=9·?N—c €,fç@á“Iì¿ >ýÏLhîþ[;£Š8™Äa¡á ­dGÿ3jÇ!•^‹áŸÚŒ¡B§ÅdCžF‹o4¾H¡Åól´Œ“¹ÓJÊ/!Žþ 'X—±Q“ã˜VôÀ.ˉ;-¥˜æêè_u‚å7(îšì†·XNæÞ©*ƒQÙ£Ó D^\Ÿ•Ç“ØJ!À=çRObsM Gy™þ ·púuy ÀeÀcí‡ß­ç%Ä€´±¿½b•æ¶>úg³êÄùJ¥|M‡«€&¿dóyšø±\F¿æ©ß±N“Ò÷—6Pb@V†JÕ˜#¼ÁÉí:›L ™‡¨~£C“0j‰ s'2<ÓùÓÔYœlå…IY¬ð  å´¬_c}/iì®äE~Ó*hCeóJ3,_“/ˆÚxL} kúeé°¦ËHJÞàÔî¿÷­,¦Ñ2T–Ï*¿î?c‘«¯á}³Àù¶â‡MmŒ+•ïºìVâ%ܤ¾¯°Ìþë¶/³…*ˆæ¾tr;>†¦ú¦ëúàÀu}"ï6|>‡¶Æ»—Ð×XeµtM§»ÄB~ ô^ßÅ)Š-•fkÝ(jͦâÚÕkCIRéÏð0–8¥_j¸¸âô·QøIâsð_Vˆ†¼ úè§µ‰þVä%œþÚïñ ?ܲ…>Æ2øÐCÐ ‡èÁì,æ„k{ÌÎb¨:µƒÙO—c?½2Ãóœìz*…ƒ÷³’qü+7f±3¤Î¹—N&qXhüЊÇG;38A-†*b¡B§ÅtCÄÎ46 /óEX‹ç)ˆ½{Ž“°Ó&JÆÙQ|ÎðC-{™*¦Åó8Bßàñ#6%a§M0u1q‘39€ã Èj2ŽÉGðïTWX÷Íò1TÎð#.vÖ7¾gØJ!Ô0gÝãIl.båëSPy ‘:Ð9¶#ñüغþÔL˜°‚ù?]_ÊÄ endstream endobj 663 0 obj << /Length 2384 /Filter /FlateDecode >> stream xÚµZMsã6½ûW°t’*Œï”½‡­ÍnÍV¶’ÌøªL´DÛ¬¢H­HÛã¿ ”È1I4÷b‚€×ýÐèÆÉc‚“]aÿüûÝÕõ?‰HAFšÜ=$„bÄ9K&ˆpÜ­“?矚Œ :Ïkûdó§l—ùšÍv±¤j^Õu~_dîç¦r?6YQ¸RºMwûñ~—– 2_- ×“«*²ò±yª}Órí õó}ÝäÍs“W¥«Ù¥MV£Å_wÿN–D!! <9˜+™_ž÷£R9ßT­eëÌÚ…Öx¨¯›]U>oî­¬Êe¾ÎJ۱ɿbÂSçüæLBc~¨Z§¡]Y5®~—ÙËBhÙöw¶…Lûd]ÀÊŽä Ù·t³-üËcþ² zžùFé½ãÔŽùbÿd?„z×é¦-ÉùWŒ1ÿá“«n]Öó5ðÛz U_±À9ÊÐbÉ©y?`§›MzœÓú)u3l›k:‡‰„®M¶s¯Ž"[¿«|$ìü„Aeõàžyé\±LírO–û ì#~¨í¶È³Ú½´!dŸO·±}^--œ„ Ê[4k>S³ñÓ 1³”œ¹06ÂE‚‘óïCªZ\hò\wW·¸P±Î!*Ë•ê@¿éGœÈ˺ÉÒu7d^>úAÁ«€ÉUQ´“þêZB„ýñŸ_\aå§6ûÉö¼úùîê¿WÀ I¦HkžHB‘02Ym®þü 'kø03:ym›n`¥k„‹äËÕïn`F@b7J%’œÀ`)Lew¯/¨8xF@OÖï©ÀÁaì¶‹cÆ·"ÀÀBuí>¹7UKÛ;ߘbà€á[Ÿ†°f‰Äq¬ccà„"£Í»!¸!ˆR}ù-Ô&¥¤u_+D¡$1GRú™'¡I팦HÑQD‰”£/â¨ÑÂ@•TÎhzÜha2ŒÇ5’ÆD‚%`’!æMÃÞcÏ6ùúvöª>Û*2ûÛ{“:Æ™$AKÄ„?Y„}"‰,E²¢ßÞ¼fùãSþØÚ[þ‹r—ß“™ãä!ÝäÅÛí¬ÝÙÈË_ŸÛ§ôv†ºv_ ã¾.·>H–‚§ô¶óY°{h~"F ²Ìœæ«Ym›|“×òî¿eµ÷ ÔÜÎ@îø÷}K÷ƒm‹§Q)’=sE„"yâYñÔ¼¹öóõrä £¢‡+#Ž (§¨•°Ÿöµycä´\e‡Íãs·ò2oÐKZfˆ:†’Q)apŒ âÌÓJ˜D˜˜i(éc†(Jð)JF¤„êöRÖšg"”€vã„LCI3D %£ R ÎÀU{– “O8 ‘Hc6 '}Ð'| '£ râ”R¯”HDS ¬1Ü`;yÖ½¹Þ볘ǣàÃS¸søK ‰ R ç<ýˆˆ¾t„£6s¢Jø…E"úÑ"+J&ÑШˆ¦1Ñ3Τ š#»õ†\ŸyŽê WÑtR=Âú [JÀùÄ=[È•½êM¢¢˜ÿ/=ÊÞ C²ÏPD\ryñ¬pêž#¢/ú)ú~F#ð¤t’so:÷ä¬[H|ã, ’âsÿD4#Ð|Rú !RÔ(RFY$… +þæC"ª‘3DNCJ4DŠ‘rJI³0H PêAQœÂaa¦¹oõ1C”˜Qq2ÊÀ % ?%õŠFT#„%zš ×4x-Ç#¤ô8 ƒ¤€DÅÄïx4",9æÈh2‰”€ž'¥ÇÁ‡=Æ¥þ«ÈRQ¬>¢¥/â¨ÕÌ`8TýÅFd$Óg@FÏ}?IÄ›m÷/(ûï¦CøþÕûϱy‘¡2Ý@ü¢ëòyUdùŠ æ[ã_§MŠš·-ü^61­4Â… eºOYDK2¥‘0z’õ>½Ùäßšç]và¬ímýîõ3í ¬+ð® ¢;À8›ƒ4)ØmöGEDP2©‘™fW`cé—Ž¥h!ÎÒ“ƒ$IjÅß©hD2qñ¬Õ×¼¹,¿˜ÃýÑ.'‚꘷Q"?´E^:Äq«9G²;É"2ñ3Ïš£`lƒ¤‘ ’ŽÚ /÷ H;ØÏ"‘1Ú®‘IV~óèö(»=PuÝLW q…4Îæ Kî„Ì+8‘ŒNóñuxtsìNŽh!Nâ[,#p;¤]E$#l‚%×G»`[$þÁ0ˆá?ÿ²˜l´¦Rñ¡=qü+¨\ù‘ Ñ%êØ!0‹*9+öÿ>S‡†Rõ(h+*ýÂ8$C¸Ô›avŸä°”D—zc“·\~Î`\J–ûF‡çtyTÚ<%›JWú·AòVûó>‰Ê¾í“¨ìK/‰Ê&­9ÿ9=ä º<5iVÜ'Oy1`sÍ(Ñ6·ÊænÙâ ‹Ó¦˜½ùf•{V¥oÜëï £¡b¿ªÜk?ÁÌÕØ\» ¡"Šž¥þ Ä©’ˆ3zb’– Hš3Èú§gph†4e‡-AÚÌB6OÛÌ3ÝežlyØØ Aãrâà “¶-Rëð[W“Ì`Î÷ }P¹M¸¶–µ{k3a´ÍÖk2÷²OÜçî-½agÒÕ®ª»¤Í¼Ký—TÍ—­K¨à°šüÍU#¹XÛ¼KSî‹tUÖ‡Î> 3D;鲋 3"!¶9èr#;Þ¶Oo›"4 ÷ô®*›ˈ±rÏà”,aºX?0äWg²Ëõë²uÁ(>Xÿ âD@GŒ”¡Ý”úo½NÃMƒ ½·°zn¶Ï ²ìvfÿZ6 YIÀ5vp V¦l~×fgJ3ߤyéJnHW¶[@ÑftJ ðüíÉE™·ó5i™ou^ûÅí‘¡ðš·™Ä÷ûdT›ˆ æW‡HÉ}*bçÙûà N.¤¥„­”!ÿê Ç!±í˜ÂÕDݎź¯8ûPùv,&Â5päq5Äm@…æ‘©‚Íé@Izš=fÈ:‰$%;‹=û9˜H2 .“H :Ä­›´©Cô1Xjò°ú ͦOÃJÆv%8å;I¤­Àÿ&N¼Ê endstream endobj 670 0 obj << /Length 2199 /Filter /FlateDecode >> stream xÚµXK“Û¸¾Ï¯PéÄ©ZÁHð‘ª9Ä›}e½yxT•ƒã†„FˆùÐ`쩚Ÿn4(‰2gâLì âÑÝh|ýuƒñê~¯~ºŠ/Þ¯·W¯~LÒ笔R¬¶»1Kx¹ÊcÎxZ¬¶õê]ôϘç×ï·>.„Ub¶Š³"?û®ïuƒ:ܬ»AS)§í¼ú‘ËÙº”³´”ÓJv½I½;šótÎ'OC à£Oòs."miNÛš<äÎ`éíQ]ư/+X€'†ßª~´=T»Ú ÔïiNÓß7æª×Ù÷GLçQmA§YÊ‘ 'Ž3‡&ˆ¶NÝOúûõ¡^´7žßr" I`ß<•ž‚ÇzPÆÑvo,¥Q8ÍŸúF«wcC}>±³í;ãz7?@^„Ðr›·Ô &ž[6ùÐ; 5,…ïǽLÍÁTk½ ìlÔp¯if­œ¢N«Ý7÷»AuÕž›¹›µz­”êÍÛíãíÏ€Ë/CdžÑ÷ª©Æà…´Ë£:‘tĤ‡ÒO°#L8 n“á¤Gr’HËpÐ;=þ=Ô,õÈ!ÇÈ8zœ€–è l¼ýé d 9sô¼ÿeÀToÞ^<Ú’ÌçDdŸ‰ 5Dð¾ýù¿ÊHã%`:ž†Ço\~µ Û>óáð zœ°¨Ð!àoÀe™ 69‡vÊ:=ШçKè ¥éËíUÆ÷¡ëî,ž{çóvœ‰Üá!¼&å]½dãhGÕ4´K X÷oS£ 42£ êÓçÉÐhi ÂûjVƒ¸;ugã ÍÁ1$ ³â3úÊ‘¾6KVà²8Òµç#lo•£M”0w§¡£¦AdM«ÃÌ?vÆš–öx-e¤‚P$6žÌ“HÄœS14Ú~Rwô¢Èî;dU"ó"z %yÕz§€Ñ|àá·ò  ³£w×Ó{~ž–N”V‰ —…wÈàØØêú;dçlBdñ"ÇÃ6âXn‚[Mý㉠æåÅ)Ê}ßQyŒàü?°ãKÈñ÷ÑhG‰ú .,2Ÿgç2ÇšÍMgy?MGo/—šm@»¦OŸ&–ª¡¢`é…]ËÕª”,É.MÚ†4 N,¡J/ÊQÌkªEËPL$‘â¨ë F«©éQ$ätJ,5€õ: – t¦Ä,8*ÊÙ9K2ÒŸ–®uÁWJàëì·×Ø$bñ}Su)ÉL›ê9ì ¦ç§{¬£!Ûz1Ÿ.,Ø]L† fãK˜â¢„)¢z© ±À:@»ï¢Ç¹«ÕNÆ} `ùKòù1Óy°j¯«ÏB—x9Ëãyîi$Mã@#â<ÍŠP½`ÿgÕKšrd6 EŒ_ŽE åô fî7’™Í"è9€³CÀ4‰Â$ê Éà «¡S‡ÐÕÓ»BräéÐN3}Ù -»×¯hÔÍxЊ f»XÌõTê4œê¨¸5õ~4j!¦ 1,ëjœÊLA;Uâ ùØ]C&2N_ÈnĦjûÑÃÕ—ô ú2ü §ó(ás DŒþ\F·Ú¹§®YîèÙ2z S,à¦ÌX’¯[öƒ9XRê|¥ cÀOHï}Ôÿâή©6Ït£Ð•ÁCö5ÓTŸãœS ŒÒ…|A[‰À±x¥Vn*yðóȳ,ì)Ÿ€Š GÎbl+XÆÄ’ÏR˜Tf§ ç¡ÞxX’+–•G_U}‹)Ωƒ$œŽôÒ¿›2ey ¶À••‘û¥õwû‡géƒç#€ÚEÂdš¾ˆ= Ü|^oÖw ð_ëÇ5Ƽ Ó×Hí"™ˆ8angd¯·N y ×'”;ü‰ø…Œ]róf:CŒ7kÉ„îÙÉ€gy6L–ü•ÁÑQ;ÓhÖ©…O¿ò‡íÕïW8‹|!$_ž‘ ®ì«ª½z÷>^Õ0QÌ’²X}ôSÛ‚—5«Û«¿‡i3ÕB¬…—%xq ýÏ•4˯£2•ÞE3•x€ Jó˜•IþuÔæ)ËÄÅNÑ×ë/8r¸/Ù õ&iT)«ƒ—ùÞ=Î K¯ãÁãEQ&ìP‘ráO_Â3Vfùå/s7zŠÇúÏÒ»ÅÂÀ![ï³EZ†vvÜÚË ³Jéïã%\›ÿ?¿ V€Íþž‹gVHVÅ×QZ”Læå\é2Æði)¾Î^ÌÎ/öŠ[$¶œÉ³ß὜þä¨E¿©í‹T¦ ¿.N Âæ€y`C1ýââIÉê/?üã—ï¥|†÷-å¾ñEµÆê P5ãã¿IxaùÈ£ÇõÓ¿(ERúÃ9#ÿ ê~¼slr‘`!²@.Ĺº‹’+Ü}NõŤ²SMŠnîð~Ÿwôh)zÀœìe/ŸÅžpÎecáG:ü­—>&/ýxÙÇ ;¶áB8ñÃöG»©†˜I>/,}Y¢>y‘W‡§~£Òènì**¯f¿¸D>H}1ƒ!ê%ålÕG{vT endstream endobj 677 0 obj << /Length 2210 /Filter /FlateDecode >> stream xÚ½ÙnÛÆöÝ_AèåR@5ælNHS'MÚäö:Bz‹´@)‰²XH¤Â%®||Ï™’¢Lщô…³Ÿ9û2 ¼k/ð^œGí÷ó³óç\x”-%óæk²€pª=PBEäÍWÞ{ÿ÷€ªéóWíA8Åz§(‰8¬˜ÝeËÍÅ$ËÒɧI¹/à›åY2Açϩ씜(5gÉt&õçÓˆùE’Lg\1¿Ê÷ÓS~¾Í¯o픹c sS?-íü2ÏVõ²JVvº.gx©7k®™QA„íeiv ÛXè¿yó; •Á:.+hé7víí/W¶ƒk±Ý¶H+;WnsDâ?Iaçµ[ÜåEb÷ÇËe]ÄSêW B¶“¹ÛŸåÍv„òÑ€*‰a÷åüìÃÞõhÀH /”Š0ʽåîìý·‚ÅW ¨»1[wžÖD)”ÇÖ{{ö?'æ hŠlgAD¸ËË¿ãÝ~ 8K&ý|mÛ?û†ñÿ±ãe¾Ûƒ0³ê.†\SJù ©ä$] ¥ “c0é;  ÁXôå Ÿó$ÑJ…Ȧ^(4a€”áCZÀþ{. pyç/„0‚r@dƒ2A™G„J=~£&¨6'•‰!ÜIûw>iôæ»»—·Ô>èòArùÁÕ|„\ö7ÒáTÅŽ.|’fegKg:éêb2§7ÈÒŠTàË.&‹4ÏþrÓù¾Jwi™¸¥ª¨·ò;åb„e_NÀ ¿¢ïì^Œð‹>–_Œ!yÿÂ&B`l8Óúuˆ¥wËbƒÇÛÂá…OÎ?Ç‚¯C)P"¨²‡c”RpÿóTÑ`!5!>ÆÇ?DOÕj ""ÅQ@6æ1 ´0$µ%‘p›õôó%AÁ©…MÒSÄU²‹«"]&¥Ë‘z°Ð´»1CÆ@}ŒÂSh«¡¼jF©&"`ÞŒ1BC§ÿ¯“gå·ÇÉ\?TDÀÌ -—IHwù*Ù^L^= 5ä~?E|ŸGÔ|Åä$B“ú-’01£94/æWð]Öe•ïóÄ Ÿº­Ûì ó¥z¹Mò*]%vnW1$’‚K¾q)Ø*YÇõÖefi9$ª4ˆ5D8‡ ¿¡èrÖ`ÀvP;@·‡¶cÌÏ/€Ø_Ÿâ÷Õ|ß×ÕÕå;˘âÛM¾^ÃäÏ^×´WvqòloÛwsƒÔ1K>M¾ßæe½ ™ø:Þ™öi0~| °ßݘ޻EËê8¤ IX§ŸÈl“E7óö^iWã]šå³x™®\Nœ|¨ˆ…å]­Ô))hFBÝ2y5„"$ TO'd¡ åh Â8žë4YÂ÷b@TêAiJt€ØLiê?ÇzÆrñø.ÁÈÖ¸XuŽÆ;dLA…ôãý~›bуƒ*·­5 àyg8]&MM¤¤é¬¯ENvß"Þö‚¬dù ;%¸),›°oJhWéuZ•ÍÆØYA­CEæÎŶqôYPõ¢¬ÒªF—4¤Ð‘¨I‘òßš‚P[Æ (U¬üÐ×ί_½8óÞ›m´'^3ÉÁkZûøú¾ãáÐyëy`Ù•wÐK3T켞6àã…-YM1cÃ@u‰*ˆ½ÔÍ@9þW--[pâ&­6ƒîÒÁò–£® ‚·èèùfv½Î—9‡`A½(!s;ñIAe%‡sÌôPñ{K¨é[Óàìuêªùn·5¼„Ù‰¢DÕ<¶=13 £;`”ðµ‰[é¼°›Vâ68±ÝÚQìV—´°ÝuÑ8lw°2FØ“nÓE‘Ö`½\¢°íó tAs|úúg;BBlÏj–í[óÀç@çif'“æÁH5¶eÝ>ìÈ–³™'ˆ7ûÂ>œ€ƒsµÌ~ƒ ·`i»í¹»«<ÿ?%“Ï·-ö Ûj+¼¢¸˜Ü&%]Såác|L,ܖÖƘ"!c¦&8Ç(BODpœ«Ïˆ"Q¢}m‹³Õ 0ŒÀ­Å@j6Œ"¤-†6ÖÌš4s„˜Ò¾½´y¶½… #(mgŒaçÈTä4­ÎŽ÷qÆZ%Å¿àC»J¾¬>Þ•4ÈùÓdDÒü;tªJ°Ñ|AN[ICn=è©Á+v>ï„W »\Òò¯Æd̃ÕgPAÑ£÷×Óê'»a,E‘ï&Dè(oõ ¼M§O¸`1e~UÄY™¢6›®õÕEiC8lpŽ ÎØïѤ™Z÷1Ã*ÐÇx[ëŠâ$êr@t ZŽ9Ul÷,?¦*rTÆÊ¼àÜ'cPLÐû\ TNݦÙ*¡‡e ¶‘­ m‚ÊMÔM\LjÕy"Ù¸ <Ñ)‘Cä¨Ü[¼{ç7¢§‹'§"(H‡¸8N‰‚ºü°Pžo’ÁzÌ„‰‘z_¿%°è¨àÇd ~hdÆAêÍy8'‰sqpu• gY!H;Ô}~´ì&I¯7Uy.ì<Ë1 dÚÚ;þi kÀøDIyU¨[qž€ÌÄ`Šú͘ÿr=¨G`e!»ã‚(¾ÔëNÙgL›\(s ’ЀÕìV³¢E¼€,¨J1Wâ‘ý_dê¨ÉÇà~#¢Òýè‰ÜØÄmb£69ré2εWYµŽl‰Õì†Hb4ÆL4ÕÕj(5ZؼǪô¦I”œEN"¿ê~z•‰{;¹üP7U Œhû# SwL"Í.£î@A°³¹äy–wöâÞsL¯”¢è!=äø°æ2`ô6]ÎÏþÂ˜ï¸ endstream endobj 681 0 obj << /Length 1905 /Filter /FlateDecode >> stream xÚ­YKoã6¾çW¾Tb†ïG‘hí¢¶E·zØ-PYfb¡¶”Hr³ äÇwHJ¶äÈòÆNE‘Ùo†ó Žî#½¿ÀÍóñ‚ÀG$"˜"­y¤0AŒ«(]_|úG øøk„3:zòKבֈ ÃUôçÅ?Ý^\ýÌ4P@ÝÞEÄHd¨bQøt»ˆ>Åï¾$뇕Îqqžÿ”Im×I]f©­¾ si±~(r›×Ó¿o½xwÛá’c†6'pÙ•”!¬Y$FD˜18¢Èhó‚7Qª_OÂcEi$QJ:¨´BFÒ0ĉ H‘—‚ï˜ÁAM£'J¤”aú•$3­9R¤Q/aZSD ?Ñ g<‡MŠ(¤èÞ™×]ë Æ“-n&?Icfu¶Î*‹žlv¿¬«›ÉW[M~0¬œ“XGue#à(ФÇN”X€C ‚£zG^gyU'yjw¸laY »º™¤›ª.ÖÝ9”ÂïÍû¿ÉÕP'±=”þN{®ùPòN$ø8JÝó†P¢}”Þß~Ü·¦² †4 ÐëÙDGt¸#èx*õ&f$ŽÄúýõãûq$Nbm .À$p&GÀààM¥9ŒÖátϼ¾êzœ1™Oâ`Pf¦&2¨™™DÒœN'±ã‚!…ÅYAõtmãH,ÇH0Ègý,0!ÈA½´ÔàI ÐH"ï¤À^hw5'$ÐóËìãæ®´UXÙ§ ×AÓ®tÙÎtÆHìRž)<ëfèî™píFD3 ¼ÈÆ~TäÕ÷Þ(Ú”øâ=)âÌmäˆã&6|ÆDíoê CÍZç ¸|9áG!Û˜ †sFX¨¾"o—ƒq–°‘½*ö"(¼AÌùö"2ÁÁ¿:ï)D€ÉÍ$5$nóM=x<¦%S/hKG@à \ùPp¦\!ÌÍK˜ö.Ù¬œc`Ø9ó!·ÀÛS‡ 1ÌûðÎ8fñ/wƒ@20E=&ÈaO³Ýv Lsã°Ëû71ñCYÌ“y¶ÊjoÞÕ;$?yC„£¼**ï±Âq÷r—JnÜ¯à…µóÂî-„…´_C»È¯zÜÀ¹ó2gï'îJ¸ÝP sÎe»gP;ì®lfZ2Ác:òÍ–…çÂsѱÜEtO%èmÿ ZxVEemˆÛï½Mü®› ŽË°ò)[­Âhî/« /\õºÍ.dYëΑER'h¨ù*#ò°ÑÚÈâÙX bí»D d6B޵ðÚ›z¼}Ç Å‡êò_V .…VòœJãÕ$i Ð"ÃŽµïÀ  ´¦çi¯&qi »ÒàXûŽðn„¼Iû®wæõÖÇo{ ï~>¹uw›ƒÀè“#­;ª¿áÄoèHõÎh¸l1éVbQqÙÿíœÀì 6ªÃëH·Žª7ÂFÁ¦íÖ %Ô£x¨·ÁCvøéÏQùFxÈ#x°ýû³KàÆñoƒ‡èð7Ò¢£â\> stream xÚÅXÛŽÛF}×WóµÙ76™µØŽ‘ @°Ù ò`XŽÔ’P¤BR¶˜Ïé›DÊ4=3Þd_Äf_Šu9uªZI´’èõ"ñÏ?Ï$¢MÉ2©„.T´Ú/Þ¼K¢5ŠÂó,ú`·î£L!†UôŸÅ¿ßß,žÿÀ3H y’ÓèfÑ\$M!,! K7ëèMüêc±?Túz)™Œ›{þ÷¶-êÕ®Òõ¶ßu߸ÉU³?4µ®ûëw7?-^Ý Ô‰$¹âOPsh*'IÆ£4Ï•ùœŒ$b$ÏòODˆœƲNj°Îb,2V¨Ôø*S„a”未œ«è§†Ÿ•†áˆÓìS¢”œQú‘">¯t&ˆ¢>¾lF錖óù/æÄ ç󘢊(vñÍ#ø8ô”ë—WßÿL¯þ9žà'é3é5ІÏx@=à‹t.¥XNðÑ÷^”u×Ã~}6vû;ôå¾ì4oº—Wwº»z>ç‘Çë7éŽt ž˜qGÊHšÉ/ M²/{$ý‚GؼáOÒdÒv) Mr§ˆœ±]>à‹Âð{S†ói(lŠªÓó>y¼†“Ó‡ˆ¯uH †á_<qܹâc.W$Ü}]͘Ëq”Ò¯bð§‹8k²3¾¦ø=]Dè6ŒÅfi‡g‘pëÈÿ(””’\Jfã¤Ù¦ÀÇ?#)± ZØp·  öòì¶®ìu[ôºs[Ç‚eN2IÃVÓ–\/9MorgïÏÈá™%EÓ“£5Y2Fhê+ú/ÈÁ¦î¾³°Ý4#;\â  "ÀømBÕå¡‘9f<¨ø¾¨ŽúåWSº¥Š¤êdÏ·×K–«øÃN·zÒQ ¡çÝŸÊap›ßV¢ ³,ûvƒVWE_¾¿f*ö3Ýñ¶ëËþh<â÷ n´iÚáù<‰W×px»4_†o‘ª ú- ˆ©ûd«;Äò›z]Ö[„ˆ¥ñª*ºŽ¸SàK–¿úJñ¯)‹)p$è%4¦Œ–œ°ìV ÏJˆ$Þêªêν–õª:®5ûVLj€j–#·¼àºÜîúnJ¡=Å]Wz?úr¿+üÈûF¯J@I8œÃ*35däGër®X|h›Ûⶬʾ\™¯Ë®oˆòÖGÍLšÞl?‡Úli BrT"%â›°³0{Þ_KeUÜV~{ã²Äí1P0º&c-»ãÊÞ¹0 ÇDÑê$™ƒáaIv ÷¦Ø—ÕÝË«m±ß÷ö÷YY¿¿ß´Ú&£ÛšŠKP¹Ó÷i€YØb…Of²×…u@þʲØRJå£ïFÚ<å„'rìKÖSLe6¦‚RS31Ž©YrliKÿìtï5nâÖaνî­ZÝ{)¯­anA×ËÉH—½ùìÝuƦ]ÅR’%éÈU&“ùŠŽÑ wq™†d”1ue,9Ž2kûÆZ·Ö•{/½˜ÂmÜ—ûcë÷ŸÖýYJScû¼ XŽ,¨×fYÀrf2CÉemö:êÜ®·‰Lú¥Z,”~ÖS¦½?ï-µbü6I’g?º gÅ!€"'ºÃŒ{Ü_=Ó]FÁZ§”µN]¯ Àwë>¼¬Ý¢öGê¦w‡ŽvgÐ[>m±× $¬ÜÔæX¯Á¤MV¬rʦìÒn¬¬œ4çîνsÌÄEd¹ €6»Œc;íçßxJ0°i·‘üúzaîºÙˆ.0ó.¸4åñoõZ·N†‹’í¸í[ó’9% Ÿz=&üÒLztˆOl¬šö“ªg6€þ8êzU†£6ŸÝÉ.œ5•ñ$ºÕn°.[½êQ©&TÑ(×{¨-8*ò¦mön䜊Áºè Ÿ‚€ß••ŸP5ÞŠêJ1œ±®1û*T9‹t[)1³oZ/Xž$‡Ã±/ŒC}uM3 d_„¯Hê:Œ´˜\#™˜N#Ì>ûфϽŸn‚¥ò¸ìÝB³éµ Kl+×¾ ^hW¸bÔ•ÛÚ–Ý•Ïd«+ –³X÷¶:=°höù"fÏh2Ö¿seméKÔ×Ôµ¢:ì Û=õ}¸5®'+E-r9h%e’Í´’ :u©“E ,™Ða+)”«¶»(*3¢±Ç=ñ\˜°Áºø¸7¿ž+ÚТWê¢ÝùÍ&D&|ŽŠLúõ³›sµÍnóû·¾t™Å]q8•:,yJ3!Ê8íЯ¬L"M`Æ‘><3Yëpãc§vï›ÉR' ¶~g()d*˜g ¡yuì”RÓ>ÅyæñÚò|á^<™Cç®q~Î"ó 7×ú£Gµó®ãÉ¿ʧÿ<<¦ïtwß·€uÝÜo€#ŠP<¬E[*Éíõ͈ƒ3¹oxÍ`~î»'Î]——6U÷K.êK]½‚ÄS™ÊbÏ¡L±ôL_£Èþ=.= µz 9¬\ð9p:ÏT¸î~‘‘ã{&§Â4Löù&qg$wSqâL¦ vˆ°ƒ¾3%W{KF®/àÔ’ƒ©Ø6Pxí=æ™Lp%½h¬-iÀ>}0@Åð´Õú` ƒbºë뼄æBÒ‰CìÛ9—´Ô–´Pø™˜û›!lOêÿCî¼Ñ™»Ýgxƒðod"òF*Ÿ€ÁL†«B4îÂëóq7fÌøKÁƒH!¢¸Q ÉÈ8´þþ_z6Úôêfñ'Ëëã| endstream endobj 690 0 obj << /Length 2331 /Filter /FlateDecode >> stream xÚµYÝoܸ÷_!ø¥Z4K‹Ÿ¢Š¸‡&mz½ø¥¸Pe—»K@+m$­òÇw†¤di-Ëö&}?çã7Ãá •DÛ(‰þ~‘œ|º¹¸zÏED)ɤdÑÍ&¢,!œfQšPB…ŽnÖÑoñ§„¦‹ßo~î7Â.6ÚE‰æ0ãVW‡ÖîmcȦ6¦Î[Ó\_Þ›æ[[Í·²ZÐøÛ&/s‰$¯ÞS9¤Ä8'i*:Zd±T‹ÿH.–‚ò¸ÝÐ>äu¾7Ð_"µhÙí_RA„PžJkêfS2®6þÛî 6Dü~¡i rþ rú‘}_¯Mñ’Ç–ša›Œk” È[{»`iÜ ¢®¾™—뎑—Û«ª®Ms€NWåÚ–['s2Pûr4åÊš†8ÐßÝ\|¹ °,‰hDF´‘hŸ,Zí/~û=‰Ö0 ”Ïttç–î£L‘,É YD/þŒ­Sv" À®DBṿûšï,™G ¿ÿmlë-ù'?°ªö‡ª4eûX@ž "©>CÀ¡’œ$àPЧ$StŽF1’éì ‘Q˜~= c‘$Yš*DI§„AKg18&:e™NhP\«yŽ œTÎýJO ÍÐAh6#4cDètž£&*Ëžö&JS’²žo{×ñžc××—¥—},K¯ýY²Ljç*£ÔKÂg´§p¨ÒlžcFT¢g´gA·²|k˦ÍË•yÐTÒ¶ä6/Žæú’’äòj‘³ä›DN’ JÏ‘hˆ|œéÓtT uÔÝ4 —1äP$õEظœƒÔ=ÉTWƒA‰ÕÚÖB¾_˜}¨ÙFÄ!Î ©»åXúLÐdàJJv‹öök{„²ë Š)è,ûÅXm,–œÆXr,à Áp¢t\2>еCÈB9…¥cU69­_ÇUoJ—°4I²sŠÞ- )¡½¾´åáØb»“E.•P¤f=bP\ E㻩ͤ98d´[="?E]K§}·.e­+]±á¶¹”w¾fÖà¨þ¨fÆõœ)Ï›iÜøÊÔW´8‰"¬û·“-ýø/ÿøÏ??üâÇ7U½Ï[˜¥¾ßV~ÍgW‡Íy™÷Y“Y3-=äÞLg½M¬ó6'íýÌT¶ßò|Ú< 0{Èb™jô…»YÙÍ=à'X€ ¦ãûƒ{7pCÔ•Î8 ÃòÇ­¬ü·W;‡ºr]Xx›t2Œl‚—øàp\¦jí: ‡ÌŠ{[VË|e×¾9CŒ#A4Âÿa[Bp.L~kÖ£gŸ™7šAP¢¸5øÁ)êiaË?´¬ýQA ¦NJ F¥ŽûO‘A1ßïB±¸ª=‡Æ„%N3"!º x:ñl^ ½üá$LI©‚H;–"O 'ÇÂ&þìô‡³s¯`ÿÂnË}í9C ¸43b}ôÒ×B('Í*/ÌÐæàxÕìS_F2&v§’ÑøuSZÇÍq̹7˜õÖt¯|~ëÈ(·íC[êLàLÉuŒÂùÑÆþa‚©aÜGÆ4hñŸeª4àg´›©J¿ª«áκ]H|âs0ûÑ;ÐugJßYÛÍrô²J½ Ä÷nM1a‹=\±~¯Å°² ü£¡n÷”uÎ>ë";5¦õ ¨‡Îx”š°£šzlwΓµD:mx¦<õùÕÃ;íSžðÄõ§]t {ïlQxvxàÃ)×*h¥C=㎌BÚg«àpÛC\‹îÞwÁe@Œðî 4{ã›+H lÖsÖîÂ:ÆïáÊtvjÀ9ã–ÜTÕ:‹×¾ç7Õë߉3Õ‘DWøƒÝ§ÐÄÐtrD¡f—ׯypÌ[7D¿zðú„êͬ†f†áÏî{ÙSôÈ-Õ#·TñnšýÈ©Ânpoò@"¼b ë.­æø¹.Gäó’ˉžs;õ!k蟷y1韸'ÜGS¡œ0Ù‡r 3ß(IÇyKCèÆ†"Å1tççO­¼ á&ÀÉ!h~‘%!w` €<ùòÓ}0ÙäÇ¢}ã`;K‚4¥yÈílÓ]1!ûóñFÅPtŒ@ÃDíñ._¡¸»É #:su…<©+¤îí0ð¾œvÕ±Xû¶-WÅq"†ùš¯ÚâÞw6Õ±ž’…BÑ”1ýtA2®-8K ?‰6ÀJL¬¥ä‰O²,þ\çeÈõÃ9u»ú/G[ØÏµÅ«§?ƒ°ürê¬ÜA*а•úÿY)þÏò3î×6ü½ˆKÚ*\TÛûäºxCæïb\ ± ƒæÖ¯wÿ…–þ{·³½NÊG¿ ÄO~q,Ÿ0>ºe ¾ê$4¶x> 9(}wíÕ5aYYµ¾Ù$“oºË¥:nw~Â|]_#‡øŽóï Ãø÷œK+X²h|J’£½Šÿìa|tQr(Î{§ÿ0y!RB¡¡Á<}™4&0 …CQ!w>¡_¦T9SMp§œ8¼}Ö9Å^‘L÷+–.…N£ó†híNñ©•$úxWئŒŠ˜¢÷‡ŒR[¸žB^Ç¡ÔM&®tÁyl0°èéÀ"$Ìì…g¬ª ²6.ëpçÊ,Ä_"Ð[yãH³^‘P‰s/ç?‡~ox´)ÄãåH¨þŠ‹$ ƒITø×$øhÉ»›‹ÿ"‰¼ endstream endobj 695 0 obj << /Length 2728 /Filter /FlateDecode >> stream xÚ½ZYsã¸~÷¯Pù%tÍÆEܲS5©ììNjR»ñømg+%Zb…‡†¤ìñ¿O7ò@”,»ò"M¨  »A:[Íèì—3êž»=»üÈÂc$ C>»½Ÿ1ÊIËYDa2žÝ.géw]lòôb.Â0Xe< ÒÒvï.æØË+$>¾¢A»vƒ¿R&릵E®››*¨î-©XdßÛmí:™U襣<¯‚û T¹“š•«‹?oÿ6Í™$R*§vž &Œh›ŸpÀåGÁÇÆ†œD<„¿™á·ÌŽy'‚ŠnÌ{›ˆéF|ÜÏEÏåÆÏEÑÑåÒdžs’°Þ¦ÏGi3’;h% štQï¹I?eÐÌÜÓM ´`R< °’˜ªü¿ƒÊ÷&Ç ª^†*zä\Ä!á æ˜í‚à볟oϾ!VtÆú¥§BIÏÅÙÒÙ^‚k‘ijG3´˜S¢¨|öåì_v‹8„&Ì(“HB•f‚ÄÜŠý¹[Æ!·+ ŸÿÙèºÍÚ¬*q¹üÅU±BÙþ¨¥¤!I"q‚–cK¡1ò`$’S,è €“8È„Ò_ÊÁ Åù mˆG„CKIE’ÄíwÌ79Ne f®“‰¢p¿Î/e±_iþXù„ÎâlÊ™X宼«¿±n“-¯Ï{2;·Äû,OI©‹ôúœ\6…Îóo)¿7îýW&¤ÇÍ:°^®»)Ã2tª‹ ¨xHb~R\B—ýhq~/ve.u«Iû´ÊÖYž•mZç©~H·§´9ÿë')æ…‚Ô’PÀÆÈUtH¢¢ñ añ®È+wÔn“gM{}~ËÞÛ®¯q~9…ÍIšz±¡1Q¨:*N`CQph¼6c‘û°ùØ!ákLcs’¦>lÂ$1¶EÕ~lÂ$"4| hv$îƒæ¦â†w Ñ5ä$4')êE&Nˆ„µiôŒ&ñRò7f,r4Ÿ;h|ihNÒÔ‹M”X¹¸'žÀ&:Bâ1gÔŽÀ«ËSjÊâ—Ë÷› )…•LK‰Rñk‚ˆW°èµPQQòšðë,ºhYÈI;D“PŠÝh÷yèMaöÀ$Ɉè–Å'ÌP¬Ò2­už/™tiNU½LkÌÍ “`Â_û’%àˆá]p?^pžLœ@²>§¡VȲ²Isc5)«ÖÒ ÝBD@læÀ!rç¢ËœM¿Ú„×$à†ÇAZ›”›k›‘ËQN92HŠƒešÛwkÝØFfz¸€aºÎôÍîeÐdmÚ8–ís–ƒºN›aZ•Ài´Ù=ô=þx²ñf]ms“V²®h`;C:YiŸV"4p+³-3Eð49©Á:›Ú ò-Óž7ôŸ¼IÄø<œDãÚýŒð™/bP¤îtmZ´¹\¤]¶Çü?Ú5ܘĕ3 íîË)@Õ k…™×÷öEvÿìoµnÕø§Úý{™"z¥±†h÷þ¾/ØÂ‡?Ñ”QLD<[' 7Ø©D“C>€É7Àh*ÑD×26N2d¯!s/×ðÇmŽIÂ’ø5ÛÜ‹Yì=$lÛ2 ¦™RÅDrñšâÅ,ö+­ ÉÕÁ³1èéu˜ÈEr„Ä#ÜdGÞÕ¥ó“ SO¼k§y <’Ëè„¡1ìúÉ+ë%.žØzuÙSæ¾T¼Ç‚ß¿ê†ã,º8YÈi/ȱ䥮&gD_¢¥ŒÊ‡î2™Œº1C^ ©P¹4i $>»«IΆ¬UB ™W—¸ÂœM;¨»³âWØòtã¿Ðc澇v9Ún åÓ8xZôY=°f¤»ã£$ÉnÖ÷¡ñ× ‘ ÉíïñÚ• 9dÉ\„&¥Dâžj… ‰`ѱŠ˜ÖHŽÌ¢MšZöyV¦V ²„±\CïSY¤î¹– ôöØûÆî¶Ñ£Ï\PðEï>Æ_¨È“5ã|`æÅÁïk¬Œ<ýó3ŽƒÇ,Ïí¿6µu Ö¾¨¶­ãVZBú}“g ô+7"­k“ìØ"m½J-]›ûq Þé,ï™_Ùã7¡2Eø£-Nz7>5¾0FTÙÒ½Z›i‡V³®êvQN…©´ ­{×1èŠ^?x½Í÷…xøÀÀïÁ°‰7êëÉ ‹ï a×]5vŒ8zv÷½w7à#Ÿ‡.ÕKâFFàCxoÝà `ªÜRL"ˆo(РÉ\…%ê}ô'ÐŽÒà—ÛK~7è1pçB'1,J}:€¸¨_^²cgŸ¼.Í1¡4 ±S®Jr‹‹HŽvv¿§±´Q‘«±.-…Wf壂:ý¶Íj¬áŒbªÒGWÁ':JëXØ?¡òpùdû…­MbÅÐãÍfG–ÿŒ|ÒÀŒ¤<[•]¡Ó’LÅž†¶]äiÕfX34ÿA“~ƒÞ6…X½±·å2­mÓ}Ž"Ü„A£×2GÜ›íÝÜ[pl³v‹€a\ÛÆ, É­é@ùòûí7©®¨ãÚ¾¸ÇE/ŒHq³‚û¯¡×©{ÑVîÐÊ«ÕÉÅ<≙\Ïê<‚c§?6ë§"÷yŒI,Âát,ænI)/v·ÆîÔì¡—°5ik«±Ø±f@¯á±9‡w¸ êü©Éº¿TþSSõ§¦]e¤ó_1œw<}iR˜ÈT—v.ÌV§[gMˆ á³Oet?1Œã&»ÁMÛèÊfÑ0á¶x¤.³f“w»,ìVŠƒÌÁ³Øæº¶ošÖ–ÿ ã{;f{ñZ×zñas©|È› o†÷‡eaýWUé–Ÿ- ·xá¢_·Ìq&Ù)?¬ý³(í1k×þB6%!ïÏì #Ï „ ¨xTÆŽ¶žAñÁ‘«ñ|ðù—Kèä0m½Ò*jùØ’‰! Vxeɺ±ÏÖõ ýÝdXŽºv<û¯¹ÓȳuåÎw³â-3 íxüîâóm£…7-:_U5€Z`7†-ÁΡµNkw-d>s lïmK;JV.³…µ º{óÊ]*ÅîBÂHÛµ·Jø|ÁÑL¨ëß°úø×^ªHèœônÛº/î0:ËHJ¼ßº1»%ë¿d3¶¯¯Ï›Mí g#ü0L솳s GØoeþä>ð+Ý'6ÄZ´öæ#q[/ îj]Ú%cûyZ®Úµ‰úLÁFf$GA:â?)wAö?òìÝ endstream endobj 699 0 obj << /Length 1411 /Filter /FlateDecode >> stream xÚWQoã6 ~¿_ôÉÁ$K²=Ü Ø€k·aÛC‘·ÝG­ 8vj+½»íÏe;NâžLI”DòûHÊ|õ´â«ûw<|Ù¾{'ôJ–i-WÛÇ•à’¥©Z%\0¡ÒÕv¿ú;úRÕõzÇ*Ú­72, N½Ý“TÚÎÏé¨¯šµˆŠ0j›úi´MØtÌ;W¹ªmHÃÖö`›5êhb~W…“Ž]뇅íáV¶Þ(E¿Ú¦°·ë¶¿ƒ;¡˜R†,v¥Åé÷w±œy—±ŒPöJv]Þem›'Wö?цy82Í2™ ŠöpôV€7`sâm棛 •y?L- KãñÀUÓ;°Á.^n4fÔíO»Ík˜÷®Lü¹³ ü\÷í-š“E9Yè<Õ–äûí ŠìÞÖ4€”ƒc® SÃFØ E$ÁíǶ»X>T_Ý©³¯®Zí?\ä×°“)Ó&#×åÎr×UÀˆÅ襋µy :¼Ì†aHÒèõÐ)–@ö¼ ÝíÐm×Ù~ذØ €Y€!S£ª§ŸOÅ©Î;Z»zH°SH±ì<è6Fñh뱕Æ~u´ëŠu—1¸ìƒ}>=vöy#˜#`@D•ɨg €®§ veîHÊé30å4Ä9…ãö‘¾pkUW»®:hl€¢ó|‚rP '{û;ÈrMÖf+¨;X» 0‰’Ñ_´SÇW ˆ,Ñz$A_9‹L\Ž@"Y’ÅoQЀT2‹>s¡^Ö¾¾.]Í5Keúü3Ì(qο@6“0.^‘íÒ° lšEwëTFí ©¥´¬|¶·$NGó$KÌP;”Èa`®/óãù(ÐùX×Ñ2â€Ó® ëÀCÈ OES‘6äÍþbÇÑgÒ@˜–ò`…<'êø(M¾,C" ¹Ê[HnÃÂc×HŸlaŸ»ÜGB_ƒ\f†É³þ9>ñ ¸ˆüfØ2ƒã)Ô ´=ÎÀ/xs€mä0t·œ|hOŽÆd"höÖwÔêê©™žž8…yMÚ0XÊ< P€½úüÜH(éMý6ñ!æ,aÄh†Fí2èqôé­³ä(f=FšË«‘VšÉdJ®éWãœB›šõB7L&,Ë.z=!dª‡„FÓy“ž=eªæ¯¬´Ÿò1(I7T,} R5s–{³ƒÂÎ9`áPÀ.ð #¸©>|$ÇX\IÓT$cã¯ìzw®Lò!ß_X§=ø®ë÷…ÊèÙ_óÇÅÖ©dÄ`+n±%èèO1¼ƒÂ,Ûïµ±„«‚·Š»²l‰,P^§gõb¹ï°˜™‹¯HSÁCö¶ð­åŸâ1½Ö`Ê z# pP-ˆ#1&lY¤36Îôul`ã ßq’œ¥‰œÃý ƒÚ²{ ¶u'8 9>V2H;Wúÿ¬ñÇy%T ׈ Y¸Gé™Ö§í»ÿ>þl endstream endobj 705 0 obj << /Length 2509 /Filter /FlateDecode >> stream xÚ­Z[oÛ8~ϯò$c×4¯U8ì`ÛbÉ¢›æa€¶X(¶k!KŽ$'Íüú=)[riÚ–ýd’¢ùó«.Ø{ö°÷ù ›ß—+¿Ø#ÁIɽÄxèÍ–Wß~`oÿð0b‘ôÞš­KI"aœy_¯þsõûÃÕä“pŠpD¼‡'R‰8à4Œ(\z˜{ßü¯ér•%£± Âÿ²x¿»ÕÃ?ÛAò3n6üxøãêãCG6àhˆl]Â’yA$‘ëìQÉè—#xDhvú C”zEa(‚dˆ(Œ‚ˆ!NBÍùUó­Ð 9Xlj 0¡O¦Eþ¿ÖŸWuºL«Ä\zO*sá;aÜAØéâ[Ùâé[üBluñª$.g ˆóUy=q9¿Œ®¬ƒ:teçêÚFAp:9& Ø…4…Ú* ,š‚QÁÎÊS§±_hªª«)›‘KhŒD@/“§º˜ÓÇBw‘%ùs½¨¶üû-q–—Aòô`(  éHC°ƒrä1ÑØ´ä®[²›¤€œJ')gÀž.Ÿ•ÜåÃÕIásùhý¡‹8ôÂ¥/¾ˆ¾"HštA=˜€3”òœ°=ùˆýBCøjz"âhŠ„ð{ £‘(ˆ¢ÃvêN˸N–q]¦³¤¶÷wΰ&Ž•ÕfptXz:.É¡L`y0r{˜–Ƚk#wYÌ“ìæúóý3b‡‰fe#AXaØp4`"oéyl´þÐNºáRzv¥ Úx€£B‚ó"÷Ô#ö -(â¬ÜÐ%5F‡©¸=Ðiò²~*“—NÔ~üäŽÚA¢Xµç]íM’àêüè"QÛÅ´D-èî ÒA’X•g*Më°ŽfK°# ©¬=Äé¤5¼KÛÓ¡­ªR ª)éÔÑT ªþpÖ㘓Ø/5 P$ÚÇ1ŽÖGŽ"*.SU» Ó*­•H;ÁùõÞœƒd±ªCÄxdÔwµBX F‹gÓœ÷mI}³5Ü©„ÝÑ:H4<ûp“6¨£ÅâÐ@†ø"©ª‡icƒžÆÆ0ѬlH µÖdêh·¸ Ái·z˜66؉l ÍÊF(6íÄ?=Š.¦ ~"ƒD³²HµÞ©£ãAм¹]L¢Ï>ÄÆ Ѭl@«Èp›E  Rœý<¡8}KÒçE åƒ`*þ٦Чx™fï7×Ïñrÿ-Í_wŸ3ÄÙjÿ4t€vÂ0¢›— ŽžsÈŽ?¯#n9ë`nô_'Z}—§ ’ª8ï*îè9;òOéN'ÆU\ºžlU”up™£ä2þ!:òî´:l+—ºƒà­COʹ)]Œ¸4&ˆrNÿ{òû¥& IfJ s4€wò˜”ât—uZ§EždÉr›Ë7ËÿUë›l–f Êãers K.«•ÜåÆÕâKqÓE¼F“AUòb´ŸÇuŒê÷”¶¼Þ¼ëÏ’ø5™Îbø"¬°¨ËŠ£-d€+ñE¡æt™þ¬×e²õ˜,­jõðïzê8[‚a"[Y’N4Í s´‹LRD"q–º˜ûXºk©pÜ, ÙÊRÈQ@LÃm$ )ò"·Ÿ=Ì},}j©pÜ, ÙÊR &í׎ö’þ+/ÂRsK÷-÷´°vÀÛp³4Hd+KB ÈŸ†%GOÉCì2®Ô…ÜGÒmK’sà&iˆÄVޏhš;Í‘£ýdü0â1­8ôª½Ká“á­Ú2 ¿¦äŽ”±‰(8§#;ùˆýRƒoáö+"GÉèˆN™¯Ãº€`"õu˜Ë4§ÃÚµ„J+LèpGßÉÔ7‰ô¬nùŒ#¶RÀ}/£ç|÷xÆíç¥êˆ€9Û&%pÒ3 =ÂãÕv×§QI@gcx‰ähL䢌Æ,~•ÌŠ|®ÇæÃÀ¬0öo?ó?•½à\Ž"!šs±7¦Ð¦yX$ðoÎ6_¦Â„û£1 ý$+Fðó¦7T =«ôtѽVúß1áµYZ˜³n?ˆ²4“eÑœ> stream xÚÅZ]oÛÆ}ׯØÇæ¡Ëý˜Ý-Œi‹´ HrôÁ…l3ŠP[4$ú:ù÷=CJ×¢>lQ$zl-ÉáîìÌ™33+…l”Q!;e þlP–"®½²¸2)çå:(—p²ò.*6Fã½”0füycš„Uò óA˜eRç3g ¢Å?Lí­¼ƒµ<‹0‘Ìb² ¢²œe€y’7¶˜'G#s(g &›Œt`g•³P˜1³sДÖ$ L°žc¨Àwb€Ö6aGÙOä®7wXU´Ã&-V‡ÞÞ¼`>ÌìIùàe”ç(¼•<Ô”;)a-·²K&«ÈÂRL^‘ƒ%:€á} H‰¡(Á¢˜ž)`q'@8ŠòÁ)JQ¬•ek «VÁZ‹WÁ‘ HŸdT²å0«2Èpã"ÈÌŠ…K4>O k4þ€Õ™Åy2¡,cE†‡hìÿ4a—³F´œ(ÌFø®#ü ¦Sªxåñë×^Ya¬°¾ðÑJ›' @¦½gx¸{-åãF ˆ Ó^`¥âeuõ®¬ÕG¸ì—Wªx_~­Õÿ”8èK6û¾Ìgù²x¹XT˜ñcø¢’0®| ã¶Ÿíýš÷&ÅOÕòº\6K™OÅoÅïÅϸå®°+±v$¬ K€f49áTÒäÄÞÝ_Ö˜²x=_üU¼¼¸h(^^ÕójQ¼+þõöwùûîK]ßýP³eu·Ò³ªšÝ”úªºmïw_¾ÝÞ|ÿ¹ZÞß¾€¢çéÚBÎά 9p½×¡á«¬sc¾LÙõBªYé¸îæQwjܯ£ê$Íà¶`¼ŸBîeæwªøµz_)ÄÂwWóºÔߦ‹Y¦Ëê|Mls±ÑiÁ륤-H ù];p¦‡u³O5ùísUÕX®Ôv[Ä«T'sÌŽðšcbÖÆ¹…‰4Èöagt²RJ°&ÄËÚ8ÎrèÒR» iCv²“JióÀc²õƒsùÄîñ‰TAƒøDJ­–OžâÞ0§?E€KxDª•ĺÁƒíã3(OC@¾nkªp1i#•ŠèÀžòðD¸Íîç‹ëjahç¶Îíè“v»8?‚Æ;ÈêPª!ë¡q ´ç‚ªî‚Ι> c·[HÉ~šE)r³Ô±KÇbÛFrÒ% Kî.íۅϱËV0Úv¼Þ›4)íg38=e-ý˜$÷,´Ä@&–bŸà‰'‚⺜-¦ “Ç‹O´,Ú7 Z[w¸´o<ÖGT¹,Wõxjx4K_¶VÃ[T¥È‰Ïª±ªËÛñÔ P„‰üX…­b §¨1]Ö—å´k“&Òbºê ¯éÊ9-goº:ž/O Ë‘£~?FýÐõ­Jr0(&»Õ²¢– ôÕM5F–´‰"jÜL]¿º¿\•MM«S· ëYP;¢9þA!-x#B»XŽP¤úÞu¹Ðó¿æwbb]-g…\Þ¼~ѧïNœåjŠ3ré0éthËOÚ­òÎ8’êζè>ÎC?œ‡¼‹óЪ$àï]µC·P3YØÃÿV›Q3™àŸÏT4b{‡6ÄæP¸¢dS®Q ŸÁiÇ|¼^ºÖ«raânÐ…þAw¬¶Às.^Øïá…í9xÙÚ=»Ø^ŸÏ6.ù4á&w£Ø8‰ÌNI1OóŽPKF³oñ40B¹Ý |µÒ~Æ1û<‡LäåÛ8„Gó½YŒˆPXRº :ÓÅ|5¿­þ;µvÄKh>Ù(ãQkfÛGÃ#j}cŠ2‰uD{V™Õ¨r=/§9ï’ç>á“$0¼$Gǘf;u¡¾+#$£¸ŸŒâÐd´ŽXŽ#'#´I0 ™¨åKeçA*Ò8g4Ìõôò¦Ôṽtä´äu±Ùdû*!¨ˆÜB]áõ¹xBB|â²Ó ôDN®´_;Æ<0s¥>µc:P;"ìÐn§Ó„G»ìÎ(Ž´‰»Öž«ïÙ8ÑÀ^k>Ö¤cØ05Ì+Uµ÷Y§¦©6ÈYî ®î/—óriÝnðl xÂ! cËôO8v”0ïW$©_E’Ý^$õIb)ú©Ö:~^8&cİgÄì1S#v…× ƒ”’“¯Ñ…¹7¿]Ø6Ujª4Ú1ǙۊfÑœ…€G²Œí/?š_µŸ£ö>E¬o¾-a)<¬–ß9Î:p:Î73ú:à˜Ø¦Ô|-aâ@íæ7"V¾6ʶ÷)ñÃÞֳ«ïoኻò欮?/‹ëêaqSM¯‹ëi=]•õª@É]Þ¬ Q¿xý+}ø½Ñõ×zø/Hdþq#ˆ>tÿ× &¢9…>þ²s endstream endobj 712 0 obj << /Length 2440 /Filter /FlateDecode >> stream xÚ­›]oÛ8†ïó+<¾J€ ÍoR g-vR hfºi.˜ ÔD‰…õWe9MþýY¤M%ô±% EÆŠùžóˆ:|IIl@á_ñ4`›ÆíÇ3:x‚ÆÇ3öîȇ»³ÑµàÆH¢Ü=åÄZ90”&íàîaðÇùlñMW£é“|}þ(ÿ[Þò¥¼øëîÓ¶÷Ñ5SŽ$#2QplÓ¹¸”FœßM² vþzq)Drž™kLW‹ºµ,Üœ?çÙCõ‰=Ïçõ‘râþøË¤ú‹×›Ïîéý·çÿ¿Pò<}ʪ˜Þætéc‘R×e/él9Íê¬ê¯53°‚Xc|y‘Ý—‹âõÂòsò'Ul“þ/wgßY¶…§µ$6ƒûÙÙÑÁü4 D$vðcó§³3†ÐšÓÁ׳ÿ¹3a¡’ЄUòÜ*g:ðMQGQѯ+ /!LÝ0vA¨ÐY…õAœ$6y×…Láܶïb“=çEcô†½!ZZ)B……Qà.hʼnfWLHEv/oF5h²¦æx9yM/.WçÅzNò‡«a5`†õG‹u¹\—ä1ŸfWÃQ—Ùª\¹£ßŠt~?Ù|t5œ/†ÿ~ŸÀY§¢È¤aËëð9‚L*bjbŒÚš[ö°?d‘fÜHȺ“Éig™bøÍñO——õ)»+²¬n•‹åbºxzýWýëªL‹²nþÈËIÝú/~ýT7ÓùƒûÞ$›×­¯_nWuëò;õ²Šs¤ÀÉz‰pä†he{âhŽ=4,ÝNâÑty ­t™%‡ªQB4µH¶F‹m*Žó9 Šù½/Ue¸cîÊÏçyIJKWÃõ*+ܧU™ ótæ>ý»úƒju‡ÿdB"ܺdÅyI#ë$4‚dô0³Pn•¥Åýäj¸Zz&‹e™ÏòUæhA•aƒ§uLQ4Éì' ’ øk$ÔޏHÚ+ÇòT 8jj]‹å ªF2´îbÐV%\aN ­$§…Ü®ƒHÀ‚h€£²Â]F‘ˆ Ì—`èPIKt’R ÑÝôu½Xά¤¥+L³´,òûlõ³;¥n¦z,³]a:fªê–Aš†â ”ƒ†8;¥ [Ý´Pt\òlv%üö†a>­[8Q*!Š»‹“!FM)‹ÙÇüÕÐŒÌ_7~þÚ,ø®†÷ëU¹˜¥ép7¦6Ä^œãýø­ØÝ¢“ I˜_ 6QUØê^€…š1`¼%0~X§èãÀàkÌñBì *¯í‡×N2†K´Ä%ãê|8YC¹cˆŸT.pÓ ®P2ÆK¶ä%óê|g`Òý´‡øHÅÀÍk~/_ÁCÑñ(,áXÎ"ˆ&]m´°Ä%YGÆ ·æ$Ò¶‹ýQS?]И„ŸÊÚ~æÚ@3ð'`ògRj· x¬>§Ež–ùbÞü¸úŽ›¤Óûb±ríU^ç[:%C)Mî‹*bOa΃2žô²!:®’xTuâë-jZºÅMLº`ΜsÄëJ«`ð²>ŠdC3R$o‹îçtº†JH K Õ­…Ý‚Œr;^íxÖ\;+ÁAk#zájƸð(£(,Ôp.‚ŒrѰŽMœáäˆÉ•ZC‰îe“¦¡ã""\ª]ëœK§ £\”%Òºy„#^V*Mà/\BÍá¢Ó –ä8—NAF¹€ß6 bY%˜d¡õi;˜K 9þ‘åO“*+£Šn¨ü×W—Çt–O_¯†n [½ÝÀÚ¸¾ÂQŒW§è£¼DÀ ±¬R¡ˆne±×°tߌ¡t¹œæÔ $o«Žä\Z†¢ö1F‘ð bK%ï ? ‹Dm¥Å‘ð~° bZ%ë ; ‰x‹„YÊÇ‘°~Ð b‰%í = ‰|‹„jªÄi‰ö‚D$ÄÙŠäT$uá õÆ#Wy‘4;èFÓ´;Y8X¶Ó(Ó˲5Ô¶K¶“z<_ȇ9›(–0nÅ)KÖÖ]ìÚT m÷¤†@Œ£0ŒØ„÷r/³!º[´þg–Ï—é}îöͳïë|š+òµß>/²ï+â.æÂ]ÕOù³¿üíu{k8Xø³pí–]¨†µ÷ÃqœBóÃ{üÇ EÇÀmCjg9¹F×­ÝB‰f¯Âìc)Ô’Ç·P0b¶¯½CJS²r5Ü ´Ðw. C†0×(dO0ä¼ Ù Â@ü¢=Á`ˆ.0D?0xqŠ‚÷ƒ€!»ÀàýÀ`! Ä# v* _.CÅñÈ×K,UÖOª›Ç*¼)¼Õ„r}’GhÛ5ôhÝ͉X9N“+~JÔ­»Ø5O8QÖdɰ¨iµùÒËDÜÝ9›ßæîZ{Þ<ÚÚÜs¯Ÿ^¬ÛÓlþTNŽq,Ý¢Ž‚‚ŸÒß둈ä–júájŽkÜ«¢ô᳟¼1]‚Šb0!ĸqsXñˆ’ÜЋ”ämòÛ/äö¼°ªÜ>¼( Ò@Œ×'Òð#"CËV÷’­ÒDp÷øDœW’ð䤺ܺ‹ýQË„(ånØHÄRqiˆâ줨ÛvDM‰U~d!Þ‡ K¤è§Ü„š»²|“¿”ëâýMÒtµÊfߦÕ[Gâ.aFÁˆ âƒ@õ âQ—\(8^¦E™Ww„³i6Û•¡íÇìýõ›ñçÙ ù2y=êÙÚö‘GAqFŒöãqQœ%Dˆ~žcoˆ>¤eJÊ×%0Ø>$’Ïˬ˜fésöpðÆD·À¢,X–¼Yµ/*z¹QÜÐÏê‹h7j¦yõÆsÏAÆøÖ)Ò(Ê SÎ)ÌR0S¼—»Å Í}pn<ŠîÂ7ä8]"Áa•U•îö­Bl§©X/·Œšûà\{8×ε‡sÃéiŽå$n¡¦3ȪXÚËCj Í}pn=œ[çÖù=§S¤Q8à\…úP!ÞåI/<64÷ÁùìáÄ8œN‘Fá€5ÜdÄJÂâí°ä1ÓxCq> stream xÚ­XKsÜ6¾ëWð§6áMòC²µvœ8.gW‡¸â Jb-9THŽ-ýûôä G”ìTæ Ðú…Æ×ÝÉm"“×2þþpuqùJ¹D)Q8§“«›Di)¬5I&•P6O®¶Éïé›Ýj­¤”iÛmËnµ.Š"ÚHû(•âx¸+ãèíkû/l`¡ÎÒmY‹ÚÈÿqõÓå+£5ЙÆ9PdßwíPV^9×Õ9!•öåŸûr·!žÉÚX# “¬•s<¯@MkRÐh仵>UÛr¥Òm¤V»8xF9e¬pvY>„æ¾.ûË%í|&2iÆ¥Ûª+7CÛ=®r~ B´,Ò¾j@ö}ý8 EïÉ_ËâÁ*m²‘©¸¼¿{lêÑb'àÀf¯×Mý—“¦õ­} â7> €Âƒã&?J'Cßï›jw»Z;ÏØi•¾¿#uyËôëjÀ<úTõL«vkVnä:Ó®B]—àz›+ò<þ>ãøÌ 'ÕtÖÝfÑçFBèO|F(±ZçtV £Ý³¬MˆBÛ›Hh÷]_ò¸¯«[²pÀó!ÕV:O?#© ÿ?hKƒ[ šÃÑz‘û¹éïH\.´Õ£Ya.3™N÷¨ªÉÀwB™<” %ñÚ!5ÞW"ÝUqÇñ%‹ùÜ¢è™òaׂ݀Fût›ûrQý "UëI}‰±)¼W¼;„»Ò.ý~‡ÂÜxxò¹îxÔ¬ŒJ÷õPMßîC7TCÕŽûê²)w¸jè—ü‚µÊg,øŠW©ƒ<œ\óm« >3íneõ‰ºgÊ0îÝ´¸uˆ³ß(øÕtü¼¶Å_™öx‘ó´ÜT7#`W…]¨ûŠGMLáh¬ïJŒ/ãMÇ/ÑtŒÎÐÄzšuBh ˜BVµ»-][âÕŽ<#GÚ½ßÔe; ÒÇ CiÆFõKA}¢pßÀMÆuÿ¹ºøóï©L¡¥Éuâ¶L‘%›æâ÷?d²…`3òä3-m#|Ûêä¿rb:EÞ\ÈÌ/UÄÄt¯„Â]Wgê¬È¥?ÚöJ€§–BÎBRÒ·K®Ë…—D=ã8m­Pº8‹ Úf"žÁ‹~Ó^L™óÈô&!OžúM?ç7ð³Îg·T@J×þ ®3°òg±ÂdŒÕ—]g )Šâ<®3`eþÔuæë\GiT[üEp(»õXx!ó ¯Ë@5!$0òþÇo߼DZMoÚ® #¨ŸV"X~é0tæ„Óy°Sÿ³˜ÊðnÄ+CÒ³\hˆu¡…#s¡/€ÃõSñJu8’rî0º˜SÒ9­ÀàÇŸ?äŽOJ†H=–®Žçgç eüí÷×=ä…=g¤`ÁÀŒ8Ô…] D»»¤{×O[»lx³"}°½)ë¥TñA\‘¥7]Ûà(9HX`ñ)ÊY‰ÉeB¥8¿7~„þÀ2åØbœSN„%4Hù´ÅBW°)fFø6]Û/fU0Ó¹Íü‘“pÆêfYzš&0­¿ cNsÈ¿¡¼ßñôØ?¸ýÓ"dY6yãÀÞOÞÿ<£Zh’”ÏÏ’Qmèå‹/gÔ³u.ô¥Ì (ü©^-ôх•¶…¢º¦›}? óq<¿ H™•º0g‹.ùf‰‹VÂå—×K®<4SƒùÝ“B€ãŠ?£IîýßÐäjI0ç°:-e¼çzÛ/TšH»é¸Ô¬ðJzÐqmŒcè$xÀm(¤HÅÄ•!1n¡¿Ž¥ýBÐÚr±u…pêI°Ù!h!RÃ{´3VŽ-¶1vÉk“CÖV/p/´å¥Ð+•à”P{9‡7œoyNýL¡Ãâ @Ëm'MOð(ˆ‡q5rFl:¤‘·#¾?îëàGCMiÔyàxy£¿~Î!t„Ÿ™Ð—ª+8ÏÜÎàÇÌàÇ`Ny‡^_ý—ø¾ÓRÈxc\ð@cD Á×a3%Á½‰ q2’’þi¿hœŽ¹Ñ8uÈ÷€4Æ.Œq@mê»–7ás@x-#!à’VuuÝUû†¿œÞe¤Å»¼Xð7Îa1‰?2Gʾ#ì"?j8n:o˜êÒMXemtãnŸ6Õðï"«0:HJË„ë1‹#ô uäÓŽÚ„aIqÎè|ÆÞÅtnÆš I¨i×L=~šð³þœ¿cÅQ‰R,¶„Ø¢™CgóJ-¾iaäñ»œbQxŒN2² ¤jz•ðñžßèêö¶¤¨{Œ5&€¢?ÉjÛ9Tgpâ¨tî§ÀêPªô¾-üÄùÄòñ> stream xÚµ[Ko7¾ûW,tJ–âûÈ=MR´ Ð:>´Hƒ@qd[…^‘ä¤þ÷•vÒ¸Ôæb –Íï±äÌG®–W7¯^ñæõó™€W^‰Jpɼוã‚)íª«ùÙ»÷¼úþVq¦‚¯¾îþt^ aY0ÞϪ·gž=¿<¾T†`Q]^WRf¬…Ñ8“ðÑå§êݳÿç«Ù䇟Œ4Ï–×û×?nïß¼Þ¿ý«}s=…¿zùÛًˈ¡rši§JÆ2ã^U6x&L á•dÁ‡'Cè ˜”¾û;Ÿ¤¬ ÎÙÚ&w6(¦…Û»$ž*ÿF”Ã5"-sΤ;q˜´×̉æÒJ‚´—LE#VOœƒÓIp ˜"Å­nïç³ýŒYß-¦ŸÎ‹Åt3¯¯nÍ$»Û®î¶¬žOçƒÍ|<›}X‰ûß~~ÊùÁ¥"ΨKÎ1cÄž±"\r°`D8éÒvâ0ië™7rOZ¤­eOº´Â1'a޶ËÕr¶¼¹§®Q8*×DІk2Q… fo‚7š.6Ûñâª)‹õ,¾Íô.¦[¶]O`ò~œ.ÿ¶³zµÎa¢7ÝO6Íÿ¥ úÓGÝÒ{K¸¥-óòØå±Ü÷+FܯïÝR ©éQêUI­÷èŽÐ«Ž’“£]1Þh˜³:#ã:%ã®iBžÒÉ׿¤JÕuˆÃ¤¥bÊ5 !¤%ß‚^*UŒ9ú¸†Å{;›,n¶·›okøùkA6˜">©Š“ÊŠˆà„"2§zÅ€Hõz-—)0g³/Sä‚íÎõƒÇ~Paj#m/бDÒÊ‹˜`â Év "“@vÊ÷¡=†Ä¤+RzT:DCa›&!ˆ¤e|dN¡NGäP’»ã£zlq‚mô!ÍÀ¶)XuJ½î<ÄaÖòdhg(‘µ`óȤ=R <³!d\¨t´o'óñv=½šDõúâ Y¯Ëè @ø³°%Ü;@ä'c2 3êuˆ¬Ð7m½ž/?Mfçƒ_ÿÛ›'Is³ýr¼„PF-Ò±EDä2ñ ÕöRÆô—dêÒÕÝf»œÇ¿cWðó| ¸T\gò2ú¨cyÛóˆìfTbΜŠðæÈz1Cº@õÊH/ûŒt4ûés$6?T:?^]^ÐF1C½i×´!I@åPëÓ¼h+jŒ9Æ%•Ò\B—,¡Ô¶GO‚’Ì™µ'íU:q˜5 ¡)1’Jg¡åö²YI@G“Ïw×ëÉç¨ï½xI÷½"*˜zbõD>«¡ƒí¥¨'˜È¢íÔ-c‚Ї¨¨Bs (‰°¦}dFN1åm;û8†Ê½›çΤù1ýAûÓ,jŽ‹Í!2!T¦L/Õ<ÁÄü¡·-eLPñV3çÛêMÄAm3 s¶- âhØ–JmwhTªqÌŠfÇ"‰X§aæ´Û‡8Ì‚ahïÍH"[éúÀÑ›^v, èh3ÝNê•í·dÙ.ã‚ʇ¤§x[¶‰¨¥ÕþD®Åc"‹ó¢Ý±|ÏîêÈÍ8½Z‹¨¡nAÇÛ»9DÖÒï¬í§TŘ˜²£EÔp78tþ¦’("†iáïgjĘª£%ÌP/€+4ÝÆ "Üiî™6½ÜI013tG3Ѝ¡npμkJ½"ÂŒ}2'ïÄ€£¯“éÍíÊ¥à†ï¬ø¥-×ãùtv>¸ÏçãǧãÙêvœC­€> stream xÚ½ZmoÛ8þž_!ä“‚«Y¾ŠÐÐ=ìîÝn{èvܶ‹Bµ•X8Ùr-e“üû›!)[ÊJŒ­÷%(ÎÇÃáCE4ºhôãõ¿ß.üÒˆEŒrbŒŒ4eDH-7¿ýN£Üü)¢D¤&º·M7Qš”¦`–ѯ¿\|w}ñúa t³èú&âTÅ£$M‰†>¯WÑoñ÷ÙfWæW ÅU\ݸßëÇïùïÖ¸)ÚVŸ©¢Ëf»‚_võûõOß_w‹TÅÌÄÝQ B¤†0•†ú '©IÿÔ…Láܜ߅åóH‘Tëi3šp°’TÉ´£m`àGÐ0p 71!Z«è3»m1Ô8Ð<Úœ‘r‹1M4ðÍ.Û7ESTÛ¼Ì7.{ŠÕÛ˃û úÙå1ÃÈ6Ûäo?3!ÿŒõÀÎùX©Ñ¤"@ž‹šnÀKòºÞdeùeǾ쪚‘:ÿæyXeMFšÇ]þörÛx_±mò}™gä@ßc^_þ5Àž‡Ÿ¤WøIÁ'ƒáR’@Wãñ”@Íè…|³)š»}~L²¨›·—×ì•»2._‡ˆ™„t% w0U€Å KÌ,ÌŽñò¡eaÈó2 ç /Šê&f$'jž”éF£æ‡–ˆ!#LÍ ƒÌ ›Œßtu€›lÒsPÓ 9Fͧ–ˆO¼5DkÈ05“rÃèA &À  )ä,ÜtCŽqó¾åfÈs3 é 7Lø’˜¸a'D˱¢sT=ÃÀ$8ƒ ¨ÚJ‚îù'm݈§‹ ñÇ *Q/BY/\Õ‹^)ÝÅ8j& Óí+¥€DSì„'ÍR7âibGœ+vÎÇ:È ír‚t.nºŸˆ1§Ø¡³$Ó.A5(SN˜œ¥Ì÷bNz«tÚë¥iY2’(¿3ó€"”†%ô,$uBŽÊ¡öÍ@Ðs4 ñ GZ‚üô/~x@4JÍIÊÓYHêÆ£BÛ(ìðr…Þ®°Ãë~¿2 ÷ U‰ê_ñ€º” âù,'Œ^ÌQmÕr1`œø‚näA–”²ZÖ±P RÁ¶Íf9…ôbŽê¯–“ fiäA–dz·­M•*å !OÙázO×hâŽÔmª½BæM*‡…y‰F;»‹qÔ^"ñº–”¥äò%/]hB8ðÓ‹³´~Ü”¡Ù9?îð8aËM½‚44N<ê½HA¿ ‹ Hi¦ÕKþŸý‚.Úo $îÃÿ8Rô?&`:!.$n€7‡ÞìèŒùgazµ` *Òwûl»¼,^C…Jd\æÛÛf]ã…ˆï‹Æ»‹-¶ù㠜پÈìUS»{Ùvå »æ«í6_á ÃÒ&FðhT¤Â§ê[¼ 0”8Õ) sÑ6ÆLI|y·\V›Muµà,¶·`Š$¾©öh踽——µ»ãã-Ì VÒþŠ_E`‹ºhòÚ5ÉvW,Þ•¾_7•oSm|k,^9ô¤í`±MucÇFaX’@ÍsH³«…`I|,z+tXÔÙ+4‡†Î®ó:wWýØK½Ĉ /šµoWg›ÜßÏçÂï@Б¯n}£vöºýœ/aÒRhñ³•»À!ãoIÀâj[ÃV–o—E^“«…1iü7ô­ò½kf™—é­HœÜ¹3çì v¶m Ä<À›'%…dBîñOå-/€±$‚ÆïêúÎ’€í×YÓZŽËN'Æu±V—_h…üzñ†g-Ë.<;<ÓŽkIÓ–kÄfxü®¬+˜i 0—GÊ ™*©‰¼þô—8g¶Û•æ¡mQµ-}ÏŸ)“ûºqVfnþñíjÛßþ²-:Ýæ[åMŒ:+œb­âVÈØ=JFm¹‡d½‰óe㦔ÇÆÝÿ~µ‹Ï¥†°Éh»¾ûZCÜaÔC(wÇdzë-îs‹ùIAãÈcÝuâ6`·ù!ýÜeQ»~óowYé›VmÇpNveHÈnŒÛSSõ3¥Ô5ƒM¬Ó Z%°®h; ‚¦ˆÚ}èG±¡~à,§ÁÊ¡n@âØôâñý:‡ôêM®DÕ·$1ýÒ`™âmz€‘à n27çp¹ÛWnÒª½§—ûù†ßÂÎÉ¡Ðú‚‰ÅÛ²MÕ§X¹dD‚Z ÝØLèÆMöPl\2.Êâ¿håe±v;‚ßlú-¸¢„ÃXûëØ“6õ¹gÙß®nçt©}XÊà©}/ ÌÑ¥»¥—T §¡+( ®V¶ëŸ²«Î7î¥38†Ë{VÈcrc$ôx#h±¸ù—[£Xøž,S¸gÇ¿ýeêBôÂÂIJã. ߤ]K`ÂZ˜Wa(’gsZ¦Ç¤¶s$Œ"¤joðû Fi‹‚Bî·Î]¼ÚqL©ÐÚÕúÙµ«æ]»š²ø_kü> stream xÚ­WßÛ6 ~¿¿"èK ÖY²ü«}êuë­Eov·õ¡PÅQí;°Ýå¿)JN|KÑaØK,QE‰?2ñl=‹g×±ÿ^Ý]\¾ùLä\ŠTÍîV3K^j–Ç‚ UÌϬœGBÈ”½±ƒmÖó(ÉSöËfžv¸ù0ÿãî=XIgBð2M%Z‰g‘̸,RÚ·1°Ifì‹HÔÒ¬ô¾P³ÊsÁô`ÛæIVmGºpLñ7µýK&ˆ?ã`R•ìzo›eÛü–¿Àè*öÃ~êŽäJ;3ø£;ç~ÉÞó·¸K)Å>p"«dÌ~'aÂ^7¶·Û÷ü5OS¦iý&lú .ØÒþyO ŸÂµ©Iú‘Ói2ñ ‚\’?ÜéÃÝúÁ@4lJcveÛºÃ`}8Ø2ã€ü€„¹´ü§q?âeç îQ"Èždùlol?~ªåqþ?£¼ø¯( pÐCXvµËJ@ÈJ÷‰ÔÝ ªö´›…Œ )¢¿GÔã¬ÖÝÚÖ;“pAø9ƒô“|Uˆø·’æ-¸Å‰Ã­Tòˆé1ƒ_ÇÉYÌÈLð¸áiN1#SÉ®€öØwp£x ñqãà‘¤e6½_*L©SVfQ+op¿‘,¹Ì ÂI A“´WÄž€?BÆwÄ¿»®]wé g¶¡/1„žI[WóD²ûy&™†}Ÿ³O€)s Àį`}»pá8ÀÐ*š‡`ßÏSåÌ;á°Ñm_]úۥîùÖ“9|½¡:îÚEm¶^«¥ë{ãÍ9y8Eª"Àªp°BÁ·¹W=Ð"GÆ1{×ôƒ®ko4ÇWî m8½Î]ò8K]{–B«‘À!Ý—zÐD½ú@ô5»ZÛÆ,I!ˆ‡@3«¶®Ý³>ŒæzSa%·Gd)ž¨,Ä7Q<ÍDÀU+wvûM`H.²l § h øjü¸Õ!6iîa *¼~ã_ÞžÆ]´&=R¿_À®a÷"Iw´°w/yø¨e®ŽåÊôV7$Õ;pq–³ 8KrÏݰ¶s.Q!õU´TÎ5WoµõvVFû}A¹«´ 6ÖK(UŠcªœs´óф̨:» ãCÈò1áZè8ªåh¥7†¶Ü|9ˆgbÖaMÀÁ¯×³Ïn†ž—“’áÊH*pŽÒ´œ:úb˜ç%ë qðÊy^0ŒÊ4}®íbáWz•¥#ùÃÆÒcû]ûáô•{Rr°ÆÖ'ȶf Æ3_nÏøsc†®Ýùܳ}ô”/CŠI­’@^èÍÖ4_× ¯KÓÆ“ôQèh‹z§Ô`¨FHâó[ˆ:rHVxˆ)C¤mëž&¾­ŒÏOA¿‡gã*Êm8¯—t£á)„Ð^’ ˜³ýÜ?9Äcëå‘B&L@ÅÌÕ‘BF™pdþ¯H%æqì{˜7ívgi³,äŽ)âXè‡NÛµ[à©ÆNC€òo}¤žzbmý“ŸB.÷$Ä̱ܸÞØŽwýÇ#­bh“IðÛóæ®>Þb‚ݺ~¡§Ä‰2å.=ù”žµAµitF/m} ‰>6Å¶Ö —Ñeæ›CØý Zp—"ä-ܤ?ñO9ù·ØãIP´*÷¤:'´{›v_/iÑ£„&F÷UOb ¡;Ò8Ô:lÅ)ï/Þx;_}Šlëçdfi;ࣶ;Ì á›£à­ûtÜ-Bë"2öµïªËç$¤rŠÂ%îW²Ñ¶ca!™ã lÞÞg{GK£õV§)êA i·|Ò}Ÿtáò)x‘_Vm³²ë=Þ$ŠE‘i0šÑns€Šg^7ÁDúÝ{§ž²ªÆ+èfT+y™É£Ö«sù8qúÄE-wÝ ªJ ÷#)2˜/£¸¨IºÀ§ltw )ü­P‘¸2Û,} =y hïx®ÆØßøœÇ <Îó xRè€Æ÷ÎIÆ‹BL¹ôˆV÷×iÊñi mшl-Žø“ŒO ž( (]Ã]8¦b¢ôãÝÅß²wa endstream endobj 736 0 obj << /Length 2689 /Filter /FlateDecode >> stream xÚ­YmoãFþž_aôËÉ@=WitÀÝnw·=ì^÷îò­-r{b •%¯$o6Àþø#‡#Ûr·NŒçâÃ!)’æ“å„OÞ]ñøüáúê»·"›Árcääún"¸dÖêIÆÚN®“_Á™`r:Bšä?Ûª*ªåt¦2“|\M•H®‹µŸþ~ýOàf¹ñÉLJ&ÒŒø|œÊ,qmKÇó4©7]QW- \µ ¢ o˜Š$î‚—À9z «èù€óõ¶¡ÑÂuލÖwD‘õ§mÑųm±.Jt5Jb Í´NI̦G(íîåÞÓä‚g–Ìë5¸^ƒÐ³²¨<Í®kxfɳéLK™\ÞU¿æè,ZüÆ…ò¯æ¾¥©ÛpĆÿ÷øÏû¸¹[ù1÷;á•J¦É¦©—[·4r'ÂÙ”ðbª…Íñ=eŽÿ9ï¬á»·JL!cZ¸Ax-–‚gG‡†7¤U°B÷=¸8ÐGçþàZºøD-º®nhXT›mwU©¡æ†iaû·4SÃA ø.‹1STš ›÷g6$YY/}å»bÅk|¸9¥“Ÿ<àÜ”Vœ³”gGw°ŠJþ_”R¾P*P[Ú¿p¶JH¦¸î÷ü¸‘S½žJ›lÛŽFñöh°mý"k’We[g«² Ó8^`ùþ›¼ÛÌñÍ€M’åúh?UÝpeX&†°{#/îྴ6¤‡@€þ Ž%’ ZpRƒ’¦V& l–KÔìÜÃ*H¢³Ýa€'b8,V®#¶Ëšž÷E·:zã¨æ•V,“;+œµOª^íUѦŒËtˆ\}M±)ê ©Bq;¢]Ùù†–w&±³á,j%¬Ö› º•œrÀ9Ó¥Ѐ¶+ï-‘®¢g”Ôd)2×eܹ,>‡H[îêfíÈ,ÃY²ÄššdîÊâ¶¡ #ÁªêÃb 6`Rž\5¥ö@·0½L!93{ÇÍÞõ±‹µ)2;ô)`}W—1æ¡CùøÂ[ò@w½H•[Gª¾Û/Qà)xÑyôJÓ©e·û@ýá4™+®è)Lì4CâÃ:C–DH+Б¬ÍƒG”ÝË  F PdïTHõbãj»ª·e4ð’$ªÿˆ¶Â^íð«ñæúêÓ•’OÄ.{0œ3m&óõÕ¯¿óÉÖ@L¦r;¹;×a2–Á…ñI9ùïÕ¿)†åY–†ø™*f…˜èõ5¼`ža)u·Ã¦¥[xXXð‰\áqF* òáL„Cªßó8Sסò…ÁÑ]lª =Çù•kÜ<”`È`¼$”`äJöUÁ×±Â! _Æ}̰݀6¡Ê®Žƒ1œjÂäIã] ”âIH¾·ëé¾çÒ´´2¯›Æ·±¬Ô ƒù.ò B&P 6vƒšŠehžl7›È•úz¬ZÄ·PŸ?Õ>"+P-øæóÔèQà,T#Hd±‚ᆡDçv¿ÞÄò!·{Æõþ΀ö¶‘Zžü\õçaC\÷_fc"»õ&Ô+`QP›ã¨h¸òǾ„ÝžN‡÷ÄM½Ýì5½ŠÓÝŠJsœ †ˆ“¿ ¥)‰k:c&7•B•mN&uŠqTÞ ÍMƒƒž^©‰±6dßßĦ“vÛ£rÄûµãžÀ“á§kh(èZ}Æ·ÔŽBn¡†ÖÜþµ7gÜâ–>ÆÐVǃÁæínÓÊËU€Õb”ÃI®°ÚxÈ—£}ÒLplc+N¬ë¶ §Ÿ{ªÝqªmCDu(e¾ aÚA7“ZVbM+߯Š9έh+ $"´ÆõÊ‘[MOŽ¥ÉÏÝp£+Û¸#Æ®vÔMÛâ6¸) ÜÏÓ¿BWqÖÑ£÷NŽLrMޱ|ˆ‡wÖPÇ ÷%tE¬6ßC7ICŒ63á}Q–ñÐÊv¤ZïšZ²èTÖG_ Â% ¯›9ýÍÀ¶­‚0@;ìâ‡~gdB/±j#³!œ p“ÅËÌìSzÛúfÖ+ƒ¿ÊG®®½dXDºm‹eEtGzƒÑ`8k 2öøéÑ»À˜£F/šîÌȽu¢á™¼Eë ú„E¿peù0kCü^ÐìëÅÎíuÓsœ>ø0 ¸·qÏP´ÑßFâO"à?-u±Šê¨=»ëô›äm|‡ ²AÉhPeil”eg6ÊÂï âd~©¡ Lõ0>+ XÎsâ³QÁ`f7j¬S©Lì”aŠU”‘Â(÷ø†p¥õŸ¶á÷©âF>„)ã©z†ü3|)S¦¥}IŽÿ;)DÊìŸÔ ø=q±z’ðݶ}“=ýéô+=¨G‰'K§såAÄás-.‰çLj½‡ôÃs +ÐcLP)ºº&‘ÃF•î1½b •{$žÄt¶@#˜lÆòÜ\g\Ú=¦‡˜ßOc:W L™eÊf—Ád98÷Ò›ç@:WžH©…\3¿ ¤Œ‡ß6v˜Þ¹ßOc:W LØŸy.‚ êÉÕÓ»#L"£ß“Ó¹`Ò93é…BÔhXï û` ¨¨“Qâ\™Æ`¥Ìdú%_ɰèód¡2óœ~؉¾˜ñ7’jVÛbFgOÿŒå¬™ endstream endobj 742 0 obj << /Length 2474 /Filter /FlateDecode >> stream xÚuÛ®Û¸ñý|…ÞVb…Ô] Øݤ)Š ÝœZd--Ó6Yòê²'§_ß¹Q–‹‡sç ­‚c ‚÷J¾o^¿ÓY uTeY<Ä‘N« P¾e𸾄»Ñn¶i’†ãÉŒ~$ ¶Ûlã"ÜË´îúÞ‚uíÞµGÁïîöõ¸¯ ;¡×îÖŸN]ãOí­ŒNfØüþøwà~«Ó(MsfÐl¶IQ„r¬­ÝoJ§5ó°1;†6?n¶Y’‡ÿE ¯ß%ñRat‰ÞO}×?1Þ­~’<ª´öx?Dˆó€sôÇ€¿¼¾l³2?ŒÌƒ˜AwÅô£i7 ýÈpTâ‘% pxfÈt™zÆ4í^Äê6~Úðêd«ã,*óòV5,|7µ{ä!KÃC‡¤²„5ž-ˆ–Àé 8u-£wýž˜ÈØ–øµí0õ–—ë®E^þd†Ž¶­e K›üqïÝn·jÅÁœ/í#0µÖáØg9,¼ôYÇ¡£³FÛÿ¹‚¦aèÁ/Ë–|)ÂOÖO´SÈ üm!¿s »Ó¼ºÒ›.Û5Ư&Š‹l¡qž?¹›‰#2x°#ÆN¾'YYÚÜ„@™6:dš9)õfO×ìí kÓ¸]oF&!ÀÕ¢k±Ã‹`0»V)nßÈ„s–éº";I&¢ÕÉ—(¹Úú#1ðÄ-‡OG4ã×ùŽ5Ø?&t¨W7ügÌc 9ešDi‘â08DMàwéê0]:Η~•‘_!tjïý‚ág:øÙ&Jžj뉙zÕ]ê ŒCv£;Ãlà)ÛµZÆ ‚AUúb‰f^LÓ<óº“mãeê-ÏL/Û»Ö#ì“€@Ký“V]âÆ’8¿²ƒ¦AßàØs_6$‘©"™ɼd­0º…'ö[m/#zѹ ~O”%aÔO»îÎV€‡¾;£^%dZÓ<~åø¶wd9›ózÀÒyîÍh^¡ŸAž‹l$CÿØž-;ÃÀ˜”sˆæ“«~b°wMÁ’|l·E1GsrÛ3š вžÑr% 8å’c:Ç׿È8ßmÊ8¤¬ÃTãÚ‰g"Y\I¢GjÞÙöŒB¤¦3²¼»&À#/$Š;Ø1NèÃZ왺æýSÃdÓ¬t™~Y IX)‘CÐÔàø’`º, ‰“…¬y:ùNŸPr-‘ùà£'ö‚>rphH–Ê»2Ia¶çõnq—1¤q­Å0$ͫ𭭠0$awb³08ñ±\wMck:{…7ÖuìiÄKŠË„ï(à rÄÃôkËIºåé“OÝ4òİIÝqrd„çM©Cò-Q†XöÛØ^œ­íKÌ%IF΄#©d{ÛAŒŽs1YÇ3Ñܳ_ƒ›ün¶;os RfÏžït9ˆËXçܶÆåè¨lªnÒæÊßT¦$¬ãªà#Ê|5–ï3>BÙ(Uø?ËU*8²Û' §‰V¾LB†ÐÆ©ÂPO͸5„\U÷nYÍn £å½S´/ŽJ®î­¡XÀÖ¤êˆænk‚Ïÿ䧇;O(Ê(Nr ¥¢2áÃÉCW”‘‘«r©DÅí\¢Rj”4X8 ¡æ+ëNkjÑa}Õåmä+ß¾!]ŸyîkmUEU¾Ö^3p ådàE²M¥@Àïò‹GE/©7ÃÁm>FˆäcBWfå~=Áëébô"§…¼æðÈòà.ñÄ76X¹1äšÄ`øCÉg/PÃs¹0`Tò§nÌ0Øáå’ïªëäÂpr‘̹Æï ¤d–wº½^dåòÚ2uß‘ÜÈ·%4˜L°¼e6\Lß?È nGR87AX6Ld ˜SÏ•bò¿ÖÚßq!Æ8üáwB¦æ€ŸÊ¨âB¾uÀ€Éxy¤ºv7Ç®G…BúÂNg¨å½ÈüДùjÙÅyT<”÷™êV ™¨%¦=¥<dXâÔ]¿ÿn÷028ÎŽ¿5+·¤þ z´·X%f1œw0P1aB¡‡}¬ƒ"ª ¥ù®H£²(‚4s1¡|-;”Q•¤Ávv+·ö`:´fîæ€õÊöEˆá÷-í«x»¶ÁkË8 B#‰J­ïžYÈ1 Pb­‘_ÀÌ^Keœ®‹ ôòœ¤®˜X²&5¤¡*a©«åƒzP‘{†ñÈŒ#xÛÀ³Ú´<Æ'Þ æN;iª®éOÇÀ]vw­˜ XÿÕàøBý…Û…ÛJª‹°R¬¬ø÷ZÎ1XtG"o±”\*›Bd…úIGÉ”U˯ø‚–hy¾¢4˜ùGPy?Ã…3=>ˆ¯Ã|áë+VT<ê\ŠGN*Ïæ›ã6˜‚’`ö›¼å¨æ[ ÔmܷܸÀwT|×rèrƒhšÎ?t†¥¯jy 7\;û4ÌÝú[+]Ž©<¿ çEŠòa~vüvK®±lÒRº›@Š"˜áÕ@Oo{ëüâùéó[CôŸìLs½k‡ÓéÙ_Ñ ÒÓ‹lšA³8ò%Eøú wp;¿‡ÿp@Ÿõùï⎷%îÞ¢··²ÁÈêâ=öæ¹R—e”j¬ƒ«¨,Å)²ä ª¥ÿ—ξ0 endstream endobj 747 0 obj << /Length 2326 /Filter /FlateDecode >> stream xÚµXÉ’ä¶½÷WðÈ OQnŠÐed$G(B¶Û§ÑØUè.Z\J\¦»ýõ~‰LÉšj9²/$–DÈ|¹!ž‚8øþ.–ÿûû»¯>¨4P**ÓT÷ŠuT&Èc)S÷Çàcø°Ûë<ìçî¸Û'… ûÓÉrcœÆ©žæ©î;ªÉF»}Z–áý©Þ„ÇçóÜŠÐ ‹kÞµÐÙßæ «Ù¨¿ÚìkëwŸîÿ‚ 핉ŒÉøÌL—a[½Ôí{Ì-|Þ¥iX5³ÌóeШø÷0TÝèOÜol÷4Iû—8…\bü”ïp•Wn_v¬Z\‡8LÜÇ™ n…Â6Õy´Ç[çëî*“ÆÌФ¸as´ãă‡ª©Üí;8³k¿#- sÖ‘Þ¡ë¥F´mÝ-² :-¸P4=M?Ó‡4DC‹†Æ›‚®~uÔ¤÷< {’Èg¿žFX.h<ŸúFš£„œd“›íµhb{­Ñ‰»»q ‚L¿}käQ È‚µ‰#éÀDIRòµ¬dÔ_CÞDy’û=ábûQÎè IÿV5LUG×”yNüYö,Ô“Ö^•eºAxO ¤SM¾EÂI’­‰ ÿàzý sð«œØ–5àÅÞ^ì*¬ždüÊ01B†É­£åûXÒ,³í¶·TílTÎ]MPS°g±«;þ3–Ô5TA{`³°ÝΊŽA(W&It•kN,¤Ú: ·õ™)Û1zè„‰Îøzø‡Á:¼bÒIc,Išœªaâ9'åõœ}±'ÊÈí§ò(MË­Œ~>Ñ–¯÷,ªØjÛZÁ1M#ëy íÝŽ¶ñ&†XæéÔõ¿„©ÏÓôLÁÒy3¯C? vϼuÐŒŽ-Š¡¨ ´ŽqÿA<õHôß²mD©Z•Î:ˆâ©_A°#‘Ó샓†ðàß¹ªÖN¤K¢x>ÕÞÝÒì…äàÿ L·ëÝÇ`ÕrGBD«©" iþ°òjrÂw¢‰‰=çÎì8Vë0s1¦…ª“ÿù<ôÓƒ®›äÉ6ÊåZ‚Ó‰½K² M­Hs˜»®îžüËôUW5¯cM¶”¢{Ïãzïnœ ò5>ú%âÛïÀ>k;qÏ{'ïÅÑØ€h~Óð[¶ó«e÷9)›ÛzJV?ÕþŽDÔoÙóG±ìÓ‹;¬„ç:„_¦Ó%”£0Îkà¥À§„7Çh´ØÅ­eÔõ2p¬‰Ub{‰o <†‚ò<=0gÈ9WÎWïáŒÚz8o=œ‘”kµ"f—QËàþ ?ÔÝ:wbѯö|Ó¹“Dèæä²˜CàEæ:æþòÎNH˜Nêì)úÑz}ùå‹LÇ~þRÖyCwæ ÝݸÁJ“ú¢?´ÎhõÊQºÑ¾ë#”â‚°3òøoë®>ì öÂP®Ö`«±ïÞ¹¬B¹Dù7{¿àз-ÃU;iÝÊülcNœ‹&—Œ-/¹’%çÔHq~ò¡ÛæQÂb”&ej…;“Y9Z™½2ãÜ›qîU,§ºm—˜ãMŠår( ÕÊש&Pž¤Y*ŽTdv{¥ ÄÍDù¸éRDÊ£•dlæ éâ™n6 ïôŠ·Ö‘ÊrfþÞ’vq§ñ_}HôzEšFqžc!ßb¿–Ý TF©§æƒ ˆè´ þƒP2ïA¶íݸ#õ“ôÜxSwBÊ\¸8¢¾³ŽØ 2Zoâ8»EÄ–^ÄCÖØóü* ùú*÷M̦ÜË#ƒ‘½N¢R‰:Á/¿^´‘šE¢Vr;UœìÞ}w÷›X„ïKTd&ïC{÷ñS1EIYÏŽ² ’(+iUüýî¯\•^혗Qf4XáœrLØú7ĸ½Á=Êd K™¼V#$ÖþôΤcSÐè$tB¼K‹#¿F(“ú³“ÅŠÕšI,¾Ÿ¤\mðÏ¥T£®øÓŽ›>— |ÄîîjºdS¥df0ʦá†ÛK2ÉýKd ¯É—†ÚË"ï_uàâ‚ܼÌÿôíOßr‹½3çµäÁWŽìÇidíc57’L×2È™eÕ=O¨ïþ”E¿‹Ò½C•Rª©ÿ¥ HÇŠòð(-HØI Ë,J³âÁ´H£¼4ŽW’‰—{: ¦`b®ŠÁ·ZjÔ¼ðù_ùPAÁ%u>ÙÎ.0ÍË·5Ì é£´·þìc–ú†â‘äžmyIör¾m]»‚žAY¿NJÐ]ÇêO§¡ŸŸNý<ù¾å£ÍPšÛ<¡ú™N-Brc\B2‘ÕÝþf$Err°”á—å[Î?ÓÔüÏøÐQ"- Íix½?‚\”›ÒñŠÁkÁl@ßÂ@Ã/Û C™™ Ÿk²{jµòýmý‰åbT¢¿Ÿ”*[m•GåºSì|òu·/ž^¹‹¸O.ÃUà“]Wú\Á«…·(”+…þO|Gòÿ÷Õ85¿~óJ°M•qÏk]¾|B-"³d ÿÌ7ùšSÊ®ÿ$º²Íõ]§Z¯jj» ~j¡–«Åé?Bãiéh=U'(:â*uéƒC)…+ÿ §Ë.š¬éššQÕÔ>gpÜRÚã܉£Ð |Òè 9jVüãr´™j¶®šÝL×mÕp{á`ãîi" ß¿úY'E—q¥œü:ðb/‹(s¦ž;7o:†/.füä¬ÓØÉ7bþCîà_a‰ŒÎJ)wÃ]dN‚t™8 U—Ê¢zh^™Ç(µ˜=ú­Îüm#’<Á+“EFÿnDRHaJ·>'²¨Ì“‚ŒHdŠ@%x¦«çP@> ʨÌtÆ kæÓ@"<ðašÝ¥KCe¨‹8sSñdÝ]Þ{û泓ü(Ë:^b_¦Aˆ×/?è®_~Ð=rAë×»jÛ5,¢œ²ÐcèûGQ»œ%áRÏy^§·¯’Þw… NT‹¯ðÖÛ°*`¤ ‚Ñ%ä'¥Ej®•÷o‘µ{³ endstream endobj 757 0 obj << /Length 2575 /Filter /FlateDecode >> stream xÚµYÛnÜÈ}×WðÍ’¡ØÞäax½ °c)ÀŽ·ÈÖ !9Ë&-ëïS—î™áˆÚ XGÃîê{uÕ©S­4ÚFiôþ*õß·wW7?Š,"©²LFw‘P2ºŠŠTÀ·ŒîšèS<íìõFæ"®MW_‹xîÌÔ}r½ÑBÇ? ײŒŸ®eÛ¯ô;þº:n'–Æ­ãá½­­sf|fñ4°Øöný Óæ7S¨„‘æpi™oíÞl®?ßý °:Ñ:÷{„ Aß²äÕÊŠÇÆÖL–îqsÏÜØáÚE<<¶ý–[iQhá ÆÑòI¹åž†Ø §yÂÍXÛ_Œ±ßLíç1}³¶O’‚N2Ùæz£²4îÚGÒ\×îüÆè×·~½ÎtlºÙ:®O;Ü,– êMe"vfèlW’¥Eü¡³ÆYî2Zã§¹µ5v&F"ѰðñýÕåFÁ(¤ïÊÖ}Ú(™ÇÃÓÁæÌ5Õëê±=°šP0‰<ð—ùÃ÷Ûͧ)Cëq8ilm`7¿Ê >×R1²L2€} ŒµÃK™H¸ˆ4Ün–6öÁÌÝE†þ9A´§ˆ&C|ñ{;€±äDP}Ëaÿ©oMÏ’?ð€Û‰µÁnmÀ'jtuåqÏA=)+½<Õ¹/ÀÃ]Ûsa•I‚,rThÔ:®¡ªJP•G"êkºh4cWF (6t¨ 5Ì• özógK'ݬÁ_ƒg-¯ÉG, £²ð“÷´gb'X@vò)Ö—t$þÌc`BTIO&á mG³õBo8ž¤à×Í÷ pXHoü®‘¾pÿ¿øøÂ'ß™'iqA™ZGKªœä&Gú®øÊñk›-ê+í·Óα+£À87ïÉWTØHŽ¤Ê²èlÓØpÚ´Y¥M‹sç XøEKtxé0ÇOƒÏ( ”ÊK޲8ê]-çNkx–V‰–ò¿š(Q–ª8ñ"#ƒtër׳³~'†?‡ý]HY$åå]ÀU…ëÐÕEÒÃ7¢=‰…/ÝVÇy¥7þ~0Áñn\7F!)‡Ò¥Â÷N³¿ôbI`¤{­tp8©—gRLéŸóz÷è®}¾¢cÐÌpQÂyЙBcÛsÛÿŠj86 ̓”~Õé÷–h%á‹ÆT!ŒRgËPüX·þ Q«mÚ¯@»ìz@LË$'"$[1!•'2/C7Šù˜¥ó*£9ÜpØ‘P¦ËÖ¢5€ÇëN¢…ò¡KƒÛ½ñBüÜAè­{úx†E¤Ïxß¾a´\83šZã×LL²ÅÔJ-¢ TÉ|QÌûXlÚ@Úq~ZÇ¿—ÀeþuâNœÖÁpÈr†í0»å¬>¡SñÜê«—OÏÄèÁ)êîŒF<²lA Nvtn2$ìùûöìõÜô-îXÈÌžHŸpJ(uøJÊ8ÚCgjŸ,y0Å‚ý¼Êï¤5·€””òÕÐSVI^£Ê«„UeIž!îÈOÓlÅ­uʬgðE^q-K€-±OŒtV í5^¢ÆKÔ¸ÙEœÓ˜Q#dycH: ÐÖy¢€ðâ¼30€ ´ efºèNaj͈Mü]—O2Ï¢J“*—þå'MD’!™Åv׫?ßµ½ažà6+JOQg‰È‹ÀˆBËZà|˜wñ|غµ½õ®‹Õéø˜8°À¯GeH­tG\ÌDä¥<-BM–×€xÒÙÕ×·/kF¥™!ïy˜Ç•lL‰D—2’¨›²ú}Ù'dd¬+˜+<=´ÝZX”IUdßgåR&yž/W>ìž1¼\YÇÒòßce ö%²j¹ò/ð·²l–%Yú},³ HèÅ!Y›Vyì±8²Ú7À‹2ÎRÅû…’$èÆ¯á&õøFB2èÀSËxª\bc¶Î*ôwBâ-1>]I€‡ïcØÈx …>`Š—·‰~øÈI ÖB^‚=ùù: I|Œ„¢1æJ3¯Gï,÷¹w=ý› á)6 ±£°A¬›"¶™Ÿ‹pÔÖïÂÏ–‡ÇJ&:X?éÆq”LcÃ@ÏI«ÐÞ”@ƒ9¬áŽïcY^ƒÆ¯_(õÒíóç}ì‚T¿^GXÄ,帋¾ü}~ƒÙ‚_í•W~^ gœX¢é1ú-™*Š.—Ñ—w¾ÛG˜à §'(7{`6nòS¢RPëEL¶JBèÕË$ÕR±Ë5§ãâô®‹ä$Ï”l`I–|zM´nÍ3K‰t¡¢afäúÃ8ø–ð €å·ï~¸½ó&*«;eN—+Ò A£pg.||ùªYHša|7M‡?ÝÜÜ[ã¦ä¾Û$¦NæÇ›ŸMÛÿûþ—ik/žé.X‘%J”g?T]&Ü1¹Ö€Úø¬¶ê• r&Äê,>¤|I• ½eéce–-: þ˜©"Œ endstream endobj 766 0 obj << /Length 2546 /Filter /FlateDecode >> stream xÚ­Ë’Û¸ñ>_Á›©Š|37oj¼å­JűuØ*{k—#B"cŠ” Ò“É×§_ È1½9Ä:ˆFÝhôwöïç»@¾?î^½Ñ‰§µ*’$ô'O¡ÊóØË­tœ{‡Êûèÿ±ûíðË«7Q¸¤ŒT@ÀOý4 ÑÝýáîËtàiOGZÅyH›Eqæ/w ¼ &ñ¹÷H¤Ø--pYë}¸û' ¶f§£Dé,Z fÍ—SÓš ÎY®Š,ù1œóP¥iºæ|­ŸÆæ²Á9 S§ùáFÒI±æü+ü6Ø&‰J‚sà0)”.žxŒ±lk‹³ÔÙÁ µÛgqæ¿wû8 üÆòw¬ mciJûýI¦hc¡*eÝã.Ì|3È¢cß·×y¦‚, Vqœ2ÓÖGSíöQøÕ44Ý™abŠ€±pWåØô¯C¿Ûƒ£±ö%¢¿QF x­‘ùSÛŸM× h¸Ä–—k똜†þòŒÅ•6ì-ˬÍÐôj¿2mFâÀÔ~I ¾¦ucû)Ðqk>–$è?3Á.Ãj²¢í$ }ÛŸ€mΪ-Y}ØåÚί»MÉ»~,Ç~x‰÷PøekW¬3ÿZxS:åk ß0?Ý¿þpà¹kyDfŸwIâ—g™ÿ$5ì9l½ÃÙcàýÏßÚb ξêq¼þõÕ«SÚQ=4½2•*ŠÃÑ®N0}~õ÷²é~‡ OüžÛq©<Œ#Rƒ†²Âo:þöCeÇž¿` f(GãcßámU;í›î(HkFËЩw«k™ëøâ*Rå´ˆÄ^ZDâ ¹HÎô&'À+9SÇ'õ!+ Ð|&‚¶©{QSœÍÈÂWë–IôþM”„[&Dó›‹ÐÿãÍ.‹5Û ÒŽ¦é^ íCj#™òg2AT}án/ A ÈžéOP55Ãs\ЫÃG.µ"¤/‡f¬/Œ'7Ö©›ÏüõÍð1ýRÕ±!4” åCÓÞê4æÝàk§H?ã$y0˜â,ƒeÛSa‘&ÂpX¸È,Å–™ HRûÍ™®`Ä'‰ )‡Ç¨aCÐÙ"¢˜•’³ED»X@DÌ¥¾Rí.ÆC² \ ¹ îIÙ}ûž29b®0[åÅŒ˜ñ#çFð±Ù–•õÆò,1q%UÖ=4‚RU.—‰?”À å•aóÐï?|:$×sÝÄt¸OßIAƒ1o8Kðƒ"ÊûH+ Zj•­Šž[e›pE’kŽH[v─i!—+‹µ†ðï.ã‘»%„¦‹ÃÑ­`#A¨6d t]8&£YÑn(p#p€rŠŸŠ%` 3g'¨9;V¾v¬Ü9s æ!¹Âmâñ4J‘¢µ®†ÊÓ›Š6뉾m¥Ú ×>ùG>'?„Åòm»¼ ƒ#UH‡¤µrH€—‡\î?»‚LÀ)¿kÆ14 Ç&¥Æèv\jiØpâ¼ÈUCg¹ÞkÛftqL ‡¯œÞ¹ïL%^?lFß³ÚqìW\ïãÜé)ÆÊŒÊ®xQvÅébWþ°(gãE Ç+].W@IÙ\pfºÌ{~O™aâ20[šåñX~“¥¡Ó"ž1š1å „뾕 ¡¯'þ.B.ÅË(àXZ`V‘æ ñØ="˦zVgŠ—A%vš°xbi 06²ý#î±6õºoA©cCµ8|+¸ÏŠO!K@/ƒ¬x4š²¨2ãÞP$“4ŠY?ñŸlšª,¨ät‘{ÞHÂÅóÆòTá2Þ¯Ré>.T–GÞ>CíKÒIÒÑýáî¿$Ä endstream endobj 771 0 obj << /Length 2523 /Filter /FlateDecode >> stream xÚÍYÝÛFß¿BoÕ¢±:ß#õЇk.-®@Š´Y ’ÑÚ²­[­´‘ä${ýñc$KŽìM‹{è“GE9äoHZD»HD?^‰ðûýÍÕ7?(I™dÖªèfI¡’45‘2‘&n6Ñ›¸¼þãæ§o~vÊ©“,3 †8’ë•Ñ6¾Ù×+­\üáÚš8¯á±Ùâ¯_|¸ViÜT¿æ}Á”²cŽ~_Ô¼Ú•Àäãáñ¿Å€vPê³h¥M¢½aÕ/ˆ}©¼¿ãíÎ s`W&‡ý¾Ê®lÊ•&J§‘ô‰”Ž9_6yÐ-$9I%NÁ.i-s©Àe&\dªƒŸ0ØD‚²qGB,¨r‰MýÀ£´¬¤…݃O²Deóóš;@Á¦S Çf@ ±µ âl¢¼¡‰ÏÌÅÃשŒ&\°}¹ .K<¸è3qW/n®Þ_áiˆHF*Á©‹œv§£õýÕ›?D´—?E"1>>ë}d}"2Ë*z}õKàÙ ªÌ%6ëœK¤H/¢Ìþާ˜]p<¢™žâÓž×¢"M2A Œ ÿí’Ú•2>Ñp†œzAâ¿{H{“Qãïº*ò–VÄÛöZÆÍ=?ôû£xÈû²©ù©ßçAÂ=æð¡êˇ걬áÓYäkDŒýb@û4Ên=ÍöéhNÁWjÍ :¼µ<ØÖÔ]Ÿ×ø"ì9¯7„J+•©D€€•4‰1Á›òC¹)ëÝÒÎI¼´ŸcÑ|WB߈5lI¥–¼èò{ZÙ“íá»Mƒh?ÖM ¯‘gŸ×»b&ÌN1éˆÙø;ÃWIH¯!ý‚e+ é@2qÅ'£ŸÀ>™ÀEq¤ߟª‡àîI¿ªDëÑûy[°H¾ŒQèËms¨7Åæ¼Š›–_ÔM½*7{¹|+¤Éo«‚˜$m‰5uõÈüäZ$M\‹tp-8본™_gFÈx×¼¸Å‰µèúòx6ü¸m)ÙÄ H›¼ÏB[Úvñâׯ¢7+çDü ¶+ø»ûüîz¯âîÐ1!IaõH;;0á£q³í“v —ð´€Gª¼?1)mß´¼]õ¸êç_>¯²ŸáîøýG®|·Å¶@Øi1íˆÒ7ƒ´ùfÞ>œ)ýPÄt‡[`è XHi‘=:TPTúpŒùiŒ" ”Š •!†¯WR*¿€ÀÑź‡:G˘¬°˜ÉÕ°.ÿ[,.ø—.?[ÖÇ/Ÿ¿|Ž+È傳».ß“ã´+ê·Ý1/ë 4È•3¡ÏÛ]Ñ3iSv}[ÞÖÃ۷вæ·Í¡]:þ5„äƒr2àŠ±ñšrÄ%câ:Ŧ닶ÄÄBäTWöÂÁ7>ðû·qÀÚr‰Ø#Òø_Qð/rª^æíÅÆÈ‡ƒ ÉuÞc8/ì—AnØ,,@Ùž“_exy]x9:8pUÆ%@ƃnM(Hp)ø¬çÅë×¹;Ñ|Lè…H%è–¼e è¹TĨ;%ÝÇ«Ê1ŸïÞ‚ææ¶ÏËp,à*ÆýT…¤ã?t‡„WÕ#ÓŽ¯–Ü;`%gÐt+ð¢ VøšÛqT­ß8&:Nk厺m*@xùq|·mÚPLä¡iÐØ©`¹®©¶e”¥c„Xì´ƒûy¬é~^j¨z„ìtIjÇBL©¥´Í@=܈Pd¸PÙ…z êÊYbE¶PGÎÛ3ZÎJžÓZÚ% *:#QߥRZ9¸+í¼”>©5±”*2Â'ÖËaïB*þz±"àáÓzlæ6pÜä ï½£×ô¢¥‚.ýÕÔÃÿX.Mi±ä ·B»X¡h›{z¶'tnt2•®Î„{Õé¸*ê]¿g"æÒÂK÷Ó>G˜ÄG‚̤H°FÈÒ£ŒwmNaû?RìïÖMÛ÷›ð&Ü \.Hh;õ<Ãð®àìÓÏ•EÚZ/Oæ´ƃ™˜Œâ›<\‡žAqØÝ È2^óϸˆü¸/ù â×,ÉM±¨!•g*B*§œÊl/´áÎÌí=MïSS}Åu)NÙ‹öfjô@¤¡·„ …¦bh­äB~ ¨Ý!µYp_êUU⿘`ƒ0 vŸ aSß$¸˜ÇíA$ÆÿŸ„»%ç¸ÄLÄXùävÞ ­Ú^p(O¬9ß`¯Àk+P æG ŸiD))äˆýL…õ ›sÍ÷Ý*­ÀsPÓâ,Àgÿû‚$¨á Y|É“~rf6NÐÆ\úN.B 46€Bð“jÿ'Îý÷åN_.ŽlæÑp£­ÙÈæ d2)3ó£5z¦ôÓ’Ðæ’ΔZyÎÒ ŽÚü%KÏ»ÿë3áNbî+éèÿ¾z2"Î܉)7ø JX?u'R¥ÿ'+ÒD¢/\gî$ÀO¯Ò™Ÿ”³æ¯è¤Ú܈¡3XwÖ¼¢>8/Ùä-W˜HØÐ2„«Í„º7ÈX4+,ÿT¼~Áø ŽhvîãÚñZ¬‚a-ãPl¯¹Ø†3K ôç xŸc…®µ;ç~œÓdêâ-—’•rZ <®½µ«|‡Å»¦þš¦þvèùµcŽÏRFA=®/W#ÜÞãæÂ(@‡î@c+€•Qjþ}µ§æñ¦¼[¡B¥c5õ¦c‡É fOÆS4$agi4AÒÙŒÉ,ÔKî²ûd"¤;–ÐÚg±ÄBPˆi™„qR@iÔtü6g*ΛڮgZÓnhhôüá¡¥&èö*Ál®pI&ÕBË› •,ÞQ)ÊÛ|W|Åä35_6Âã¤ÆÕBåžp¢pÃÔ&PSlnÏŽ–p.C# FC@ÇÜuåmþWC±;3Üðå‘ÂNoÒ0½yÅS œÓL'$“xXeã{Œ)l+~>Î1. v‚¡ÿ¬Ã$D{ŸóÅCÉã1œæÕcGùOmñþP¶Exê”(·a¦)†¼‰ZŠ–Ÿ&ÐÄ€ˆl‚&p Â&h0a±ÅìB,ÈtÀƒ¢~ÝP6†qûá-Î&y…–€r4ÈÂöB,Y9ðÛah4à Fy‘´ÉA<[Ú$õpZ\@ÙCQ¯in ”qÒ¯‡&(-òÖñŸømÁ¨’¢sšƒÐ§í!|[nO„uåM¤õº©¡Ïg:ßǹ°GÌ`Ÿá –¶‚(Bò;Ø©³>þm_VahÛ‘ë‘g?I6¦äíîÀcc1îŽjŽáƒ€³þ®|!"+»g>•)Ôë’ÿšMEÖ[?c‚FêÁÞuÜ endstream endobj 775 0 obj << /Length 2255 /Filter /FlateDecode >> stream xÚXKã6¾Ï¯0æ$mE¤ÞsË™Ù,0‹Á¦=ìä@Ë´Í´,9”ÔίßzѶÜJìId±H‹_}UT²:¬’Õçw‰|?>¾ûî“ÊWJÅužëÕã~¥WU¶*«¬Z=îVÿ¼mÖ›´Ê¢Sï-¶Ò¨ïXbüÖÞøWîîlãׯUÔÉ”ñhDuè§n'ÍÆÙn­«htß•5,õÖ }çºÃôë*jÖºŒŽýzŸ~ùú—Ç‚í•ÅYV\̳Ïë,ÁMqƳU½ë=7wn½ÛN£ëÉ,¹ðíø»7 Í«¢=¬3µí+÷›iÞŒv7Ÿ3mØŠlì0ð´~Ï#Ûɵ»Í’Ýx8e>¥¹;Ûr†–ÔEtKlgqç%¼#(õÛÁúg4Œ‚¡ž4ñzSd:ú©c½³ñ£k¦Öxði¦tX¡ ›U´mí‰û`ñ‚•vÝÉŒdl–'àÉgt±õÛ5–e öa³3ãä 9»­ív2âÆÁ¶{™Ðó÷èàlžoÙ5¦eéGƒ‚WÚfpž³®>kÁ48s¦3˜8 3tÍèÔuƧEÁ‘×TÑúp=00 pŒŽ-ñ4­°ç¯¥óö-a‡EÆË¢  ‰n¡ŒÂÆß’<ã-˜<ô'ô|YGö÷Ñ0ª@[±l<ú~:ûi }R†è'?ÈD.À6ÁiØ, —pµ0~çWÔã¿tmÎvš3 Ãðd8SZRÀÚg·#ç€#š¾;ûÛ>ãÞÞ›“}!Óü“ˆ0±áº½õž`„ÝaÚ°ÆàT×Óê»%ÞC/Uz ˆ´ÁÖ¡ Ø«t„HuôTE÷¨ú&jCì` ÄXæ8™'vwÂ@ ¹°[7Hð/_÷ÄÃUôÂáŒ7½çIxgö`ˆ:ÒîO8´u| PEZ mÇ›uŽf@{LeÒ÷Ü«"&v]”¸Eq4MãûA†/¬9ØCGi7øUËÖ• ‚’Û Â’ð½ìSF¦í—s”ÝÁŽ1Ž@Æ-o3.(¦IœiÅŠ*‰al½QJçÑŽy7-óèëqªèõ¨V–Éï–Ñ:VEÉË<Ò-i¾¥Ý›©Ep¡OÝHPc¼g‰>àŠ—²à»Oi6« Ê8KsX_Åy¡y}_y7é®Pq•Âiž\·Cwep¨Ÿ…¬Ñ²OëJEp@#h˜Ïçyô«mÆÞSÕA#=Ï!öÀ;ü¹‚ÜÈÒî„üîû«ÖŽ€·ïÎtw ·ƒˆÉ’œ£G;Zßc(€·ˆ0Iôæä…Á6Ô P{ÿÀW–În>M²8¿:éç×a´˜ië›0<³ô£ë!Æ G^—P–±Ö:¬øÀЉJ‰ ó¨Ð ¡ÿ%0Ót1ošUq­«ù]g,’Èu çU­•N;ôÜbGo)zÉù 㼇-ò|ÙÏyìHÕ]Q•C|…P“X®äÂ"Ž/n`ÌózL1ÉÙÿƒdõÊ)„;B9-*‚2fÖê6³’F¨žx†T…Eù6•Lª(lî)&pr«Ræd;³XZØñÏ@ͺÖ¾FôÎÆbëQ$0T¢CãÇç.¦Š".JõjɳŠ.jAM•¢úP© Ìb zZ ˜«ŒëTæÓ¸Nª jáAá¾¶ÿlû¿A~‚V‡‚BSâÕiJ´] ¨æOÜ‘âFï±'“¸„MHXœÆ A¢_6Dà,^ií°ùÁö‡ÅºßÑAG©yõ¯õ›BU. ûoÓýjüŽ\œFÿÁ:Ƕœ%Xó+v¨åø:aî¹ EÄ~™•ÐK•àýYHÝe.(á'…LàÇüÆgîAOP©¡v¬°v|•Cùò}³èÁÆžù)£wž¶­ƒ lB¸éRXã>&”®ã2S Äû&"ÀV1¼’ÃdáMT±†wóÌÌŸ0å&PUžæ B™áÏ㟸”§”E²ކ¼ˆÃ½° Œc‰”ÔT¤Ãa¯u:ŽËƃ{Ê^Ä&Êž\йH‰Îw3άê¹2¾OðmÚÞ†E Þ#,1ܪó+â/úJ5­k$<,Ýz SœÉ³ ͲËnÝò7]¤NçÙ ƒlyáÆo‰Î—+Ȉ7<—ÕT©°ùÛ(€ý·Î ܺøcÑ‚¼Œ“B]-HÓE®U±ºr8‡Ÿø€+…¬ŽS¥îjšÛR)<b¶äGï¢yꬨnÌË–”©ú›¼,¤þ„µ)cÑÎ ÿrtÿ¥0EIœŒŸbè;‚øÅGnuR(ÈÂGëG‰(Æ6œ¾ªÊ9ƒÓ ¬=¢ƒN¬K~hhúã„>°N“3&<û.æ…÷ ÿ‘4ÿ-bªä•eÇ ½Ãæ÷6’]ݰð¢ýWhª¹0²Üéb¾ü1`¹†étQY_ÂL‚¹žg•BžžÅ…"@b¯Ôò.è‹z";Ä5_Ï"Ïî ÝÓ{s1œþÿ o‚Ï w g®5ÆO—ÀÓyz üøAæGK‚o"0¯.0Ç­8˜¨ †#Æ™`yž¼Ø¡°¨ßPfxÃÎÜœAƒûV†»~䆙 Ðõîy;Ö>8ÆKÇÝã”Ñ’•—ǰ@®™ÎÁÅ´¯—¥äï**v–g^Pºx[]„YDÿêGùËt¤?<ü{AXƒ0eÀVI^º!—AV —”•œõýõø&OÙ½ ¹=/t[Žè&¼Gå—‘†”@‹¶‹O\¨¶7$}¸úþdN!ù\bˆ#ÓijÒ¥ªŠÈlr m–W3¥ßýÔÉ)^ endstream endobj 779 0 obj << /Length 2781 /Filter /FlateDecode >> stream xÚ­ZmÛ¸þž_áo§l†ï¤ @|è][ íµ—¶.œbk×jlÉ•íìåß÷’òÚ^ÅíÊ€!rDRó̇ÒðÉÝ„O~|ÅÓuþþÕë„›ÁrcääýíDpɼ×ÇÚOÞ/'¿d‚3ÉÄÍLi²?×»}±^WõÝÍL9“ý´ºQ"û²n~,››_ßÿ+šÓùd&9ã+ƒ6÷eopÛ`Âzݳ÷ÑZA…¼6˜»{C|¡»¾þAÉKÛl—½^4õmuw 4Fèl6+kRçì®lÞ‘sÌO36ŧ0Ôd‹5ñ_ÔÇa9Ë­zõ¶Ïw„cKͤfš'a¾ZƒÏíJ2…ÞFB.öîÊBY±/¥ˆ—U]´_âÔ\è`Ž4n].#çrÖ2'$Ø,lW0ý»~w7Š ›w#ïWU4äø´EQøè8¦5d`Ú&›>Z+.·Í¡3 ô*2BÙ)WžXnžØŸÌXâÉ]¨Q!œ9sÎd gÿ<Ôõ X†Hh“^„©³}ñ‰¬1Ý"]«z–HñÒ&/Û—Ë4³-ËØ:ª$LŒ×¿•÷QŸb‘cSt+Ö˳¥Vº¯ö«£UžHª»k‹-tS¬1Òèlœ.’]¤Åè„Ì‚ä¼dé]mÓ¸`}¸Få ±íÄrG¾‰VT Ü Ïþ#FUizQÇkù{±Ùw¿á Ð:"(qS-“5$ ®Á‰,š¶-wÛ(äz5Œön ±‰¬ ÀÑsÿ{ØíãÝd’)ˆÄ˜ñÇ÷¯þ÷J€E>ÇíR[żË'‹Í«_~å“%nS¹ŸÜ‡¡›‰€É š·žüüêqï@ÇrìµÁÉ´fRú° ú¿#\³üiÕYõ’IQ3Èák)Sðƒá¬Â+^a Îl.®­Á'Ø<}þh ‹„êÙK¹@lqÊ]_ÂÂYõWe,¸eȰ”aÂ$S~Ðý5œâÝÁ‡™H.§2t)  ¶Æ]“ÛééܺÚWËâû7ˆÿÚ 7Åò;•й›>VÕQFCöÈH#R{9ŠŒ´g@eAÌ sAЩ’§¶ð”g"ÙÐþs¨ÊzWíHœ+ǧ"QxuÞQÓ’së¯Éh(À©œig¯/á oû 2WÚ=Øå¶›1 ÐØÿÅôìηº;ð ²»Ôvž$ló Ë-¶¨2àÆËkÂЬO8’9Ž)OHùtB1(ÏËÖ{+M'­lצ1\ÈsÛ4ëæSц@ˆÊÉ«3QP¤aRŒc1êÒøS4ó4 0‹Ynר()™ †À…z© uæDÔn®’¾“¤Ò¬¾&¤¡{„„lõ©ÿ29³^œGçmÑ~>¬zI’ÒÞMmâ†îÜw‘.‹<ŠîSq(MÕÒÙk¢ˆ£Ot0£øÎQªK\ Ì£H‚Ò)ÙsjŠôh^yeŽ6Åó¼ÛÅ|¤º*ŒPz¤Á5"¼EÜ0-O £®VMtcÉÆÕ4P扢PD!',…ê¾½v(§}`ÜP¾(SzþÇt”CéB][ByÏŒV½I_\DyœÑìÕE„@n)嵤VR6„µ,3yþDNKÉyÈÌ©³néµõn«u_Žë³Ü<‡ÕǪSù·3/QÝ –8rH¹Òádþ¤³(‡d€ë.#G¹™åÆÊLâQVâG¯x Ï„ÅWZ!Ä×}c(_}ÈNzd ç•Sdó!ÆW2k‚¤G@f-¬T_†{(ÎæÜfRžÆÏtø åâpdC¿+r؃ÑäAæc`äÌ(õhK{1ÆöaDä“j Œ8|K0Æ3eg¡‚!ÇõîÇV…±ü*´aŒõ@ñ‰„>4 š9…6´Œõ@áÇçOîÚVËoÀ†P`Ó‘·K8ofÞpþ½ø€CÙëC¨˜4£T†ñ.ê²çÆ]>:™| ã”érþøtõŽ>Üh•Q:Â:î†8Ëó+èòÖ‡ŽÃ¨ÆA‡Øè{ÐÍŸno=èrféF1Na˜ËÓgŽãÙšsZ¹g`ÊY8ŽƒžÇó8v'ã.ÀÍŸ n(g}àpÎÈGÉ4qb0œ½è9†ÍKdô&âIpÃ8{ŒMæšy>6™ã*ϱÍ_€m(g=Øèä&FÁæs–+Ý}„<Cåólr(c}Ð$VÒ£@SàöÚüùІ1ÖÍfž~oý-¡Dâ(†3m⧯•߅òü >Xç5ˆCìÁh}xá; F¾8?Æ8 Æ¡ öa”ÌŽâ|Û“;ýºBG®D&r攕)Èc˜åö*ªA,õ`‚씓qÌù³/FÏÅ4Œ¥>LœÄ;&äÅù)¦ïŸiK=˜pôâþEŸa_°D÷^PâÄæ¯ŠË—‹±Ðì¼´þ«1DBŠÒ§ý•Š´¶YÓ.©žGkÊ‘ˆ„76NŠ.àìÍTg³Xi°³lFßø©€Ú·ÍY‘ }˜¤Z™7}å.”«ixïÊ~N ^&T€Äò¢z…½îÿ /4½í€Ô8N^êj¦­Âò3™ó%B…€ÁZÈ!T²Éðf4”±×7ïP1"%U£ð!•ß`Ïø8¾¯}üdáÊŒóhX––ök"øC¬Ë:Õ×ÅcoÖã¨ù7êBÍaO…=ÅC ÉPeíåf&”»(€ŒæV&óJžq_QŽæ’J\ȸʶ¡&.~¤4‡ýqPlìBQÍ2vRýÌÊ“¨Ou54­«ë¡ö&Ä,Ëô¸mÑ›Ž•æTu7'=!•+õ¸ÑEÏו"èõ–òá,Ú½ÌG°qÄPt&ï XŸPŠpizË#±§™£Gí6T¿Ø¦Ç­ŠÄ¢ÕžY“ý´.‹]zî®,»'mµÔ \μÈÏÁq­S…Y,ÆMÓ&RUǺ¼( ºë*î?©F­95Æ-kÛýD걂íT‘tãB‘§å«AQ‘¸U>½›5ùÙ xÜÿo—q* endstream endobj 783 0 obj << /Length 2180 /Filter /FlateDecode >> stream xÚX[¯Û¸~ϯ0ú$9Z]- ( 4í&H±YÉ)úÐôG¦-6º¸$µ‰÷×wn´e è‹E‡Ãá\¾:Ù7ÉæÝ«D¾o_ýô6­6i7e™m›4Éâº.6U’ÆiQo÷›Figq¾}HÓ¬Œþb¼Û‡¼*£Ý6O£s?½ÓÓö_iåRZ²yȲ8ÝU,ç“ÿ­ìþ5l.‹è—XÿØÖY¤ûv›UQ¤¢ŽþÖ>"QùÙêžW>Äøm"5î™ðn6ã~™ú9fâ—4/>LÛؼ×}Ï ½†PëH{ã·id`#芦E\;V”…'»ho܉¤hëj”‘yMñÔyåó¦åõ]têPg0ÊQOG8êSgZ^;X5èo¸>Ù¯e Ð%Kàl~>;¯Ø®©õÆL õŒæŠÅÜà¼*ÎÒ²sçMœûØm©¸ì“†{z܃àitì;2|Ov:‚V<™:ê«è"΋ÝÅ“M\Uiá~ùà±Ól4öõdZÍv™ÀNúÀã­–U§•…uÔ±#Ñøýq²ÆwóªaâØÖMNöÁÕp×of¯ÅŸOäfüÈ~bÅïMmÐJiõ¨­êû3OÑçiùi>vL™F¾Ë¹ œè¼¬ŸÐæ<† 6Ú±ˆ@ë9J9zð =`pf@åçÞ«QO³[Ór7_ „ÚàÝ,ñüælM$,¢r# yvdRdýõ×÷L©Àðþhð HL#¼c’D&+òÀÌ–­€{õ÷S?YQ`EQR'­E´ŠÜIµši—µ‰S cœÌ„DeeƒêÝ$$Ö®¯›^=õ:ˆú·œ õñ“œB~pˆMýÙ]øœ¾Q¸d…=‰Š@”Gm¯œ#çÁUƯ„(àÔRù3/^Ìhã˜ËŒÒÔ‹‰—<˜k˾ñr$€Õìɨ@zší^îõjÈzD¶‚B—¾ƒ¨d!‚DlVƒÒ¯ïµ×v0£æé7)F`ä q»”ÈV…Á09FÁ1#’zq,&{·Ìy(eØpåQcØÊi<m™ À gGº •ô29 /!à˜D7„o€nÐgÀ†ôz£{„oÌad‡b¡½¡{•%Pìt®¨L·Í³]¸¤T‚즌ÚS *ßC;‚ðK-&°M*ÂË|'Q˜Þòüô6¿-Ö kX"æÏÉèpœÍXTdF(¥%`ß<öf0^oË$Ú3[‹cŠ2Bä÷fÐñ”gy7UN#´ƒâJFFÃá4Ä Ž;m…ɰå‚›\˜~‚àÁ´©3r~gBq(þP&ã@ª÷ 0ÿ’”‰‰5u  o•9v!–;)më•—ä bðŠ£ á,ð Äo½Ç©ÔÀà@yµ³ã9gMqÑyK;áíuce£«3'Ù+^QHk‘ú‘ nœÁ!ñ_¨`ÙŽÚ”lWEG.R0x ꢬRÆ…ŒŽƒ—:52Sn‡&VVî3Á¥”½n­VAß–¹„«±Õ/•ˆÂñ¨½4˜%Ô?“«¿òµ^ðU¼zS;a>©ïX7«h˜Är[ƒÞ|%ƒö¦»š¤F“àêa[ôEŒ9SE§ò¸ hߪf;WО ŽOÖ ^3͘‡Mƒ†ÁlÏGk™Ž“çÁ Ìˆé€ãƒÜq–c(šªzM+êÑ”=-Åf¦*bÏL½‹¸"})âyqÌ‹§ã#بJt²qà²qLµÆÆk­ºbŽ7Y¸„æ»'…m2T'Çsò!|[qÕ4>§Ž ¿žß8Tapßâ"M#¬ü¨ã¬Îë,vi5aO Ùó@®ñ!"K­…*>‰½ôz8„„Ñ2ø û7ãÃZ¢h,þ$ÈwìRVÏþ€UùkcšîŸ Ü ™Q“a~×ê i½îâMZ61þ·ˆÿýÕµü¼Kn˜~~|õ_£Ïíƒ endstream endobj 792 0 obj << /Length 2358 /Filter /FlateDecode >> stream xÚYK“㶾ﯘ#§j%ó-Ê—T’ŠãMe·¶l¥|Xû€¡ *!ƒä®Ç¿>_?@=†ërå2F£Ñýu7&}x~Hþù&Õß¿íÞ|ó]V=dÙz[UùÃîðù:+·›4Ãoó°Û?|JÌùüc¾I~s'3ÚÇUÞ4IçþK$Û¹£e“Èß=Ín“`FçGìÁ‡Ç,±BQqŸÝÞ*éEªëibÄ‚atý³Nv ôXnV¿ìþÝWY¹.ËZÔÝgÖäqUäuB›­‰m>&so«æa•ëmYʪâ–é›ïŠÍ!dI*Ìï§ntç[”e•ìÍhd4Øqx‹a½M¦¾s'ëT)f[ûÓy’£it'ÑîÞðyY¯›¢ŠþË 1­Ì·É³íýɵlƒU\pc Ó›îe £Y– þdiCþÌ“`»™ð½ü>M®Û³n4>>æMòÒyìãâ¢Cð'aÆ5Ê@6qÊàJ½¹šJôéLxæ{©¾Ø —x¢Á;‹ 2Ç2ð‹•û`N®ƒkœ¼(“ïq©2ažëßÊX4ÂàÇw*è ·£Ãåe ^sü0.ùìb??V%މš#]i¸ýª"ÄÇÛiP†Az¯+ho"ÛŠ‡óí¹þkI¬ LÛbÛ)p`áìÚqÂq4%;•i£bRˆæ |7ѱMx‘iˆÂ¯Ž¢ÏƒPÕä#­øÂzÙ^f†³Lµbðz³M~ì¼ò5|KÄöãÇVOf°û%ÕŽv 1ÛR@oòd8ú©#0Ød¼sñ‰0Ë—#)@#>MŽþ̼zÃ_dšŽ}ņA°ºÀévF%¹“œÅ‡ÑèU.(K¡…РƒååFäãWäcpñð¼l’ŸÓ*µëç5¼.¯‹ Õ“YF÷sš•­»Èi’£îw?;“é(îxƒ`úá`CX¶!¹?_V+‰Ï¤%‡åFÃáÜ ƒ˜€æ[† 7ྡiƘ&ï"â(²â ›C§–èG! Óy6×RørU5+äôÉî^T°“|·ajmCW¶¥OíJmKÿN‰"pJ#À© "Ž­—Ìô± ý«ÌDįg¦?œ™„Q¢¦tôdžøtyÔd  TúÃy×Zá;R>ûs¹¦üÿrM^Gãäõœkò¦Hn2 ÍÝeZøõL“m×é¶ŒÛíØé±ŠÕy=ù)!M±c1ñeôš…TØÛ¨á`¦"å\O!ÝÚ#Ÿh®—_#?r#½etíuETƒÁ\àÔTÄ„F@Š ØÙHFœ9˜a´Ë¨¯ÔaMË•˜Éô{PÐÌÓÜE S¨P9)Ð7|_Ýn?å{Û·7Wi¦ZP†÷Ë«ŒǼ­¶@>M¸(nÝ\\¸ü¹à3ÆGÆ6ŒG¬82:â®Ûôº¬÷ýJ#6heq§ÚÓUùq„ÅÿMÐ8¹¾'|Îñ#9ŽY)LÏÁÍ!:iØ+[oÒžT­+„ïùW Ì1"ˆ@z!½I|ô\tTænÐfCAÛÌA[mŽê Ã0=áÇIë(±îžÂ»[ÓµÕÉOG×YÕw³®ªí­öö`µt¶­Ö ƒ|Üø°dSá#ˆÜÚóüQü²(Ô9TTªSþ0Ú^†œÄMšè8€@ÖмOyZp¡?I:7RBœƒ]]òM8- |ØKêßL™â܇owxÑ)Eš Z®(-ŽZYÜX—ø£uÉ´ jîŽRWÞëE”ÖpÙÚ\á ¨{ßëHs&/9O8Ȳ¶›‹ñ^¢Nâ#òet¯÷\¶%€öIA<ƒÒœ?óðåmø”ü²”O=%.õcðãî±É%¹ådW¯eóšCçú¡ÑZ*–Ó‚}°2{FpòuåŒ9;J‡“e(ˆ ™G8ÍN—°Šj™,Ù»¡ –ñ©„hs:]&€%OS¬‹Röš9ÍF•o­·²‹›à²tU¦‰cÉC(FQ¬¢'OèøJ_¾V-sߨÑf‰M\¤HG»ÉD‘ÄnÆÈFš$t@Öp=~Õí8JGXÜÂÁ‚P¨ob)ÎmK&¹•å]j‡¯)šj}[¤Z7N÷RªÛ§ŒðV(mgiøH€—iIˆ °‹ˆh§<„k77DÄ8iºAE˜8ó§ jÄ 9O)}Ñ¡0˜á1o´b‘k=fó2qðS jjûŒÚ*«ë…ã£4¨ïÿýVE©™‰CS‡ Ÿ^®°Ù@u4\ôsryeuL°Õñ{±5>œÕ<ÃàÁiª×u 4”ÓØ 1¤Ô”î³ä¾„­%2ðãlFªè¹ëg(ëè D‘.–ò¬à-íÐ?踼ÕááMý op· âºCíqeb<šQFaR äb HK+€¸9b$d"U Ñ먱í„ÌY¨Îc]\⤉† צ).7vMœ—3„ŒJ[PõÓ8¶Óø$‘¥—'‰¬üÈ.É Ò±;\B4÷ÅǛĢ¬Ó sxv[ ¿{jÆN®W†™sÙxZíÓ¯úF3²¾bb°8ç Ýðp'þâé‹Å·ÙÛ•G¥PÜôZwÜv]Ú®.¥= Ê§ß Ië ÊCÒæº½²%-÷w ÔÒÄ6iCXW¡6 Ð8ÏDc”©9.2C ¶¿ìH“…þ ó|Õs-Ë5 럊ƒ GkÏ ‚ô¼i9—/*Ðíä¬Ä]cÇöÖ‡Ÿùå3%ÓsKCâÑõœ¡Ê‹ íËW袗rð¾úˆ"Ev‹ÚT³ßÒóå–ŸB2ze i¸–6í·Jø½óaâ`íI¨£²]õ…0ÄÞþ:™Q…‰@²ó(»Ðjôwò­MÞ×µ7\Kco¤žP§iIKuºüNÐHKj‹„éUˆ^$&BŸˆðÒnS¢°â;¡0Þl¨Õز#Qÿ…â¦âã’V¿Qfè ç’KFŠÏrÒE]Œ~~̈oë1N"ékÞ !àç~mÐ`˜¯ûîQ#kšu™¡éÉ·ë¦Ñÿ ÔÙ Ó?voþ ]ˆ) endstream endobj 803 0 obj << /Length 2432 /Filter /FlateDecode >> stream xÚµYÝä¶ ß¿bÞân[–¿ž‚¦È5W´h‹[ ÒñÚÚ÷lkηÙÿ¾?’ÒÌx⽇݇µD‘4%‘?’žhwÜE»?=DwÏï¾}Ÿè]‡ešªÝãó.VQ˜Äå.â0ÖÅî±Ùýü+Šóý/¾B*_IÅa‘`…¹ÿ°Wi0îÓ(0ûƒJã`>ñ ÎckÇIˆUcˆåóRÍæ;Rþíû8][’…e”{­ßW{•¯ôÏìãZâ ­0 /.ƒj¨º×©%íqŒ¦kÛAžÓOH×-ö£_Ûá(t1ƒÛv ý3™³;x±µÎÄ ÞÂþÄIИajg± ØgYè-¿¨1ÐÏÕXõf6ãî:‰ƒƒ0ò›‰£¦LæVÆÆâ€4Ð$üÕѱ˜inûjn-íÿ›­í„jÖWd—SO l~šŒì±­ºîU3Õcû$§#|'KL/²>⊜<ÛÒ´<Á„y ƒP¾ìST£SYÕ£¦-úv0Øôé^042à£Ð±‚µö©zj»úkYk0†}îeÂ]Í2üY‹ôUó‰ýåËÇçÖ^NØú†Eíq°#{ƒÎKgHíðlG>äAV`«lÓåÉ]>±‹ˆG31“É|^ÌPºù¢LƒG¾– #ü%é\Ý%ÍžGÛËh ¿Žc¯Ò Ò‡YH­S{Fƒ8 wñ_üZIM»8™šV?¹¥ÓÚÈTŒDÌ"^kºc‰/èüê_ =sp``*Q+,ËdF¸ê¡1z‘Ûá¼ÌÂïv¢qFXµccœ62•ž•¥Én:ýßO|!mO­Ó`0xƒÍH =/žN“qdðÒÎ'Ç'»È© å:LUêép€ï(þðøðù!9ÚÅ»$Qa¤vY…Je»ºøù—h×` Ö†IYì^˜³ß%aV’T·ûøðÅ«÷%Iæq̺"•Ë[›j®¶ÐRåašdÞ6{&·¥óŒŠà'ò{·±Ö…0Ω$#¶ r£(~^ÚÑ4ï0%Ø`/Ý;6Í2±ŠéwAJå4¹Ë&ö—¶ë„x¹ æ @¼ˆ¶q&aÓ,#Á$}]º¦šÉËhD¶œÖ”@Ø!5P*Àe0ïÑ+ò`á ƒ6ìb#"‡ý…Ã~̯ØÿŽÅƒË4Œìy¬´`#Ñn0Žè'ÓOÊ^g] ²4¿qWlÒ€ã=G¼½éeb$9KÐpfGì@&û"†…5ß(Œ•3ÖNû i·K×È”#ë ‘¿%¬L36XÍÐü*©ÚN88\Á7PÙå^ÃûZdUÁ¤›‡:*ÿ›æ•Ëiä±øLê< 0W‰óÁ¦ó™Kû[ëssÚ•DŽ´÷ % Ò*ñÒ¿f³èQY&Yì-OÌ(ß>S‰P»){[–]púàåÖ©Öx/_1¿›ÏT| ò)ö± µ33q# ®î’Ê-]*ïÐ8Iï+Ä žÞ³ts‹ô¿[0Ë Bì°å•=e"—º­¤$ µŠ°yF+fIN§¡興_š*Zù"Å\¡\§ÜÉ«T¦T7yD«Þ.“è4‰»¦rª?l9$ ËÝ®ÊHWÏÉ*Nƒ]¡Dçõ…ÿïèôÊÀŸ¼ˆô–<†Fî<óÀ{Ìä8c;?À±,´u€/"‘ÐÛYžÜ/c%@ëè7¸,„JÇ{¯r´“Äëñ€ÄjÔÉØ{çíØÝ-,Ó²yáðÊ'œ‚:LBáêŒGò. Î’ÎáÆ‚˜NP|î¤p²•<:Þ¬ráçt²£#=Õà FMÚЄïÞÌ1 •È„Œ—`ÇÁ´¶ƒ«)a÷+;Z#+¾T¥¾‘öµŸÐÙcËÔù Eó'vô”K7Zi§‹_º1¹wh8zWÞ4Ú $ÐåŒN˜Ü•vDÂ9“~™ø(Îü©gÙ:";sq#; VùÞñM5Ù¡zÂÞ:nÅ×vɵ¶K 1¤Æ=©¶ƒEâÒ °ö„zºÚö=åž‹‹[áë®1á’Ž²'°]³¨TèÙe~»ºP¸ò3Þs§ì6ʹ sùãS±—®›ç ((ÔÉÌ3X¤ïK‚¿qÁ$ì´÷íÐ xö[6I7ÐðéTºCºˆ$Â? EV´” Ò4ÒÔµD)Åu]Ä:NaD®m·ôƒÓ>¬´£<öµÆí;°óO›Ì%­qÏË èÄ‹c™Ÿ¸Œ©®¬\â8utH#ª2qóÖcƒ,½Q+…QtÉÚçÓ+ãò?ñ·•Zó",®ŸÄ0Iž J…â.w’CutºpÖ%@Š ò]šKû ó[…k4Bu‡ÃãÚŽ£é| N—[çkÚ0neö2PVÏB{£ þ}ŒÂ1¿£Š›Ê”ÝHœQžeÁy®Z›Êž>ɳ1¦7N ž×“»$²÷f°ËñD×[ë6MûƒÜê‰-vÔÑpÌúZqÐð-‡PEXùµAã2í÷-ZY„y‘í’(ÑLþO=šŽT¨óœu]>—uŸ6¿gåažêu‡æäåÔºnYй¢£B­¯Eè´Ê¹¯BUæš— ïë 'eEè’]¿Rªì&·ÿkíí‹T{åÛ%Ð<ÑVP"w²òAâÊiQ„Ï—júÈCBxâ@îÜ®®#ܼ¾tðk?Œ”|T$d–þE£÷ºiPgl¬Ü•S¹º+ñv±eZü‡­.®nw!ø c+Ý&})LÜ—ƒükWG#4yÝ7ˆë<.¸g؈À-¼Oïñ>[ã=Õiô…±™ÚƭߥŸôïIŸÀ*­TJÓUb« ¸É~(" 9$+ý7D&VÜÃè¾Ðšq`ÇÒmw †›î’fŠË+ä‰:‚®¸ï}Úl·l“Bâ6ä®…•—Ö¯V³®V>7Ñdp»R…ǵQøGÿqÌGtå¸3.¢ó Ž¢Ð¹pNСb`Eœ*C•Áß’2,Œlg¬à¸1*É÷{”#×ûÞÆåvN]ú'šón1ý #©ž SÁåÛ‹›ˆ½ƒ.&ô!\e¡*ü;ï¹Æ°¸FÚë_ÿBÍ`Ô©“lÃ'þ¥€¾È/Dscbl\Ÿé"†“ûåÅ5óqFÃà'ÜÃ7Në‹`ƒ—ýîëûKËÎ)7,20™ZÉ …üh—˜ endstream endobj 810 0 obj << /Length 1692 /Filter /FlateDecode >> stream xÚÍWÛŽÛ6}߯0ú¹X3"©ëSѦI€¢ÙÙ‚")PE¢maeÉ•¨l¶_ß¹Éko• IÓ /69ކ3gÎáb³OÏÂ{ÿ?]=|b£…Ö*c³¸Z/t”¨05‹4ÔJGÙâªZ¼Þ„:]þ~õËaãÃ':>Ù¥Ufa…´¯¶n¹2¹ ÖÝRý®ð<íÖü»4YÐ=Ï÷çèÚ’¶üRÔÈöz`Yۉޕݦ­ÿr/¼]š¬ÑÚ‹-Z½}ö«âù¥sè1ø´Ò‘Š¢„}»t¥¯»V.ô¢ÇáàåÓ³Åë•5IpzÖ»3ŸFjŇ^éLÙHq l”eÑ÷u±¡Y ÇôcßÊ q[ôD²ô®X\Ëò-.S(qã](qC9ðRÑ‹”‚‰æj.B‡ÛÔ"Œãããü·e¦áÛ<Ù¡â8x™רëx6Œ½Œü¶#ÇÓc àL00ã[=†ÿöM1»÷ž…¼û&qÜÔ~+±ñE[}ų<¾ ø!Úh2kåÔùœOe×÷nØêà@mU·›%ÈwøŸo´pß}øä±²6Ÿ ÐŠŠ9V‰Užf÷4Ná”(ëIã»sþr×üËÖ*¤ŸþåþC_6‡/C„ô î!F¹UQš,VÆ*k +u¯:lzJ>0ÌN˲¸ï—ðÛáφ†ÅŽJž [‚9×5Ò’£uI ýdr Bé ê¯¡ÄØ vÚûÃ}×OyÓªÜØT¥ÉÑ&Ô“¡z2i`½·Es;8žC Ø¼C¼ã*T4ƒìhAPñ¸ªi ÕŽ×bARpPªBn.ó&ITr°C±†Š+æ@`#&“j·Ÿ˜¢Ý# ³{ÕÛJeP e·ÛAU‚+«¦núh€¿ÝþßúRü¯ûÒb…*ÕZ*ͲAû9•ösÇEÀ@±wy¸Åô¬`ÐHÝt£çìÆý*éV‹€òL’5f"Ž‚ª#ærÖ:xŽî’«&†öS¼/xDí7Ô•TF¦‚ô-åŒÇEÅôAA0øãû¼:Ô›VLú¹î XǬôˆ6Üjxö¡.rÔa¥-vb[Òàdò àIƒTi@½2§4aÿuŸàI˜;ú*xrƒ¯¡îLeCzåõªd¦<:þWBÚwTþ­ÐuÑ!°ÒH2ž„TÇi@1‰>î6=¶!\; Ž×˜`@§… ÓQ€FMÊ<œrßã+¶å{‡èÒóVzAYHØvˆÓ´áÞѯÐû8µ vŸúø‹®ìx.ǹªw“f'Š|”~Ýõ¢:ŒP±‘ЕVs v;Ðí àøvô ×øñPÓ­H0Þt›[Öº©›†ùnŠ@‡¯X(‚™J} ¦B{ñçÀô2žŠ /îº.\0 ½¯±¼&H¢VUø’‡ž­lx×nl|½oÄÆÆqÞ¢9¦D…ÿ˯ˆ)£ˆy/ŠlPŽÀ7Œ¾æ–E„£®¿&îA “6Ñe“K“n_—À®i–OÐòèÇ^¬÷®qÅàÙ¾æDÁ œï*(Í81úñˆ™|­xÂ(Íx„¤X3<\÷˜Ü3Âg®ívu9‡YL#f1ƒÜxì%6´òf@!WOQÙ j{?¶Ðk¦öž±CùTq ¨°‘X×K[ëã[pØÄÒ$Ù1T³O0×P%q¬‰¦B²'ÖÓÀ‹Nzû «²»„SuÎ˳»Ÿ6l™6:"ºÏ8OQ DÒ _™ë¶lFÌŠ¥…¹’úi9énº¢Š\8°Èw¢ïŠ~¢—hº ³¡¢”!)fjœí±GœR;!¡õô òÛ‰—8oâ <•Ö¬„!TrÃÂH•ÑqD·Î8V¡†‹¬Í•M¥j»„Û¨‰ƒË¥ÕÁuÛ-­ n°âá ¾q;0ü0wgçM¢L_Já‹×`añ¦Ûï92ð¥*è7!|ÓÖ|?…†! ·DC“(s­(â ALÍd‡‹*ŒýäÈ#ù4]‘`ᢘ)¬À¢ÍàÌŽÿ¬¦, ^:Ω“ÜÊòeY;|×y!/!R]¼¼¤ÛIèæ‰Æü´ýYÝÖ%ñMhÌ2J€ÖÈIP:xð€|µ@—‘6 «Âé{,?Nàiûôhíq5–ÅÑëÅ&Ê¢Êñy/ >ñ½gÊBg|*‡¬æ*Ë„¡{¢ôøêìo8@ãí endstream endobj 709 0 obj << /Type /ObjStm /N 100 /First 887 /Length 2062 /Filter /FlateDecode >> stream xÚÅZQÛ6~÷¯àcûpÉrÈbQ m±m(’ÐkÞµšq­`íErÿ¾ßÈvÖ¶ìT²|½`cÑÒ~óÍp†²—bœG†£ïW6!ë5ÎzŸLÊWˆá*&Áµ˜Šñ™LžˆOÆ;Ü”€J1ŒWýüÐÜ¿¬×浩~þîÖT¯êkóiªWÿ}_ãÁôm=©¾Å´õr½R\µû¤zQ¯šÇ‡ûzÕFƒöÖóz6Ÿ~Ó|4¯õF,Ñi!°¹¼ÁlÓ mGx¶\6ñufT% 3z=Ò •›Tß4³ú¡Ú½©~¨~¬¾ÅD7ªÌ=Và²z¹uU\‚e¥ë\‚ÜËÇ»5Ƭ~š/ßUÏnnÚªg÷ëy³¬^Vÿ~ñ£þÿâõúýWUõáÃ;]¿½ÿןXýûz±˜×ö÷‡jÖ|X.šé¬šM×ÓU½^U6³z±ªoùcõÓ÷üËoüÜ®?®¿Ä:Æ-d±¬Ž£%Ñì,óÿw)ÊWy¯¾å+¢š-`×9¾>qg˜|1Es—¢éŠî/Xz.¸+¼ñæäƒõCgÐ9ç¦GÞ 6SI;1l'ŸœñŠ]…[èºväÚø·pQζ'.^£t×Ç®1 àÆ¡ð†Øù­Ã¾xÍHÀ'Ö\Šu¹Aqc/ì‡ò™p¿o¦ p§C¦o¿ìB&¹b½&_œlLšryë¢À“œEV ¹g-œ/Mõ}óª1°Æ«Ç;ý«Û¨i[½-_šÃPG~€u…7ÖEÖŒ¡©Ÿp„H:û ³|î'„lF<€úQ 4ïÂÛ5Ò J]^ñH¤8Äb±§Å®Uu«Y+åîîw)ˆÜuN¸yíùß|Ž6Óðýî0Ú=íj¸_ŒT7üsÆèºaŒ‘' Æ‰ðVìL(ülF£ÚGíd™üy]Þ>Η³féézºè.íP6ƒÇV5rVË'ÊÙ&–1¨ô(#¢há ,°I‚ñD`³ ®!ïêéjmïæ­gvzoßUϧóåoêVGåav≰b¶zfØk÷8ØtÏ”N—ƈÔÍOŒq#RÞ^·±!ѨãÝ* ò©ÝÖ±;þÐ` Bÿ+{_z²Aऀ›íÕUk òh98Î2‚¤šS²ŽÄ¬¹MÑ3W[DúÖ2&¨j¤Ù|,Ø )ÏK²Zãõ²¡‘_ý0 I›Ó‰´™œ¢’¯yÄ¡gÖ#wyñ].—xðÞêÅ €êPx[æ1Yfê'€«¾ï8ƒë`‡9V1ÉÓ©„kW|Á®äNÚb/´^ ìÀ¿™x ü<þGë1ÀŸ¹§°ÆÕ|/ZŸC屮Œ”.®2×<×<à¨ã”pT…ä‚"ûl)}X3u`Í~$¬9 €õPøo`=%œ`R)ý„uÉ÷æÝcì'LX¨nLÃÍ{eG)ÝÑ2ìp¤¤ã .oôÓ÷‹›ëÈ#€£‚‹Ö·Õ²Œ\¬¾Æ&$tÞ}¦dx߬¦³iÉW¬£¶tõ7²úòß#߉>C3±)}¦ŒšÞMW÷Ó…‹×S…\F‚˜ J«/\QR"‹úBÞ–œ>SÒMëyýàø8á)CŽ¸Ê‰#®”=Êmê'\ Vì% ú ýR©}‡_òd× ú’û‡yZ£¾Iï õ‘ðî4‘íq49+¥ÅÙ ûü¶Ü+C½ÖÝ[ò}Xó¸8¤?5P•ô—›«\õt©6hÍcûCÍCõ%a‚‚9©z¶ÆKÑǶRÜ©¡•Sú§Ôàˆ4ÐéOpLÔ¨ÌáH7Eú”€èÖ)ºôW#£œz¯,(÷^ëüøÇ ¦ endstream endobj 819 0 obj << /Length 2145 /Filter /FlateDecode >> stream xÚXÉrãȽ÷Wðä#ÌšÚ°ù¦éEêE3Š‘lǸ=‡Y"K·dý¼s)Pö(|! Y ª2_¾|E9[Ïäìü ÏŸoÞüôA¥3• ­b;»¹›)©E–ÙY*•P6›Ý¬f_£ßüo|µôíü›Oûé07ž)%ò8Ö87Ylf Å<ó«úc4eöuas÷sÕª®þ:_X#£kO%£¿ÀCæÑ¹k—½/Cç¯Ð™d*:ãζØîJúî\ÛñTW­¸ß-—}ã:ÞÊuÝÝf˯]û™©Lh™ÏÊ kÞ«o»bKóŒÕQéš5l2¼í6sFe½öUn£ŠnÉÆ¶î¡ØÎuõÛ0¿¸Çn_›z¾€ÿ®~ÿ§&=ôœN`?Jƒ‹h'×mça+ÅÖJlôsQ—õ<–Ñú‘g«ÑìÅ0}tœX‡±£)#l<||ht%yò”J‹/iôoK-¥³CS‰qøF‰$Çiø’ ðøª'ƒ|ÝÁŽáî‹?•Ùè B§2úíìáòËâWoÿ]©Ž.Ùƒ){0=íÁÅ­kýŠÇÄeq2°•'Oj›H\ùØbµÍ£ïˆÂnÃ/ݦî[QË#ë;~vîÁ sW¬?ÎExÝíD5AÛ-7´ƒƒB²n<[v›Ç£å(˜ùq¶H¤È¥û ƒh²“™góëí>Ÿ`)üvÉöÖãÛz :lÐè,Z‚[ßµ<¦¯V¾á&m”ü[üVqÏN¶bû²)¢r¼ÇÎ7E]MÅ×HaÀµÁ“ÈÆFWn§XÃ÷[Î,Ê m¬¯Šo”7M[tC|Ï›9P©p-¿ºŽŸg=Ð_5â€IÈØLİu†L c'!söØx |HÍ&Æñ|d¨ ¨E°Áj( ÁÛ j}²_7Q¯%•Ê'•šCÐ(8°žÂR ,t|œx8Ÿú{t‡ªÆ ¢&5¨ôß:YÝ„þ·TUTôž€_—}ˆ8L©a?wÜÜ5uç â°Æ¶.ý²/}KSuô1Ø/ûª©Ã²âeI ÀÃú•ÀƒNÓ¾ˆ“}9¿¸¹² TB\1é…½€áÒwî–leÑn'ŸÄB[uè~`”pZrN}$D†_‘¦ÑõÆíÂmÃL­ž”ÑlÄ£œ-]€’Ê!­äQùYù-!Iãæ};PÎ/þ;Ÿg:ª›û`Wy’OB 8r„€dŸƒ˜j®iâèé/NPc‚Ͷ(Ó:Ò‘-ôs¦A#ˆ:NIì¿áº"œ˜`E¹Øò¢I0¡È8©(ÚþÖíhÔ DÆMݯQKhô»Š€ ¬Șµ]¿"ùˆƒHa€‘ÀÜ/K_wÅjè© ù<`‘§{Uñ©î› BϬ± â뎟—~Ä$€kØôþÛ6ü ¬„ÜÝÃO%§徂 ¡iú@Œ¨<“”5*zT ›ã#ÄÇDˆ._µ˜G¨Gl}¤ÚŒy€‚lÁÚ5ž4ïšzË­w¿œqƒª–«àx(%‰†ëöÆô<ëÓS¸8%Yá×P9jj·Dn&ãªd,Œ> +…NÀÀϣСéÇ¡‹s‘»]úªÐéXE&Éž€xë!tj*­u˜ÃÛÇHEf¯Œ›Q9ÆmÂy,”Ɇ]]]üþåãß­p7ø¾—XP5Ã=ìcWUoÏÌWnyïÖžG†o(¨HX‘¸I…½Háhú(ÈøõwP½›â¶ïè" 5Þ3TZØ&]ˆ ×-5sR?¾óÎ%t[Ïå ǨÀzÊmÊ*.©8ÆÃUôOTq®ÝLJJ`»Ž®Ö˜‚×ÞuÝ—‰›a7ynþ”ž‡0æ“a¼r\;ÜßwÜ‘4Ü.Eh|.ÚMQÕáíË9,ßRqµpû^*î98g`iÉNÁ'+lh\ô ²gAu±­q×¾õ…Õøžžñ=]a>ã#”b? ÙTr¢òõ†‡Ðp(]¹ºpîÖÕª)\¹î˜¾ôÅ©ˆ³—yl’P^à9ÎcâîaÚè?LîØÈÐá;§/‰/i9AáfG´Ÿ¸ñçÀýYz %'qqC¡e–¤Òm“4úŒ¥Ûò;&ÕPPGF5=Íõ>ÔhLG> |ýCh~oƒî|.¡p®¢h†2Íø€½?Ëø¡†p+S¼Э2\: 5çiS—ÜÓø5ïQrñFÛ–¡‘Ž¡Á}\[–Þð9ÜðÉážq”¾¬Ú@á¸ê¿þ„H¡©ö´>QÐÿ3"ý}ñ祆 íë…|5¦b¥ŸbbjšgtˆÊõQWÓÿ~ÁÂ[9ô )Ä\˜ÞŠÐAJ:Ë1Í¢é|è»vKâó”9á0΀áÞ½Ÿ1_dPíϸ«Ba‹C·AWb £ ®øßŠœïJô?ó^jM´jG¶ú<Á$V¤ö‘ØŒ >'‰„fýß<òú˜gÉSnF,b'"ž¯…âTäYˆwbGcÞß¼ùõ©¯ endstream endobj 824 0 obj << /Length 2177 /Filter /FlateDecode >> stream xÚµXKsÛ8¾çWè´EUYâIbnJœçÆŽ+ÖNj*3Z‚mVøÐ’T6^ÿùíH=†Îú2hÐýõ×ÝLfw³dööErò~¹zñËafBÄÎ9[ÝÎD"ã,Ó³4±ÐÙlµ™}¾ ùçüÏÕ‡qáìëB»$ZÍ3ås™FßçÆDy‹Í?©æÚÊÈŸÍÊÉè:ž/ŒÑuSy¤.Ú¶ÍM~S”E×kåõ†]Ÿ÷,Q^‚,K¢-´aI髎'55¿û{?,Ïˇ®èð”3©ãÄÊÙBèXkËWhnñ0it~¹Ä†:ÿï¯×¾‹qÍ/oTz¬PC«?ÎMy|¬û]K8‰†N¢…Ž.r8KG_‡¢æ7g|,n=‹®×ì¾B›‹£Í¥–±pvØ\¤aÒ±¡\Î sÎèâ eE,¥;¾ºI3 —–lcá2 o[t1h Þ:qƒáÕ¤á?z°˜×HCæÕ™‰þ/½Í»õΗ4¨£O0è’,ZÖ<©¨Àös™`*~ÃÒ;_û¼*êf‘¯‹0Øúm™¯}åk\ÒÿÕÂ†Ï Êo‹“Ö}ó¢)áT Ôÿ²›¯¿csÂA‹a­4OÙÂìMAª*I…’ vSÒ¼¥%I6¥|aMláÐ'ÚדÚÿròe^ãVBTbÑøzÛ”›j¼Dó$"BØ'it‡Kƒ¶±ï«mÑkîÚ¨jæ 8íÆ‡>¹ L«õ!BOÆkÊÝâIwë rQØãÛb46 nÛ¦âV…â]ÙÛO…BI;a6ƒþm^A¸=»†\„zyøTþ£¨W»jQßh¿²¸çÛ„;Ña“ãsæ[Ø/_ãüûIè»Cä0 ìJàºB ÊîXÀDµ#=L J¤"Ö6]<{.¬¬Ö¹P%‰uLz´U±.€jär3 ªóÕ÷pßü‘›Ip½‹˜6º†XIøø>ò¶ÿo˜ö9FàëS»Þõ=.~\lÉÇÃ>BL¦z*ÔYÞ>ð(ïš×wþI¬!R¤pF;ûÎçkƒ­é£oæÜuWor4 턼»/껾õÙ‘wJ>´¯â3¬piöüØc'úöó~xí<}2òP6m~AÍ8MÐt&ZÝ7mpèé&8ãžV®0Nãœ6Çt£ö841á‡Èè g²éóÁÁ'‘ *~Ò:ãà´¦¤zL¾³°Cû?ÏJdâcb𪩶»ÞaºµÜnË‚G‡êXJ†7¦!£áG,t‡I ù+¢æÕòåûO×{ÿ8a1)¨ÙpžI³q*OI ûQfrObMDr22[kNI,ÄÆ;¡ùðw¥RŽŠ _0ítŽ% h€öóžÇIˆR:êv7“ö»×`loQì… -°èOÂ"Úªè¦d$Oû6mnëbgÇàh†âϘŽÒc^ˆæN9^ëtÈ:ApI` Ü zËqu¾ñÕÏå5ö8-ýË×<áDGwúW]ô| †Í58Å!Jˆú9+Èxï=¾®.—O£+Íbu#ºÜsÒ`ν'Ì#>%`6‰1)l,Å)IJIˆ-7ù ʱ:J(‚¼Þå¿£¨Ã‘2Ì £!e¹øôñêÝï<•3£¶ é’Š0GŒUø`é®Í©èÞmÓr£‚4dý4ÈBrßÞ:Ä| ˆŒ«¹#n¸I;£yö) žÊ£ðJR|Åiï! ÜíÚæŒ»“PV*‹µyÀ÷0è.sî#£.†éG÷â`Ý=­•г=\ÈcîÛ(#45§mäUùö¾›D—q±Ýîú®Žd†`TQØÐ@ïk&Ïcä: ¾ÊYpAr!áTlÌÉÕªÇáEÝohfŒžîÿWn#|ÝtšWªªXŸqVÂ)4 ö÷¡ùa]5¤ieèa4—ŠPŽ/,3:$´Ãa¤mÿùõo¿â 9ÏÍ™S©‰œútOhVšýÁ:¹…£“@»¨o}‹‘2€ø–ß­ï±¾L£ïE» XçŒÖ´˜bfènž}›×ݺ-¶=¸ÃTy0:Ч´á­2]'@ʦÇLñC³k‰tIp¢zøy`u,ö€1Ïæ?kSuT"LÓžMÀ˲àÈäy¼IW˜{ /Cãj‚‡‚ÄéKȳ#A‰Séˆ=Æ¥ÑdÙ=ߌ¨‹A;Xäiö ¶‚9H1!í¦¿0çE(f¡ÈgP¥IÁ{ü¡u‚J0k9ÖÜ<ÅMXzÃ'™€k2Õf‹weÃ_.'Ñåtlõ7 kÌ. >>³U:ƒÊ";„ýטD˜³1pè)ÂÄ$ÂþÙ@„Oß@ÿŠ ¾ÿÖàZƒÆñφ²Hi˜Å!ð"˜ÖŽ×Sæ#”¡àœ‹. y 2ý0ø“¿IS¨ûÛþ HùìNN=Š“?XNÚ%Éb—º“‚KNÿ彨¡QJO5Ôó+Ô{J5¾~ƒì³år*ã$Ç@Êx1Vù0ÌC &û´ÿîAY6> stream xÚ­XÛrã6}Ÿ¯ÐÓT1¸$0osq¦Ê»ã¤2Ne3“<Ð"l£–"½¼8qüóéFƒ’h“±6Ù h4@°ÏA÷ùêfÅW^ñ'ÿo/_}ýÐ+!«µ\]^¯—‰1é*ç"©Y]–«/ì‹T¿¬¹<ßO\}Ù¤–³wkÁŠæ«õFå–ý” Ë×ߨüx½Ì$)X8-äzð5–Utž>\©Dh5:¿kꟹÐ~‹“2Ê]Sß`Ó2_—þÞ—>¿"ÓÎ÷Íz#s¶]ÃÏmS—­§1ÃîÚ¦w¾î¨çkšÑº nbµÉóDK³Úˆ4IÓŒÞ5Õ½S)ëo64»»ÅŪæÆÕkiØ™›kòsxÂcëhnK×v³a‘’'9×㫞7C[‡ÝjC«éœ}l*·Öœm‡ªhÉt¶ÞvßTCÜù¸Ìdë½oêÝé3ÓÄH1>2Íç*I÷»B`eÆÏ•”ØÉÙÏ\sa­ÈCS$SZl2™(¥`c°nGö¤³ìù€èuÛÁUø -Ù·É{뛋ó×`K3b ÿ~ bðïñÇÁÔBß03¾t0„ðÁ  çq©ê¦i}»£îUѹ’š/ Ïd ¦¦Íè!YϯµwÈ3ÃJWQŸ>«·Ñ«,úbz‘ëD[;ù)Ê™Æ÷¯´Ý ¿²‚PÒÈb¿„¯Èe"Ì`‘.œÚÂF*‰”vJ£ÌèÇÌjâ@„=ŸÃ| Ûs=‹ù›ÚtÒØï !ÕðŽmœ}Lbーâ`z?\áâD H]Î÷.®¬šßc÷PJ ËþA|ƒÁÀ7)Ù§¡Ý<'@ ñ-!jø¿j‹šò õ»áî.$Ÿ¦íɲsý-売#Ké u}[ô.ZŠívh‹-¼ÆÃÚˆpÜrÎâB¸ú¯Äí8Y XÛÐvù”ªWC××ðúðR9m5…Y×Eד¥òÿ ïRù¸³¸¿M< èSÜ…cfØo~W¢sG/ëvnDo–ÚŠÛ$7ÙÈ®O]ïp™m¤YžÄ÷êˆì3¤V6Qr_2~ §c‰¾öµ$黎›?bpž%F¥OœýCºBÐLŽœK9â"ç¬HÙ›»˜ÏB ¹„Ì!³G¨E,hU`OOÞ×M»˜¶udÒ k.Ì‚]"¾Âtä_ïÆ.ò ]¦ Æ´×C…C rhï RõžŽÅ|m3ybì„‘,‰-™CYÛ :â ­ÿ^æÒÊ>¤Cæ’œg§g®|÷+ʨ”bï1µ(R‹ìD¼,ª*Žþ_9µì“«Ü¶JBÕŽŽ $$ rbØV®é}éÈÖ W]ïûð_/&¨P!m8º•߯C«`Ǩ‡p h–a7úùÝ.<«Žär ²Ò­‡Êõ@÷¾:j úÃÞä‚mÄ>ŽÏ?l êÅ|]#°¢Ç„©Ób§Ç4?/v"OR»–œœŒÍ-ÏŽsìZ'œ›§ô0³ôø„©`¸j}H×ôðùl”L–piõ°´Ù’–üéô„cäƒ.ŽZ H"üoC&ÁÖ­ƒsŠ*Õùž*f0G Í·:¦×ôŠ)eE¢@‡?Q•;¤¥µÀ˜»@b@ F»H9'*ÃøjÍ¡àÍ+!«“tA¥"ŸR ”¡„yFIÔ6´îd÷±È³ÀþÆcgaþX è(}×Ô˜53L¡*"äÊ Q ü£“Dª²P àFð±8š+Ù0šƒâ¿8û÷XPD¯ižVœá~ë]Ýù«Ê-&<¿A›ªP œìÛÔèu8ô}Mn¿ùw¿”Ï•ñ ?ÞþyÅ0[É=®ivÒ=#L[þ˜I1æŠ ÄìsO¡#ˆŠÏ‚øÓÚHð ¢ 8ûœ`Dl¡S®DæÚEÁD£ÇwA‚ƒV¨ÎXÐHOØ%ÛŽ:ï/Þcç–5'Ý#0CÁÿ®,Ô•Uî—WnC>ºÕFU¹%K8á@'­³Q×ä:kÔù”.u’‰g·T(ŽM6NWWþüêúR6—"ávÏeO¿›fPV&wÓtán*´I2 õŽˆ—8"A#GàÌþµH ç8Ê4l¢LÃô —öpÑVBRŽZ»QfLQM‘{GŠ!$eð 9í¡¾/sf_ùe¬üp+ºkG´ÁX=tÍï»Øsá‘’…ìl üé¥{júôžšŽ÷Ôô…{êf\y²¡OÅ\gæQçj‚9@næ0Wy¢Å³´ _L pÐ>'”0uKË.‚âÇ‚Wu.$p8Vßc‡Ëþú-:w5¼;¦‡]ƒZ mT¼`AšŒ‡ëĬÇxŠ1žylu‰‡]¢­+*ß…4„#x‹ö¬»QòU _¥ò4±¹„Šõ$÷C`ã”'’ô ·.nŸ+ò“œ’©šè7>{ÞarÆŸ¯^OÎç£ïpZ.üˆ:~¾¨ðù3êù¦Þì‘s?N<Š8¨( {œ °DÓò鎢(y\wýx5Ç~Oÿã'QüŠˆý¨ï‚KT_°RÒq[T?+_»âfA¤ý¯²>û¿Êz{2),7HtL 9ßW0_à¾A]Ëøa!›¸œ]¾ú-ýÍ@ endstream endobj 834 0 obj << /Length 2037 /Filter /FlateDecode >> stream xÚ¥XÛrÛ8}ÏWèÉU8Äç-Ž'I%ã¬7vÕVMf`–¸áEERɸôóÛ €”(Síî 6.qNŸn ^¬ñâÝ«ø¤¼~xõó[*”F©”lñð´ 1‹´ Óˆ ½xÈ_È.þ\þùða¸ø²iLÞ-)ÙuÞÔ?-WBÆä>rJ>7ËS$o‹uÚ^G¡ró¼„&ۆהL’+,ò~gK˜¶[®(±õ’iò覲Žú}€AŠ¥ä¿£InË¢^ûyúŵ.˜ˆâ„-VTDB$þGº¢·«n&,þˆ©ÈðEoK)‰i ÓMíMÍ–œt¶´ÙÁ¼5°¼¾·mÝyƒ)ü6v…UX³¶]„+øù-WÇ[ËRÅ öÏ-å®]Â4øÈðaÇG¿Só˜âðWVaèä_ð?Wúrk6¥{=Îhr[={#þ –÷Yakÿ¹Î/‘N–H•ŠR­†5Ò˜†^ް8¢J¸Q–Jµ‡g¼áXÆ,Ž”4š²gÅ‹PŠÓer–e76|]›:pëCä™råñþÜtÈ5ð¤]‡~Ÿ#Xjk¨ÑZëÇæE—5mnêÌFm78ÇsÙ¬¡{_d~DQ¯^’Iúõ>Ù6A`@‚:÷ T*œoWöÅo¶óMYcJÛe~Ùýã§8veN|E7Å9¦À–VŸÚ¦:ЖØl×ùÍÈMof¡ÒˆÅån›ÒÅÝlWšÖÇIïHN1–:y‡Êß *U4É81S—Â&U¼—z¢¤ö;žii–œâ–Îâvë’ð!–Hò að)ú -CÓ-:n¬ÉÝ‹@ˆ=«â¯~×"8ÜåB`5¾@ÿƒ=tMÞsÑš™z[Á4çà3~ W^¸Ábê4¹ Íçà˜@<˜– ÈZãQ!ïŸA œ“yð`/Õ;$h2¹=•¨½RrâtêLd Ñã'PijèÝÃ$›¢ 9®)Zãã"Óà‘ˆd¢’‰&ïMg×Îß¾£Ø™ÐËÊ5¹EÿØ:Œ`LÖT[Èu»Æ¥°0Ú¥ºÐ›»rr©F¹Tƒ\vgü^ôü#f»-‹Ì©uç-}ãË—éZG-˜Ïàc\±s~§'~J?…ðÓ ¼Ã,“Üí¼søÁ£ 8¹8SJÅÉ4MÏŠ/dªOi@çó!Ò!HjïP!É?]ÆÓ”©×¡íMhÊ+ŸA½3]¶snŽýÿÒ áìvL_|ð„ŽÛ¶é­Ï*!î~sA?l”39œÏ­üÛâAõÄTæMxËŠÜ×Z»-Mf«!¿£ÀHØ™“è’Û êÜ-mNr Ä#\˜ÈôgNZœÇQ¢å â ±84Oñÿ‹?h–‡˜^žÁ¥Œîሗœê?›Íàd–dN¨Ãæ3¸¢Û0Sí²7*A6BåaÓ´µ /Ï9eŽ1P\·»qÀ¿/”’;ÛºüÕŸxhȯ¡4¾È‹o.Ëj×vì™Ûù³ø$_—šT¶ß230 ¹—Tî`‚>šÇ¢,º éú( ÷ïþ¤«‘˜°ø— —çà q̘(p%4L–Ž ‰”ˆæè uÄuD_|¨’p¨Jè10 sTHe¤9?Éÿñ] —©S À¾]‚c~V<Á^KIþm³¾i}>.½Œcé"Ìàèk;äþ˜ÇkŒØ¾WQR‡ž¹·æ=·Åv@œ ·säp‡1Æ8ÙØÞ¶.h½Ï&Ù,(»Ý#p¡"RO\Œì’°ÃÝ ûÑÝL’ºóéLâÀ`7®ÿ>qX Ã'ÿ°K1gxŽž8?ÿáz„{þjî±éLŽ™…½q„õAA&äM ªfJî.á$cG÷i}8o§w³÷A†k'I†´IPú6ï| ¹ùôÚWžÕùˆ17‹ˆdQ¬Òÿòü¬G»øCSµOÁ=O‚öüáYÅ.½¾Äaî8e¸ ëú^r^r‹Ñ…ìVý䫇|öéÇJJžþ_!côbw¡±ØÃã8ãFŒål¦¥¢Î݉ˆ”TÁ3դϯ¯þ´ß³‘ endstream endobj 839 0 obj << /Length 340 /Filter /FlateDecode >> stream xÚ]QËNÃ0¼÷+|BŽ„]?cçH­T N¹•¬Äm#’¸J“JˆŸg[D¸x×»3;ã5CGÄÐfÁþÅU¹X®¹FœÓBkÊâLPk2ŒS®,*k´Ã;•ï³}¹ý%¢QÛŒc׎3¢r†ß(D)ñC [ïzòê†ÆÇ¾.ðôj™08ÄãJºHê©u£¯7Aì ’jUÌO®é/éîú:ÚBBQ– D¸¢JåÉóxò‘Úàê6A+ NBŸªç!iVþrI•pˆÑâZ_™!UüõÇH;@§Qq¹–æïÖ„„¶Æ’ö6LCïZ`›æš?‡î<.΀V´Mî´™ñUÚi†ŸIŠÏ¤” ÜÈ»ç7Ìü%UúÕK‘c#Ì—‘2^ ~gš Æà¥ RNçŸË™¥F‚-m,µ¢Hsr;C½”‹oá'‘ endstream endobj 918 0 obj << /Length 1724 /Filter /FlateDecode >> stream xÚ½ZKs›H¾ûWp´R«É¼Ǥ*I%µµU›ø–ä€alSá!ò:ÿ~{)„$KQàû¦{º¿îÀÁ}€ƒWxðùöæêõ{¢¢%‚7wÁiÍ©"Œ7qðõúcÛçÕ÷›Oû;_¿§, !¨» kÊ2¼½á¦Ü]èâåe)fàâæ¢¿:D t°îËçWÁ×5£òšàãØ êšÈþ ë–mM8â\¶œ¯Þ¾{óåf„™Ñ>30°i1Îâ¢Y†ØALYÄKCn“<,®šK£Xÿ–aTÛ²Á¥ì$îÛ¤øçÓØÎœ†¸]­a=Eû·®ê2ÜŒíïƒ }Ô Ø—¦6Y›¼4hÌ h|Ü·Ûû±ýöGŒnïŠ, óx&¹m·¬ØÔI‘WmŽ@š½ÈßÖë®O&yÝ0½»¹z¼"Ý2ˆQˆ)p#,ˆ²«¯ßqÃ~ 0bFÿ5—fCÒ¸ÛÒàËÕ¿mþ÷Ù)&K X~ëÒù.I­/ÁF 6ž™Ïž¦)-û–.àª0ô¸ˆkp¸”ˆ‚ys\DAš«˹ª¡-ÃÚzh•Bİeh5n”¹G{rgÔ¹;#ÚÞ'^kФ¦}7§›‡ÐÇͬŸË­Nsw`Ã-Î#ëÒ!õ…¤¢Ó¢ò€¿ðß°ÍççSø£0Mn!ä 1|+PJž¹ÁN¯ ®à´È𜒀|`6OŠˆ‚0,†4`5Ì©õZL4ââl‹Ç|.áæPãMQyÞ@û$— øll{ù·ñ¡Ó)fH@?Æ`á„“™úïzAX ÿœî^-­ÿ†l&lèö8¬}z.1l¸ ˜À`‘˜g`*Øå ¸éx럛*Þ¤8» «:ý1;ÎÆ‚¼g¿ÈKkOx›BåÃlo”ÄüWñôÃH-•XŠ"‚‰Ïà£ô—)¹š¢äI¾ÙÖuçõ?Ç/züó«8ŸRų"¶é|n1‰{›ÖÉÆß”ŒEh‡›öi«:,knKd9×Íz¤EÕÐ"lr¥aUÉíK6Y¿ÉûÌÊ‹ãcÅ00µÈâ°0ÛOš)´†áñ6E,T­•FTëS6C2d›–0]w’Ù¬(zˆµi ú"ÄЃ­ûÄу~+[Â,ÚP´ý½ÄÕ0v2.–qµaw´•}ÜZ7{ù¬1yîÌ)ÆfNw|r0ÚoÂò¸–,%ÙØ:ÉŸæSËIÔ¥ÿا›µè-Æz‘Y‹0˜µvÇVUâ=Ó0P]¸^†ÖĘéÓú›_Ba|ZN ?–A ¿%&T ÁFÜî¦, ….ž§áL$¬Ãb; ‡9/²³»a=E¿·‰] 4S:²ÒãjN`•2`¹œ©gŒ»V5Xü—žµóô¼1oÄÕ\A:pµ¿c @‰ 9f eëE/öÛË;fùG÷ÖB‰S‚/c-`‰ÝÁõÑ ã‹ÇJUÏâ}ûWnsŸÁ A< õy¦t2¡ 7HƒEv¦’xié<3š«0놩Áà ñ'àSÏ<gJ …Uƒ%e'Ó0¿?ÎÎà±³¿XV6,£‡?{ ø‚Üubuâ?WPN)[¨êÀ ¨«×õÓüR!§”Šmeç+³Ln­Vf7fÄI˜ÏoÕ5yÎfËØXUn±úž¾›/'#âÙõi‹ù´jð°‘QD©9xÖ¸IÒæ)ÊÅw{8Ûª.²öieÖ>÷†²S]øºBû̘1Ò‚6çÞ $ =uÒ<Ad+r}éKìô*Þ¯4½.­ý õ{ÌuÒIN¨Ý옴ÃcÿÙmça–äÅ:Œ’ø²¨råî…ˆm”Ú¢Nb{!Öþ €—~¸³¬ÛŽ8©ê2¹Ý6ßš_¾aáר´µ…ïäÐ>¹“°»å©B+7ѩʘkÉE»*Çö¢õOæþ¶/kز{Ö~×½QÛ}_”°WxeÕC¸iW´jð7!ÄtfàÙòw/eí Éo>ÿýqÊËûÐiOØ› Ý9ÿ¼,Jš­g¤6\Q}ýäþiãPŠÏ}Z q–Ix›vÎwóÿØëD—{ý´à¤÷üyË“Ö¤ÉÆ)iòP¼x)>š•nÎo¼ÚnRsêÑ|;†4¶…ú AÉ’çz[ÚK‹“'ß+›ˆJ÷¸Ä=¶ÇêÔ ­»ã Ù¿z°ÿf_Ûä endstream endobj 816 0 obj << /Type /ObjStm /N 100 /First 876 /Length 1920 /Filter /FlateDecode >> stream xÚÅZM7½÷¯Ð1¹¨ER)À0x7@±Ùøà8E°ÁL0É¿Ïc5gü13½Õqoç$•šzb‘O©j')­8õÒ–Ù ’^¼y!›öÂ>Šs+⎖JYúÝí,ʼÌÕa¥cÞ .½Ï2ÏÚŠ5<+ëñÌÅ ÛUŠ‹¢ÅZÏXžC +ÓÚÆY 5Lr Aºë@gbYÀ÷ŽŠè„ÒЪ†Ôêƒ u޼O1@%ÙôÑÑÑòh!äÑãå <&4c,aÕÈn2™ñò³&fhƒµ:„ŽŽÒ(L†AÐé½(´d‚‰FÃO »X›9 +˜.Œ%Óe`„!Ó)F0+Ö ±NÛ 8‡Gç2bÖpC³Lbk™ÅfÅ .Ã|ÉÎ08…'ÌføIÜa°´n›†Î §À™°etœÑÁÃlÞ1K`-›³H'pr²¸ îð£Ã4ÌѳE}ãá¡W; 74ë†YÞaP60ÞÖWÒ >9Œâh‡E$PŰãgN4hë N`8@G «‚$ƒá×°H«¢3Ã4XF}F€-!3ÂFÍ6Ž·5Âë:Hb°/:xíï9\n*1=ìh!ãżEgÂ40¿Çhà 7 WÝÂŽB›'O6ۯ˅·‰-÷CÙþø¯ƒß\¯ªÄ•¡ÂåÛ_}¹yúô 06_5¨±J¨}%0Ô­ íÂÏ®.oÊ“'eû ܘj™ö,èèšÁ—qû ˆÑÁ‰3ˆÉò¼í÷×W¯ŸïnÊEÙ~ÿõ³²}±ûý¦Ü-õâßvøáÕv›íWXvwyó&ŒÓ7Ûvo®Þ^¿Þ½Y"Ä2ôÝîç_^}yõ{¹hЩ•m!bõù«½º3ñ÷Þ!í½·§åíM[£ß7Õ‡Â{SK 7¯³WD‘u² œ¬VïÕV Õ¾V½ÒjaîÕ× ‹Q]i7®b•0"j•ÕÂ~·-Þ£øÇÛâÝNø«äç~ü£ŸF~–#Èÿ¡p’ŸäuÂc€ü>V ³Ö.´NXáZ-Üz×uÂHUW Ë´j«…¥Õ&s0ü‰@¿V©¯&ýXç÷(ý‹OÏÙïSz|*¥íJÛ1”¶c(ý0AµÂÈ+¯T¹û¬s­¬Œ:$ÇÂâReµð£„¶cmÇÚŠÑ ±`þ-„–û1ZŽŠÑ.÷-ÇÄh9&FË11úAáÇ-ÇÄè…É«¯î8ï'Šžu°8ñJkˆ[õÕ‚HʼN˜*¯f«s­0*Lä£þ÷ðÿ~‚.ö©ü?&A_ÉÿódÒ½nÒø+Ù~qyyÄ‹¥¸•¢¶Þ·’mÏV³ÙZ¶ží¾Þ‹šzß&ž&ž&ž&ž&ž&ž&ž&ž&ÞH¼‘x#ñFâeYEô¾M¼‘x#ñFâYâYâYâYâeê–x–x–x–x–xžxžxžxéâ Ê¾MûÓÍòüí/—ÿÝl¿¼ºþyw½0³½ÜþsûÍö« Z‚˯± ˆ¹nŠò‰ânVÄaœ(ZÅ!öŲ½ž—í?®^\ìÎÏ~ÃæÀNütE².¤Õó"v#âQ|€y­V‰ï@`†CÞ8eœÂVˆï<Ý–’ÎàЩa{pÙ)ÃTá¾Üß#Ý`ÔQ©'œ‚tçL¬¼ÕpxÄÇ¡[%âr˜Çyb7¯3>5ìO›(‰âDï4ê¡0¥§ •K#)—Ùª"G •âÃ\Ç9¦rà×SÆÊ¸dG!6J|TŒB‡âËjmîça% ¶ ئŒÃSÑÆg]œd£ó¹h™îè£FisëÁI†ÓýLG×­;„—àpç#¦tN0ŠÝ†âH¹ŒÇ·ãˆ’c¹g“¦çT‚s"jùÛ(!ÈêPùW ^®6Þéu’3é°?6GUÐñöØ`dusœ–{pTé; 0¨Ìg:> stream xÚµW]OÛ0}ï¯ðc#­!v¾™øTdÚƒI µ–Äã0úïq3š’ÚMaOTûøÜsϽ×vÀ#pÀùÄQ¿_“ÉÑô„vìû$:ÈŽ"„´¡$wÓ«ÅÅëWò]nt¼ÙÝ|\ŸOÀÝÌEÁ4Pw¸r‹v}8…qƒfг=/PÖ¹ }´ †“}_‹TXò´m•«Ýa»¯ŠˆÊÄÓX0Eïé Ilj;:sò—¦ ¥ß…Æ ,Æc¶!ú óôöÇ ÂѪ4Ÿ› Cm\l%SE+,(+›…ÆvŒüþ)U}_ *êvQ‹ºÂD^?~SÁVÖLªÊrö¸¶"d´ßÜì•îfL‹èøêÒ„å|Ü"›*IM¤HR¢’dJ¸Äùº¢&\gdºVÔÅ·Ÿ—‹}Ô„cлq±l*d³sÂLÕ탔ìÑF >)üÕaüͽìÁjã§¥…¢é“å{SÌ).›3…ÑÑcEƒÁpªÍq™±¢#Ö2¨ÛÖwß²&Ü®×q\pBL†Ð£]?ªJæCϧV)¸81P‰ÇªiU®ÈŸš”)ÙìÞ;ûíœ@xNpç&ÙÈ‘³zÇ ¦87Eãíès#J·"²r5^q!‡®!ZßÕö ›Åõ“á•hgæk•2Þecê-x“œ^™2ÒS{7 ÖVkFòj§©pAK¦æBJ3ãFÅÉüx¤ ýQ©Ê¢¹§©¤§Øœs½Ã“fäpœšVhºú‰êH> stream xÚí[M·½Ï¯à1¹pXÅ*’l J$€`éd¡ƒ"/#†ÖÐàüû¼ÇîÙÕÂRïÂi÷%¤îžÙîâëb}¼*rF¯©¤Ñ-IUœ=isœ[ª1pîÉ«à++•9̬ç b`‚ROˆ«ÎA0ªo8L b ö&Ð.F‡QŠ(Õ àøŠzÅÛ‰8^*ÀUƒ[DÃ2`Ó‡u×q 8‡h¡rÆP¥v¡OÑJõ¶Î+Î%îðuÈSJ Èĵ?Ý@!Õ„m¼íôäÉéüòß?]§ó×oßÞ|8_|üLJùùÏ?¼ý×éüÍÍ»ï¯ß]ømyuþãùOço¯d~8¿»~ó!]©Ô\‰ ×ltí¹LŸË°wÜöuzò$_¤ón^Þ¤óÓô»Ÿ^ÿó:»ÿ>}õÕ ÿþ{ Ò0Â\?̘ôÈÞy–lE¾ Bì7a–[‘;Þ2ÌeDÛ„Jσƒ×’6ª€ëÁ³—Ø1öa¥eƒ)6÷Ü£ÀÀDZ¹Ôq ØdV$°¬!ˆ¾™‘¯yÍuDì ÂsGÌEøÊ‚(ZGd}Ú€íõ£¦£d„à&šrª‰å‚\¨Ÿû¦s칓Qï0Hɺå{F‰Ëdø¨¹#Û_&ÃŽ{´oxC¨’[×YȵmX¥ÛžŠèÙy‘ó¤3!阩dË?ûžŠPÄj̆AàU&˜äDw¥‚Ž‰Ù— áÚrAz½ ¯#Ã?މÙß¹ßù§+ÕA“²šƒ±!§à"µ3V€4– e,a 2gƒƒÝT˜§‚Á"liÂÈUªrb RY=h:08Ó…!Wu°6F.Tÿ¬±-w„OIC¦ª ì–ÁZ uIo>Æ3‚õ]"Xe!} m"jöܶU-{º'n¹a X…¥Úƒ öÔÌPÈb¢,¾Ñ0¨¥ÄAfI›Àt <Ë}VíæiÛv¹«ƒ‚VÓz®¬¥+"5Ü40Ë!ÌT…RVˆ 6£ 8WEÝL]²#ˆŠ¨(Ÿ€°‘«<Dß„²Ÿ‚-ìZ`RQ¢‚åtíiQ’fy aršåƒ öÔ„ÐQþÂ<[#±W€RhH޲ p*ù„‘ñÊ#@ì% Ó ¨‡ÙH™”šëìEÉ^l`H$s¶Ig:(•ÒRj;*‰ƒ¿u6D †n¼¿vvm‹ØiÙ3d×<@€\FÔ²–¡ÊèqT¨ÕïzÂÑÇ€Ø3ƒ2H×$Y› Ã` à5 ò½é¶'ÓWðø£€nwFKaá9ÛTõ ú³âý;›Ó&­pdö¬Ài<â2 AÆ»ƒ€ØÕdƒ`ë½Rãiº éû]:ÿõoO1\è^2[¨o?þøã«/߬ËÍÅñÚ÷ï}vóöÃð O°6œO=SúN[?ˆã/¾~@éV1 ?@Äùù»›7/®ñšéüüé³t~yýó‡ôê¾æžã}Nço1ÒõÛïS´àãÔÏû›ïÞ\¿ŸÝÝùÕ_®¿ÿáõ77?§©Q¶*ÌkÐr8]Ï_¿ƒvÌ—Û眼ÇàìôýËyÁË6ÿr^ÿ®ëßõò÷¶žûzë9–s-ëYÖó*¯®òê*¯®òê*¯®òê*¯®òl•g«<[åÙ*ÏVy¶Ê³Už­òl•g«<_åù*ÏWy¾ÊóUž¯ò|•ç«<_åù*¯­òÚ*¯­òÚ*oz6ë—ó"ïÕNMå*l§Fª­tܘýÝ.…lïËÞ²£¿²¡Í׾ŀèEvñ †=›Ò2:@ ¡U®ŽÈl1G;¦yÈ<á°Iö°iÛŠjPxص±cÚUŠ˜‰ŠïDEƒ5<B÷\l!¥àB ÌÂi¤\*ôŽ—m0ø4ÐjÉ…æ@²…ÐÓ¸ÎÑú1䊋,ƒë§¨ÀÐQœ «LózÝV$<®Í:¤CÚÚ;»Ü°•c  ÜÓgÿXQ’û\û›ËÒã¨æW¸†qÁ%(Ì“Ënnlr—l›QjO‹`g¤|¢;ö öô ](Ee6Yƒø‚¬xÅ·ÇtÌ´‚VÉÛ-ñ ‚=S ½Â¾~A­E‹l‹s¸"PêAÕ8i=iÌ-¸E³G€Ø5F±Ô`÷2›k …EÂB ªÑ²Q…úØ“w›MtaÖ˜¼ P¶­–€ìi• +,8¦!Àí­Kh²ÎÆY;Æ&yKÙ­»€@È$E}ÄžÞÁ&2x.ëÏÙ½+–«÷¹Üå õù¹7£×¥Q6 sgßr.8Ø–Mì ©‰d‚Ä ³µ`kßXÒª‚?€M/Íô¹ûÈ< ìÚ¶6KľþÙ û[ ½Ì==bØu.µÏV~‰…W²úãmßt=7ñtD&¸Få&j"œML6ïÂàä¶5U,yàÎ*nŒ¬d8êå p·Â³ÎµäÁe̸mí"¯{l‘æ‡ :Î=žÐ4#(A¢× z],é@˜j 3윱µS£³àDnÛ§™»QÓ]+ã6w+lÅëª{ºg .U¤MZ#rFçG¹á$›©ÁÁ¦}a´Ü¬IÁMŸŠ<æ]ޱx'“fã>ÊÕ;¹óN7ç÷ ìÿq÷329üŠñ£d£]Ût©Kd@ƒb Ní¤´qP½5$7¹ÃŽ8ÑaçZƒ;$˜¸+ ¢uÝ1[H¨U¿(¹÷ƒMÍÁà™ÎÉdS›¡i÷Ì,@÷‘¹Ù VÁ”Îv]…‚O±GÖ øåº ÐP{„÷ƒ@À!»JjŽlHmˆTl¢ ·ÛÀPƒÙ€ pøv6\á~uwSÏü­¨ùÓ‚V¹wfk½iÏ-— Á•FA&`­…hÉÞ±VøàFSÆöÜE„´ e$6;DÆn©ÀLËØÞ¤`º¿op·)v.¾áÁmZ±öÖÆ#×Þ>YOûU«fWH®¹¦ÿÿ'¯NWÜÄ‚ê荒}˜–£kÏãräŠÐgްÆ{ÿ¥ ¦³Ë©¢ázüô©VGŽÏGŠÏ…ÛZÆå4b.Çîó?ƒ~à8ÆãÇõþUöísÄåršùc¢ùÁØšOîêò•ørÚúTæ15µˆX¤~é(¶èvjsÅÝí>÷¸#Ï\U0£qã¯:B6ß;jV+ùôÚAÍ9§Î™@LbD꼧Ϲîƒúf …§:5ŠkþÀ®L(ü>ZêªTVÑù…Í—, *h`ú˜v0-L·¤fó{ä8<ÆL7¯K6GÁ1W‡¤–Ä=bzïÈß3f¿œlîÁŸ:oð‰ “gœq¶J#92ɧåñ÷uÙ‹9w âœ2A€3>„ƒiÁ÷‹ Æ·íËœr~,¨5nêåü!!µ6Ñð·Ðùðßºß endstream endobj 989 0 obj << /Length1 2403 /Length2 17686 /Length3 0 /Length 19083 /Filter /FlateDecode >> stream xÚŒ÷PØÖ ãîN¡qww‡àîÚ@ãîîîînÁ]‚kp ‚'8Á^Ïܹ“Üïÿ«Þ+ª€µõ¬µ÷9]MIª¬Æ(jæ`’r°wedebáˆ+ˆi³²XXØ™XXØ()Õ­\mAÿµ#Qj‚œ]¬ìùþˆw]Á6  +8PÁÁ ëf `e°rñ±ró±°ØXXxÿèà̺[™˜²ö $JqG/g+ KWpŸÿþ  1¥°òòr3üµ9[™í @WK¸£)Рæ`jrõúŸ4–®®Ž|ÌÌL@;&g !Z€‡•«%@ärv™þ¢ PÚþ¡Æ„D P·´rùCÍÁÜÕè € ¶V¦ {pŠ›½ÈîP“‘(9‚ìÿ,ÿŸÀ?âX™Xÿ-÷Oö_…¬ìÿNšš:Ø9í½¬ì-æV¶ €’”<“«§+hoöW ÐÖÅœtZÙMÀUÁ ÿáçbêlåèêÂäbeûGæ¿Ê€e–´7w°³Ù»º ýu> +g)Xw/æ†kcïàaïó_dneofþ 37Gf {+'7ŒÄ?1`Òo›ÈÀÉÂÂÂÍÅ 9@ž¦–Ì5P÷rýídýË æàçãèà0ÓùY™ƒÀ|\€î €«³ÈÏçOÇÿ"$VV€™•©+Àdaeô»:Ø 2ÿÏßÙÊ Ç^?VË_?ÿþgÞ03{[¯ßá˜YTVV[FŠþÊÿ:ÅÄ<>ŒœìF6NV++;/€›“à÷¿uþUà¿ìÿ¶*­þ9ËïŠ2öæÞÿ«÷_"îÿlÍ?׆ð¿Àû Ðü^}NSð/ÖÿÏ—àï”ÿ»ÿW•ÿ×õÿ¿'’r³µýÛOóŸ€ÿ?ÐÎÊÖëŸð>»¹‚ø†ØÿßP-Ð.´˜ƒ­ÙÿõɸÁ7DÔÞÂö_­\¤¬ð3µ?*.àYýí¯Ôÿ¶”´7u0ûëî±qr€ÎÎ@/$ð‚±qr|XÁ—Ô äù÷n˜™ì\Á)09?€¹ƒ3Ò_åâ¯Ó_¦ÿ .³ØoÄ `ÿxÌ¿/€Yò_ÄÍ`–úXÌÒ¿€ùýoÄ`–ùÀýä#p?…ßÜOñ7÷Súñ€û)ÿFિ¸ƒÚoÄ`VÿÀl5~#p?­ßÜOû7÷Óùñ‚#ÿ"vp$ÐÎ| þzáþ[M~#p¾é¿ˆì3u°ù¿–¿fÍlökúÖå?köo˜xú@Ë?’ÀÄÍCp ó?à_N«ß%Ùÿ‚îôøËïàæüG9pˆÅ,Ýïf`é,½-ArÛ¬þ€`•lþ€`Ò¶@°"vÌÿw)Npª=xáÿðƒÙ8üîNvø7øôŽ¿ÝàbŽà8{[ùoÍ8Xÿ±:ÿ”`qÁórø-?˜¹£­›ËõÁ§? X‹?”bÿÌù¹ÿ¡ '8Üü¬ÿN÷ü}ð3Èìjé úc`®$€qû‚µtÿ‚åðøcÒàì?š±Ë{ýÁRyÿ¦ ®ä rþO«ÿyJLÝœÁZ¹þý؃7í¿øïÏtÈdŠ´ºä`Êjý)´ë¾^ô­ãÞ´à<åžV&-£Ïªs·Û/4ø4ÚºÜàoη¢icë;’47"k$Ï>ÇíMð)*¾OFIª³{H+_ð†gJŽE‡ˆ‰ÕEö}Ÿ|5ƒl Û!{e) œÜxД‹°ï=¥=‡*¿N†/í©ì×qÉ!?UÎ1ÆiÄê•-Pšä-Á¹2#Ða]x¢/ÜÜÎcåϼ’È&Ñ#ùı—úèn±Å?,zoT«³¹ôRêCß`MÎRùˆýH—Å_ö)ÿ˜ óÑœØp©U¨èÄÑ@Ú»*P91ó}‚àÐ(H¼}g6<ÁTe›RlìÐV-¿‡« ‘»lî™Õ¨ÉE¥çàÏ;¦f!×9DxØÆõT™-"ës²í»Ða¸ž?Ò—¹V‹†‡xý稛’_D’VØL ]õú}€ž¨§=PÜ÷?ýff¤í>è]«ëœ © #޳Z’æóß~ЮÅzµ‚|[7 %g=ÙðM¶×íõ³â‡cÓá5Cý¨­e'õ=·Ð³J=Ðl|¶5Ÿl¿=Ì„Üc49›ZQ½^êñPž˜ –ðdµd°Cè'îºr °$=ªˆúM[„ÅuÙ21ßtÓlÅ\$ò¡Y˜Y²ï¬Lå—³°÷†‘ èµU3 r ‰sÖ¼*v­”â¾(¦É/W½²Lx\˵ Ä™ê„ c'dÍB¡Î4„ÕŠÁ#¸ÒQ¶CÈs„Zu­ûo-‹Æšé35^<ê^î =5Q$î~þ²­ÿ]K‘I¼”FsNÿ\qŸ¨ {  vATøÒÖÃ¥¿B!\¹õ®¹'ÞË\Í«üûR¯ÉæÔgc^7bÇøá[åíÑÄzE7ç%ZyA7ËŠøÅà¹Q‰éÕÂŽ~å…Ã2?‚Ö6ؾ¾¤]Æòio º©¯ïØ«üowÞ—zà‡xï©ðA-ŽÁw’ -}ŸbJÅ5õì¨Ä+v'Ȩ|C“Œ% +͵’Í)÷u!»ržÞû Sº»’¶/ÀY§:%šo¹gÌ´O µ¢[Fs1èvi¯@ëµ=GÕµ9—wVW7‡ØÎ×ß!4¢!1h,XFß.\"Üß>+õhïå¶€EŸðÙ\%Çfe &­+HiðÕamcê4>§¦š2”fœzmŸ$(£ß¼!õ‰¹ÔT+#D"sä™°œ2dü—ê0>zyhÇ4vÌàê\oö…ãv é2âõ+ÞÆXU€ ·î¥_Eîz¢ý±7(Œ@^/kñ œ]3cÝ·¾-Ž8«©šºŒuéýµY ZkréŽÍu(gEm-…þênw¥KJǬ¸IÕ¤ADþÀ*nŽ’ØØÃõ¹Þ!xÁú‰JM)|Ó}ö!öú ›!dË#ØS8ÛNÜQ{„ÄoÀì½æàÖ[žÔ…^¾‹Â2½,Š©|3¾/V¦¸KYÖÏâ l»Æ“œÎµò W|Å»%£¿¶jz¦ü·^L °–ŒË·¢°IÍy„”êü¤J*nk„`Wö3±ÓZ2á÷8Rºˆy¼APô²§°„6˜„(B ïýk «F!5„êü1±6ýiaxñÓ¥óqŒBég"à2Øî»í²­ö¦óX!œÒ*N®‡„t«Î&7…gâ§x¶•u!í~$‘Û$”¯g³Ë#¹:Þ&¥>ð~t´”ì3Ò¦öJ W¼Ï„§á}Sv€oƹ$P´©ÍQ ÛɉMšp¢-žW/ùNö6¾ª§CeÁ@»‡ #ý]SmÎÓª-]ÛÂä[>¢fF!"Ç1îÛ´6ùŽÇ¦‘Ý#âþ#¶77ÕÑXfY¬%S|ÌA¿¤ 8#HÝë~q…h*Óôð¼ìš>€ž4•8Û¥céÚæ–mTnR~(H/'úïûU?Qçd›ÒDaá÷Ý﬙¿,®å†è+cÐrÔ›/Ñ+9jEºú8ÓõTu), Ä7=2»I~>r(‹b§zXšô¼`·’ô nÖC/µ;ñ¾KSާ ž‚Ö“,àðÁtôVeÖz8DcDì *ÉÀî7§ØY¦T‚Ì/©»ÚôœrZ˘ò–ÄY܈4ŠîˆOº©*÷¾2ˆÎ"z0’Ñs4Rl– ͵—d ’ׂDäè´ º$£ê\aŒÆe»SGMˆ§‹#НtÍ.*,#Ò?Å$ y*žVm:î$¸@Ìk—–\U*µºÊŸwˆ»ž?.(Ï{Ó±&Ë!K¯o‡4MB$KøÈE0>`Cˆ¿dÄK§ˆ0–˜ë×ë¾ü°äòðE7ܬu÷Ë™DW†/ý†0Gíë"ºœqb.7L]ÃJTW–¢fÿP2´ãO`„In@ü¡Yßê‚÷AvÊ*wÜi"ÓN ×0ï.ˆô¢S{€Dó»²’Öäò¶Bâ§°ûî.€á­«òÖP~ñ€EñHÕ)û–ô+÷˜›¼R×´ IÀ”ÿٓц,â³x°Œ°çÏRXduo—²¦S?7yãt…•ÀÊ2îr=óÈÐgw—»á<^J€ŸËËÄßwcÚwLáDDì…«ûiri„8Å?³º 쟲Óç6\>çIàwnÍ«¾F¥”¨£¶Nš6ÀW±$…P=yIè+4aªñ¾_¹P‰ëZÌs6¿–.3|ÒçäŒH#ßYuÇÕ Ó™i¢Å=À“ÛU+5$jò·oϪQx£ýÈÀCUÌ D6£xÉØHC6teÖ Zñšé è$(C¸ªæhS‘ó¡]œ‚Ó’è2êtx:ZÓÍq\M{cÊBQN–5Ið­¾%w„%ãê•‹C“'QÖžøæm‚ö1_7ÜtîÎï5è”–_~EÎ\‰ }£6h{ @£¸Ð¤‘XÇØzívȽtCQ­j÷ŠU·±Åê Þúôþte“w6˜1•ö¡÷Ñ­©ÏǶÉìf—£ù°Í»ÂTÞ%"ï^]N¶Ú}úÍSØ~¬°V”â}Œ.]j½"¬Õù™¼ù•¹Ôs™0r1ÄdªÆô¤pŠ´`u[ìÈÕàÆ;X¿?¶z3U•9Ë™£äøÇ1žÂ¯òt¼Eˆœe)€Ñs'u¼Áe@“nŸòÔ;ÇQÈøåå–Îu£ʉÀÐ1ôiùjFè·CH3¦¸˜•1ëwìÒ~¥ê„ÔÙk… ö}䣆BP sKÔŒ9m0›ëR÷= Jê‰u.²™*o;š~õ‡øÀ#>u«oö´^³Õj&Õ*º|›‹¼Dè¡ Y³Œ½üJA´ÌðýJ(?â͕á\ÆÙû¼™:´ô@[Û´F¹Æ7µlMËy'ñHÎìe)«²ÌFâ÷;&Û•Hë1)Jëürå&$Ö³No¶±Ú­ÀMz;¹ÖÐöás²ufvÿâÁ:þÇÛtî"fîþÁ ÆUÊÀèý-ût"Y±"û}ÈW.Q–ÃË>U)Þú|õ%ŸDš"ªÌ Šoa‰|×–½oî^o^­ûàËóQVÞžP&JAák†¾®EJoº·à «ñmóÉ‚U‡'[ÆÐï¶ysª b &6tîôìG3Zj®G6¡âpæ·z¾/…ðQüê%'!|ÄZ´!F&þi¾iZ˜ž›?\‹UÜ„¢ìñV²™·ìf†B±3tM è¹ü5’ÌZ¶SÛúYÁùÍÊ‘d]ÓIÞ¢üÙÒ:súRH Ѩ¤™q(av¬¾OîôŸ\äo{_¤WÑ‚‘;䣨ÏÈcicn¥ø1&EmÌ)ߤ{×Éï•ïô+ôM¾ï,RÜ: öÐN '2|sÇ/ã€-¦qt¼Ê]ËTÀY±C Ö²£*Èj,å’h’bïP{b²Zì—W;eÚ¤ ¦‡ŸÄ2tY»Âãêº6Þë×fïJ¡;ÔÜE抭[<æ¼ÈŸÍ²_¡&ÎÃ1(]Æ¿ùçèCƒ¢îç hâÏ×øö.l%³Øëë>a{;ÒùKD>ñ ÚVÿrîóüXí‘î˜ÓŒ6ï¼–Åì*\ï9.”0n?‹g>»1àg¼:ƃ“öS£xôE¹ûÜbãF}ñ\—á!u”ºéø¹‰íN{Ê Ÿ Ýf¾˜øŒ—p¶’Ñ$lGÖßvZƒ‰äA¦A(kËœæÅƒ CY„œƒ‹™I"ðMÇ áëdþ¦9‡´ádµM2ÏÁç)¾u$„¬æ—MFlëŠÉ›´ Ó Ea܆ü§I˱;z¬é¢€è_ÃFÍ.9†Õ>áçý fº–{YA6üœt~i§lº”b'|²À(Í/ÝŒ¡*Rð[ùZ>Êž/a3ji§Ÿïìf&ôí'ÿU»è[£ž³(\$)£Ù,S›Åœ…˜{{ã¢_î˸‹´lÙi_³’w)ÈOQ¹f}^Ξª¶k[ô¥Üo4N´ˆ‘{mÏ(=aõ,š0Nì¹üK±Ä‘p×É’“ mlÅ?{¡w¬S½Ð~¡´oÑZ”ÊUb†ÀQÀÈòª ÃY8ð¿Òuê>­X#±’) ¢ø˜/>¡žCçR9dðXyN{Mb• éÊ¡›“® ±``·¤9‘´¦ô˜X{ÓEkaõÒŽtIÉ%«1\ g^¯®Í½ÀÌô&Ì4/&A&’áÎ’ûœG¡ˆcæˆÑû/ßÎdãwë;g÷›åëxrT¡ä“@ÏËΣ»ÎòŸÛ󑽪Â+SBê¯g8ÑgUE˜}ÌUÄúU™÷!Œ.ßú¯ì87’ÖAst>çÏ&ÞtÆš+;´žö*ÌÓR3d¢q1Õò±\™;cŽšÍ>š´>hTó›{9•ðFžu ^lÙþ¾dX¾Ùèï#ïã$ª¡:gIAÃç­¨&+¿áEdmøa0u$™¸2q˜èíœúÿ/rºÐ¢¸¿”Y`‚ád•ñüi„üy·©>—nº÷o¾’!„ÀöÐvGhs¼´„Vœ *b¬|ª Œc…Ý^r‡c]·p>äàjäz›„wLúrÕ¬xýÜo]´­ÄA\Þ³Úc²ñºWÒéZ(uéu¹ß¸wó“êÜçÊCE^7Z6¹È© ‰¾ý»òùŽ=Ã7k{Is;ärUiâ: ˜š&´:žì{Å0üòâ×<9Œh¾·ƒ%b¤•CøŠÂ²¸ÑçÔË¢L·6}>Ê£Â{Ì&E;”¦ªMAáßí»HaèBv.³ yqpx¢IÖÑÝŒÔó޲Y[PH¨Îè`A%ІTen2¾7¡ô¯K,ÍdÈ|ȉføjð5U\µ7Jd’ËÄ_..¥> “ Ïê‘…y²à@`î<#gÝèúøÇ}¾Þ$a %@9噡nÑElêŸ2RZ˜¡úw$šìüÓZ¨:Ö(ð¿„¼-ŠWÌ /ºe|Y!@Ù µ<Ô|7Ý)g¶+˜õÇö»cÜ/@îQ„ÍÕÂÅÖ2ítNø‚}…+0 É`©OÁÿ±Ú•H]µG§_â$ í‹|¾‹ŽO”D9ò}ˆ„°Bßš¿•¾Ãl<ŸzjJN%Ú1e8ÿîvÝH’uÉ íiü ()‰¶ÎAÖûQ@ïh¬Ú–;›r¥#ë І™M¦Å&Šº¦ÌÚD`R, ëÖw„_g; ¹¶×¶OÊg¥’÷6w¿” ›šA(Äö˜¨X×ÉI¤Þ/ŠG<¦þŒ‹pÍ÷RƒðÇ'=¶‘ Ÿû¶É½}Ÿk£F¢hðrÛæuéõÑÜd®KVï„%æR5É‘2±¸ÒV—&b˜_Ü,.\q§ÁÅÛÎÚg+xìi ä"ûŽ¡öÞ¶]lz°‘wŽóùN|éâÚ,\æxÿP_º`ãüÓ_&B2¾Ôîzág¶{MT À^¶gepÐ÷Q 0‘ÖÌ-g"yüÖ>ê_$ì|Æ¥¢Üâ þÚôFû™=ªäÒ»¢šƒ®Ñ›f¨=M¤ˆK,ÛtAnß`¿z_›ìâ×gÖ¿=®rÖ™=ýøI1º>¿…òj–Ðârô†6•åT$WâŠRÏÁÕ¯­­i¶Ã5‚ûDH4oéºÓ'€•bÁÜtÕó³—y·‘Ú+ÙªÐ#“…ñí1.é¤çÑc±´wO£fÚg‰Í87ñíÚ’~ ¹§aaû -¬N£ù¶¶*Ø\ÏpVå¡AÉR‰oزžt¡_6¶)ñ6Uà =¦ 6Bb>ûäPIÖÄòÙУßþÌ&+oh•ñ-MCÊ÷_\Ë©3—«°²ñ,$œy÷Û5·çÙ­6úÛÚ ©3–´î8w¾o8vI_‹Z{Ò-Û«®d‚1xé7À/ mÁµ¤|öÍ1×{[i»Îþ5h\ï[„÷0Ú3®ìâÿbó f´DÀ†¯\¨cj„‰40©uwæïþÎuݰÝáø¶ãPi7·¹Ý£ëË1{¾ ½1rùulhÖò5íqŽÎc” jz g& $:­¼‰mP¶‚¡ž-n[àTrØgà.^ \ñ óþWm|ø1Ûf2±¨Z?XdšÔ5w×ý´Ë!CMQ»ÊÀ=ÊÚsƒºvFFŰQœ¥ó–DT-^G‹ÏvòTÏÕM§¥³GÆÅ†ùÜÔyâQŽÒAþw–ì¬Gßç/¨T}ÑÈ ùû_÷}gI~–¹‘ :á„ÂëÖPˆ*•Íy:Kà&S^¯¾êjB¬Ç”’PhP¦+ʇë3g$×Ð5ªÆ„¹™wáÉXF„ꜞ'ø© -am¡•[VfBRÀ±;žÍtö„é"ø¹Ýp÷ÐêCyqâfDŽáøiF©¹ —³Øß˜ý˜UÈñÛ)ð¸ÆúÑÌA}zä(‹jÅ`«AVoô¥~CïG ÈH/¹Õ¢!oN‹@J,d¨Ç,<ˆ¾±Ì¶µ[¬Ð,7Çû\hW¬>‘Íñû;=2|¼+ëeàp]æ§µ‹MÈ  vp0úuñò²Ã‡b¬Ù$yÃEPTf8²RÈ—U`݈Å”ì¼Ê•Œ‹žíõM¤—Lp$‰÷Ó̦çàªrµ’.ÞŽ¢¤¾Ûƒœè\ì–k†Ñâ* ±3‡GÆÕK€lx&ÌN¨]¾°6¯bvhT¯TçÌ"§´ýÆcV÷íýkÿ…Õ¶ÞZñûö´@¾%Aé²Ý‡›‹÷ø1¥釃¢î¯£³ÅLÛx6›MÍdð'?QÞ¾ Ó]}‹}AVÏ#b'©Ÿ—†Í_º¤Å¬ë/›¡9|P~ÈvµfKɆe²x®ãj–€£ÒENÿ„[$^ðeã¡s -iä— Ý$%Úà ª&~ÞÕ3pRû×ÙçP½é˜ ±ÅÍ5K¾¢C'‘öº$Þq*åd°9ÌÈ:úqçÂUÒu]:L=ÕëAÛ׺ýL!Û4vµÁõâÓ]!#¨ŸyrŽuu…&ßdî•äi|Qhv{úð Ð#*¶ï ëŠÍ†{Í ,Yÿþg¹pˆâl…ËD,”;M ë¯ÆP€úë¸ Ë°:Ûc‚ESñ³|Ÿçy*Kw’DiÜ*oôg@OéE”8K)Lz´'CL†å—¨¹àüÛ—3¥âa*ª(;À:n:V©x#ÒOÛ+wï& ñQʃêÜ–uùÇ„<ŒÚxƒÛ>Ñ}–_ú´··£¿<íyË<©òfr^Ñ)Þ¡æÇTõyâBªæ"ùA9KJíOŸ;‚¬S¡NèBD–«ß„aâËë®þœS籕spE»‹ ãÞÅÂ?,ÿ€²lµD±© RdW©žl “îžäp]/ =¤Ýòß°¯ôdËáȶ²´¡°Ÿ:k~_ïÑYR&eÔVR67¹¸«Gšï7ÜCê‡]ëA2Þ(\+ ðä¡I‹ÿ.~¼ïHóó%Ú«ÈÕ¸ô‰î•ä«·À¬:t¦ïIud­™RåÊ­þ»ÌUê©_2ý!¾!èè‚´jâÖUrééíYœpÅGð–]¶ ‚Æ Û"©í°½X»é?mͶͮÚ^!ô3Õà‚U¥DhKó¾J V½Z½a9¥šƒ(n.Z»'“¡þ$`èðða±íÙT™NüSœ,}zž4NKòÀW"ÑfJ´I2‰Œùùš‹uH>‘ê€T7Lj%ÉG“¤%†NHfýÁ×Å«5¶š^hÁ‚”-e)›b” y!ù`&1D¢{•å¶WÆ0y–¦ý ¨Á|Øã Ú4ý[>¤ì©+L‚ZÚúcœCn@ø”ÐñªÖ”(’fÄÆ赎Ùi5nqBŸØmÝŒ5<Å)ô@+†J9c¡©ÞZƒVù¯ÛIRÒæl7…ÒŸËÊy¿Ëé•—šÇA¾·×ˆD½X9|MgÉIñE/+ŒËt¾t-eqšjl$5ˆÊf9DmK0@P—³ Ô,Õò³œ {úVg¨=g …oÀ¤ñ<êÏ&M{:¹D/.wž’dÑ&|v•jN¾z^™Ë!ì-A}™*TlL=z÷+#û G‡éY¬×®ÏíîÂñ¹Rï2‘aì³q†D­¤Ïnbˆqš†×¾õò©ÝR¥52õú–F±/»jb «"Yà6²Øˆˆ‰¶ûŽ-ß.DÃîpàÞÏ•¢_˜O‚€ºeµ§/:®ñªÛ£=Õ€dA2/UŸ6Ó|òTd¬=ŠñXs@ðMîëKW6¥÷ˆZjüÖlb:ûgØ­*깊š3ŽYÄöÝk—|$—·˜­ßl…ㆦßó„Q…2L'Zõú]dX'sÕµ>PÚ…æ§¶×]Ð&2A-)|zQ‘“MM¼)€Ôçô!¼˜ÏÐô{f_ƒX“Ôõù¡¨™|H¯/ŠXIÞó”9–‡\‘eœz!ùd™œ"”¥¿sÓ’kŒ%*lÃø¼§IfYçð” #a¿¹‰VšýéqYÅÙ4íÌWå©pÓR± ­uÜ:Û˜”ƃkšžú="±GZ@¯÷Œ‡8[}xãGJ¸Mi9'8vTq»B8^¯Zš']D U"·.¼1Û]7õ¹iþ¸Žz„¶«v¸vJy?ÆÎ:븰?ô‡ƒ›rÔVìFÈÜ$áUñW®½;… 2TfâZ“i‡Á!Çש˜­@Û)yÌ Ç|ë„MD·‚`û°õpJÒ«Ñ(DÔW4в b\ …óÄÞ|QòåQ[Wr‹«Ñ2ë4©‰UØ›äÖµf¥º´åÉh!ïf¦ F,“üæ› %œµzçÇô«–“©G9Ö•h»‰Ë½0ÓЗ ée°˜D©š"x¿mxl@~£¸ªÀI›€YH3ç™^o>ÕyH– ½)’}†ë´¶ZµS/I¤ê„¼º¤Ÿ¦Ì«Â®:¥O{‡Ä*XI¡¨ƒ.¶ /ÁÓþ­Õ…ad¼c€ÀÚÞÇGö¾ 0ÿœßÌ‹þ5¨á’«D°þä܉?d}[)î$¡Å€™ý^Éœ†¯ƒêú”¥ÅàèM°‚Pb×ýKeë-»YbV$íF^qúÄ{€Ýfe˰Ù`çu)ª·,·ö!аó4ôþ‚"œR‰DCm®Ë÷k,Óô =u»{â :ŒÑâwGLy@'tÑk“î.™™…ˆëŒcÅ“™Èú”n%åPmªO„ ay¹+¼äËÜJ|µø™CõCÈC]B7dzí×¢9×Þ· Ó)«fO ƒ8¯’´Ó´ôp¼.Soñ„pŒM «Å%ñ˜ÒÒ³ Î_÷KF£Ä„-åúáëÔ¥‚»õ©ÛGR:zR)”N|ßåþ:ôEðÚ±fGxÕ1ì&x_|Ã-*›¸!~kU¹þ:u0ë]öþí’Å=gúàÿƒ›²û.ÚP—:rX2UÝ¢Ÿs„6žýÍl5 %ÂŒþ×N±¦ ¼N7ªáá«òE•çÖ¹ûsé0IмZûÒ¨úHs–èrÓáån!é`â± ÕNÖÙ܂ܨ¦qœ¥gm¹ûWé ræ„u;ÅÞé•>}h PÊ‹©(ã0ºaØTIÄ ™¥oú5¡Êßý´g›€“ßf|]^«âp·A\Å‚£ñÕý !¦VßÌÊÈÚÁ ûÝ'mäÝõ|ð¼ñ¦S«˜« Úþ©ëÓŽ›4êb ú­OîÓç¨ÿq vuFJdh›·Ç¯©£¹È7ó«®+ìø#P‡ùµ|À³1ÛÙìäXµ¢• Lu Y4 æªÜ/FÀCþòlXì4Ç~:åsáîœmŸ”í%úN5J™µ—×êb˜ñ¾·>¦HÄ×Av‘üü0ºíªÆ¡Y^AÝIz>ÏÃÐ ?“Ïì7È&¨ùÒçLô‘7@~<@&Òh~l<8¸ œwk*9cošsâÓÆfÛ c5vH÷t'èÞóÕÑy°]º-eÏpÜ‹›qÐÙs¯;׸ÈJæÐÈí©i¹|“N"!{àEPbˆ)šë321%[‡Ý# DdªnmtºGÆ÷Ò•7çFzÌÅ×åÄ•¬³@¾Ý±ÙŽ2•,ãa“†Æq3|9˜ðÔÏ2aÒxDÂ{ÍéÆ\×|ËWƒÈÎ]ÝýËòÛxXsMŠ¡ÈK`á;ï×N_3 ÄW£#òwÒ”>×ÕŒyºÉ/4>_=½«¸S-Æêf? ÙBÀ}çQßkËãE>¹p Ö覶XŸ§mò iìÛ¤+Ð(ÇeO#È)‚ äÔL•Ö6Jÿ…%,bôJ²åuè¬0úžÞÝÍ)ŸºzÆzÑÄž»€4>†u)~ÃZÄ:üó­{ R–€€kDà'¼lþ scxþ~M?Kln÷ÅMìå³cmû=µ¿»% ëgtaeL£ÝxmÕäÛ£ì¯þÆñÜG‘lQ®Ì/o¦¦,«ˆV½Ëòº±ãoÈjÔÁ~÷©fœàˆÞ"©¥('ÀW|¬è¹Í=6Ód…øè °FØ ±ËÜòŒ¼“ךáêßKã¬U?ß=Ol8ý€"©ŸÒ×Úû“¥ì )CËЋŸØ‰ÒfÉÆ’ ?m·@zwsNÇRñÆìU=}¥"ÓÓÕûhøÛÙÍrƒüØé½‘ÉŸ­'ØÝƒ!⤆^kËE¸ŒÖ–À®~6Z¥i;y#®ä±“_›<~øÚσZdHŸ³Äwyq@ð-y¹|¾½decNÅÖµK€n¤fX ñŸÀžý€ µ8Gäýã Vƒ'ã89m¯®¹5‰-aGŠÑ‡·Ù´ÍN„Œv?Òš“.ŒÓAȳÄotÚ£©ÕÁÕËÖI:\! Bb6âh?¤C9>({%2á’ ,K}{qØ_á¹r kýëšðήOV"?ÁD]„œaók‘C?8ì(וÌÂx¬qv ¼òâb) —Êèè:–{Ç7e|I\^úì LíÒ ­™zÔç§Ý†RÎg gÅ ª#ù ¾AC,75G´øP‚çI?‘ÏfæðÕë´ñèpyE !‘GL’r0îãºÊ*„ûÞ'ȯÀ Õå "¡–¡/Ÿ’Ò&_;4¾r'è|OÔ°7ÈRíÓTg¯šR¢Õ4mÛ«—+ÿ@&M $.¬ú~ŒÆ~_NÃìç;È‹zýì.e3bãn“š$]\¢fâú9×¾jÃ+ýAQžO‘Ý)<¢RŒãV—U´ŠNfÕ ìüâØƒ2:qz Ý/3Ü‚ü”†Ã%hŠ;°‰†UµU”Ÿiž?Ó $æa@‰fÝñPfY‰G&”}¥ _qOè£ëÒ£õ²öÒɦW‰YŸù2ó‘U‚4·#Œóü­–øfÙ 'G¥åÖó|4¬'¶¥WÍŽKl|ÉÇ[65I¨L?}6·r“7}“ð:¦YjA<Ó…cÇ“z’V'Õ®L˜w–XTI„¤R# wå’ý¬Ç5Î\× iJ׳FZ –ìû‘Á BˆŸ4ÉÒ‚ÕE(ZÛcDÃBEQÔÚ ,?ðw-Ê#¸·báGQ³w8{ ô9¤_¯p#~dZ Wª27Æ*ŒÒÞ¶X¤sô”Eñ#†÷lñí5mæëôgyæ²Bïüx}…h÷Ån/¡›6åe†<Ã+ïBn µë–0娞'å7!l¾q+Ô¡ÿˆÄ“pzŒý(‹8…·š,—)éÔ«-ìC^u_xS{Ø ‰÷œC¾Á=ó&Iž¢æH"ú(Šù嬉5áÙðŽÀlæž½OÔ‹ ô0@ÀÐ3 §u㧉y»^×Ò¾€¯-yÖ4jå±çhGö¥ºë{±?!:l^ofªÞ)YnÉhBêíäT.bK tÅRRÜ›¼h%Fè¯ ¡É8ââCVE§È´Oeé':0•ðŘ®¬ñÌptåJX꡾ÍärD«fÆÕèÐ2¼É–¼½iA±!XÍyðýÈÕ–©fó±[,ý!ââñ_Ÿ+d2;wO,WJ».C×6ª4Â÷rŸÛ“V%H–Æ„â\\Ði!óG¸ ½ÕîÐɵÐ' !ÞçjoSrœMé=9Ón6—wú¥U|½ã¸4‹î ]CbPóʲþÚ…qµQ± G¾?V0²áÂæÏÿ%Kw$>U𞱎UEØ& ›€œ–@¶Û®ølöVAζCúÅŠ‹åàgê· ¬¸É‰ÔEŠØ¢Éšféù²ˆEb&[<¬ä 1–%®÷™°8Éh÷?˰¢îßй=1r즭WZ;íøqA3xrñkÄ é WœzR«üL s8{™WJzX´ì©µÿ†t °¢ú“ ÊB·þÂ6i?ÐøÍ9¯Œ×u¶LW/à ¶ä0Õ?ª‚ŸÃ$sÓ^výÄ."Ö[Û ›A±¦§è/9£ÊúÉCŠÉS:F«–Â÷sð²ê9îÑ»:z ˆšŸp,g)þ;j/™Û:ó"‡ 5Ù°Kù™J¹AžÆ‚ÑÞé³ ‡£ï–é0êÉ·a×ä:œ~äà¾îÑÛ²XÄaìÍ›'! *®„ì²D(©˜%„FÙvÅûþ ÐÂ<Œíri`“|ßø‰Çy„³¾ø=ÊæÐ­lÅ÷q;åçÖ’GÂSs®ÎsôªtŽ¥¯ì\h×ü"^À}Úæ¯,÷Ù'H|qUN¡Y=•ïô6|dKÕí}¶\¸Z>RÀ°i°ž` GÝîô,Qn˜«ç“ÌWC'—ÒâBM›°GÙ2Y23F0u`|‚›£èê…!ÊɹĺŽ7Ùk“PŠêñÀ4À¥R´æ@´Œžþ,:æw,éXä¾”a‹ãÇŸ¾§11X÷e~K2ºÊ<罫P¸ç/Ñ„Øïzd:)·Æ.‡G¬¬å FSo³D±LËh»§h´Ó#ýv6wu§m¨Úãý¡GÍ›´ ³Qÿ‰O•x5LòÓqIPåM,µ·°ºÌn“ÃL€Ïˆ¦Ã¢ø‡’J–YÞÏŽØÏÆQŠR’Ÿ5Ñì¬ØgíŸ-.öƒæ~úeÏç Ò´Es,´ä‰Ñæ)âÈ9ŠP‰ôçr¥E8ñÏq »0¸‰¤YÂ>(ÒCnÈ ÀÅMH‰@‰¤ó3ÂU‡M38!Ò"‡„nØ:º¦JÅÎêâõ=2d>æ×q©—8<ÂY<º_ȉÙÇÎ\v6?v¤QÒØ>¤Éu,V!Ø‹D 6ˆ8^«Ø_´>‡Y„Ö8@lKÌûyš·í&šÝºòª/òR¤º/µn!õ­T¢*¡½•¼IðD¼™¸g”×He§é‚÷³Õ†GŒ-D%Ù¯Z’Ã8´‰X'¬2½ÒŒS…he|‘,ÏÅíîoœ Ÿd}æ®XoMÎÍâÛ´ð[oñà ùKלƒ¯eJl_L̯„Íâ~!§½{Ú]-‡n?©NŽÀa²›ŽŠjraL @œubyëuâr;€Ç–üþË[‘*MËmv¥j`Ø¢nâ:$KÚ tkåËÔ£‚·|&/ÎÃÛõmØ{ècÿ­hEY@@oJ…iC¼—B6/FÖzfd–ŸŸ29Å+c¬Ӯϒµp£7¶1.GýÂpSU›š:(}­ó¨Å'±±K¥“X4q„¹ØÆH¢XµÇœÄۺœâiÐÞUŸžN´öʫƗÌ3eƒ›Žz¬¢•hõD¨-óÓçß*šQ_2×äÄ—¾ÒH½i/Ôȃ¹oÂÃÍf È¯ºA&Æ©Øû z„ìè ¸M !t°dEóZ—lú ÝÜ,K‚ÎgÍ_>‘©‹ñA ³Ú®R‰s{"jF×[’²Þ³,gk¥pŒÝ|WcŒ[‹'¾]aùI¼€8[üa®1„Xwî€/sÑe>"¡8Å—ÒAÎYfÃðÈúzÖŽB¨Kª>ot}Ï©w Žh-3º81UæØ{ ñ‰Ü@òÇQܘ˜ãÕúƾB’€9”AþÀS™HC/õGQtŸë¶{õèo{¸¨…däç¥H4PÁcía°2Û©¬®½ttÙZÞ~û³ÙJ£L™#Ó¢!ÈÅÈt‡“tq­x ¼õ˜ÅoI¦ðÝ`2ݰp¬Þ] &ëpB®¤bUƒ:ß÷Ðáû÷[ [ÿøúåWÆúBû/¥E$Rm|îc¾Ó$ë3âžÊÅÁ½™ÐR‘“lT‹D›ªL¬DÓA¼¿ö7yCG´ÁõY$Ò²„;äÇÚ¯TáÅq﹑ïb z÷Û/%(Ѻ " yR´àä­=‰Œ‚òȔǗê)ì~¨Þɇ잎tÌʬiJ;p¾o·wÛŽæÜ¸Íb¥¯›l²øqz›ÿcÐB/»7o}™úa™WXb‡A»",žy»VYwCjãÓ`ŠÍÕ.øû~Åä`}'EœH¹x "òJ:¨e¡6[S¥pÅ”H> ˜[Æ"íÇLÐ$‰ö ñbNÌÖØ›¤¨ÜÏSÖJQwßÝáå¹Bib`qÏyÄó!©=†öwJ?lÍ ¹3¹+îkEÈ@¯@ÂGˆ™†œÞ=¨»Ç æXÊPõ69.Ž¥_"qyì×Ä(ëýÑ]&«‘’I’쯃•~iCÎÚî$ªz,:b‘¾\‡^5é,mµ[kµ*ß±wÉùÑdXo1!ûZÃãyôCP{ܵy4ý¥–u†óVâµ&²ZÈžªÑç*l„ʪêQàA3½•ÊW-¼Q@¼dýÖbJC'jV¯ ÊoÅŽ?H°c‘7/oöL‘ï®M÷’‚fŒTò#Ú‹ªøÅkÇ$ö¦ W£0OcCÝ‚§ý«CÈ‹†SWH\” ¿–¸Á÷ó,Î!ðvÍÊT¢g>2AeПq;n™üŒqêôÝ4礪ù{*èwI˜» ½by7;›±ÃÇù/˜¥j“ÛïŠG¾ž)do {½DSa3'âÊ‹|j&…“xú…iÖ½Pg _#ïhë’YV »K\ÒT¡'¸EC#X¹É£…êµæ2_ôòüÍ.¨â‹às2lͲ–ÐúÆi·ʾw^nêçwk{N©› ¾Uiy–¼Þßv ÄWÖ©µP0ßz«T/inB"€‡l5L]Ñ+‚n„SÌFÎûÊ"mé¶ é,°)nEË‹ˆCåT“S{d'õÓÜÇKr”;2àG=ó5Z—г€v4.s·Bb÷‹ßè•WvC„]•Üß­+s !·E öâõ Wàâ ÑÛ!fˆp›"VæðOK n¿³+Qo{Ö¬±z~ƒ‘ÄÚe=Ê·‚ ÉWÅ•·L‡Qûˆêhr¦þG_Cƒâýc~PÿÜIˆ’ÓY¶s/çœÙÿ–•ÂD`—à«4Íû!Dò–¢·+È ÊWÂ'ËÔ¢¯³”<ø‡0“OùÑ2‰^ôI”x½]£šRMÆ!Œ_Ù¡Æ*ÅVuÌ×KÄѢ5°ÈæÎ÷æâ0Ô:ÖÏÔ~ 4Êu_Y?½Š/&KÜæI½W©¶:MS{GÁ›æ' ·E”e4°CÜ«ÊÖG’±wèÙ*—ËPî„´-¬Âm­Í*u±èý\?‚f6Z42Ñhr Z¨±¼Í¨›rxSz04nŸ™HQÅÂä2 EÍœü!l=OÕv®j7¬[[nÂÝoÈöQϲæ(¶ådð¸«ã\ï­œlÖUU7K—_ù®ªm÷ªâFº:Cdú[EÓ˜›g©v‹µ¹«¾ÃìqŽþ9r½ Á·Ö¡GW‚7†b2ƒL(ïÌecƬ—ß¡œÞÞû8øæœšåš.È c<eòîU «¶Õ+öS)ækàšÃóVà·-ÖŽÙL*}K5c*tЕBZAb0[ýV¡NÐÍ3>o‘˹eï{ÂqÁÈÃ¥ ¨wØÐáÂ3’< ¤úPãu؉ºB§Ñ2ÒZ…´öSÖ›é$»ß‘G”HÜý¸õà§ÐÔ3®¼ [“J_¶éXé*mßhÜ{eï¯}x “J›N,3Øny>(jù´ ?žÈhÔæ—¢oW ­W:½Ê ë]¸¾üÚ!géZ|ÏÐÙPâÖƒ;5f³$+,oÂa:™žŸÂRR1ÔïþÂ…[w{ô)&Âb¯—?èMÎàå ^ì‡mÊ ó.¾ü=Ìþ°Vfß¡ÄûÃè³ïšGc²dï]Í¿ØÏ'Úâ @[?”x;wÎ\‡C7ºäô6Õ€UòGUeîóœX5ÚíÐ rTíx÷½ 9Aa}À¸yëP€µ9eÍUùºÞZ‚åÐüHb foÉ(]Ñ3î›ùH®ö¦û 8¥Ê4ˆøp±ÍLª9{ÛõXNŸ¸¡C Ǻo¿²bâî²<öººX(Áú|>Ìq¤À‘(B<ýÛ$÷ák¶È9ÐPUØ@¨wP¤Çö”t{œ€©Ë5^eKI÷ýéÅW|` ¹ýÿæÑcù&n½'D7œ(‰"¬Ô ð°DuõXw!åk›¯. XV’¾”‚8'ªÓº›%yÐIY]‘!Õâ)"P‰_É_~6‘šMÊt~À~G¿)ûÏ,>_M5ý˜ªj‹®kÕ¦PïJ&kÂ1t}ü_ÏÖÙs@-™‡‘ùz¦?1ø¶¶gª‚áCnmÜiñ{…>0‘:ß&e ƒ)´ÛO#¯HB’^exy#8Èt`¢N,¹sêju`SÃæÝð¿ÀÎb¶©sÎ¥T­ÒQõ*P:I¸_ód±ÖùêÒ5MTË$f—á?eÞV®žåLã÷XâÈ„lw×¶.E ©UZTu[º½µSNœèËVj4êàÃ$ ¥ãû¸º!˜Ÿò>/”-Õþ ݾèÚñÚ",L!Hî%{$,(t\]j›Ïq& ’¥Õ?‰Ž;ñ‹~ n´0ëž9úÞ _ËÙ,«y'ðœa½IduJWÃ’IÉ'…r'þÖ]‘¦¨Š y€}noœ_z~ò¶"3EàØÒTƒµ¡ÕÂA莃b¢˜l%Ǧ՘„Š&å·%¶ æGIŠDÈ7…a I¢á??ß…OAù²[b+›!ÀpèAûÉ-´´91b4‹€¨ÞÛ ä}2‹Œ½%—˜IO¶0ÁÆ€>ûZ‘äúh†‚£ÁCyÖÐôå“ýÁøŒ¿?Ö 7) ÁÐ6ÄâAøœÉ9¯„eÊ~ëÛr{`¦·¤v$x³´/óýäó…®K#8‘yç"‡×V]SW,GÖ«¹rsû#£Ü dvçT)× ­êE;⎻Áù›Î8m~A¢˜;¯Àµ^Ûn¼h¥™d€–&q¼{¸äÎ#”á”a•~­ø&ÀoîtÄÝeb')ܘþN‡ýsé€]÷#çéÃL˜Pw®ê!ÁÊhåê¬D¸ ãæE´B×\·8‰¨éí1×7³,,z }'•×z“Ù¾’v‹$Ðß•eÏ< K«Bª¿±w'cƒ Ý8V¨¨\èÅväÞN5$NÎl¢§" 1Œò«"¸z8¡:feá´g þÝŠ1  |hSuvu¶š{„D°³B]ÒiÃÇ01P~5wÿ0ž1ê˜÷g#Bßò­¹:jCCwÆ«®äd.ÊÂáTßÚ÷ÞYÁ籺ìÈhjcØËcMâkKôŽØÀAvymKÒu²ù øâù‰ <”Îr¤‡Á™b;]¡­vß#bEã'ß(º³©P×18$ö®?Ç? ;ôbGæ‡nÃç`вúŒdŽß H&êá¦=}ç"ñ(íÝŒD¼`J0¥ógG1Q´ÚÜu °àDfø$ ðÀú `'ÊiÂ2 G8o¹vyôEög\¼vÌ “ ÅÖŒ®ß<þ¢oöJO'‚ä ½N!þÆûþóá°Í0Ê×”ü°côµ$1;TI][žÄÖ#¿ÎnÔ%šB¬.ä΀.EÉ!‘TÝ5î²á9OÒßZSáQü!cÕCø]‹¿$3–­Â·Pž’b”ûND6@z€%Ún' |®öy"Yo¦G‰;tq¸+ÏC,Óx·tvmà“Ê}_¼`ê~8+ª£p®ï4–…³öÓ§ÉàäûJOÊ¿Ga 2­YRSà wZ¿Ð_VŸôJrŒUûÚ[NòWÿkœ*MÜß„:Ÿ%üQ¶=÷'P_2]˜iˆa¦Z¼—.T}[æ_æ GÇ"¨‘¹ƒmK*žyÖÂ&^)jŸ`G£sSB!ø¶iã#æ#nÅv÷Y!ïØjˆ {OÎHÜ ¿Ç< ÓbtɉrM;Vø}è¾9§s­=ÍÈí‡2BÇÒH*wyù§{O… âïP£>~™žµC\Tzp±÷Âú<ò¨OÅHñöå4Äß‹¯~wäî@ªo¼…?QDù#äùŽßà1‰öc¶"ýê*Ìa›¦Ø„úç/ZÇ®±Á¾‹H£†°¢üÌ Ð»Ã¹o‹‹ÑµãF™4¥ä| ¯[m¨\ÆoL9½¶¡ŸçäP¥l-9cµ_æÇÂkÜóÊXT¢½ã W—rÊ5ޙ嵇y£|îRû¿èÁñ´î’¶œ[1±c¿i °"/õVÁð½%qбÕýÉj>4Åå¶âôˆ½ãïþ²ieq„Û=l:W–¡Š3þã¡=ËàέŽhÈ/0:êkp`FÍêäK[¡t&pCT6ö—vil€qóë|ß,“g{¶LÔhÌbÙ×ò:PEÞpèVÒx•„~¢¾/ê{Nعïì9˜3"ŸiüköàOÅàðÏ} `ö—¢l`‰ôÉXÃAmÍÏ´9ö9|â¡L†àOC¸î6D’~ùäCü=/5/–Ϥ aHCgÉô‰¤N˯=î×FÑ[4x×½nMOeØkv *Ìp¼WÊv,#±× ÁÙTŒÒ›À¢pgTÌ¡Å%s³^)Yà€ÊLùsÊg•1 µÏ<.*7Ér’‰ç7¾O.Õuú )é#=ìÑ\Üw/unF¦Ý}®õsä6dÒFæ„,¯—Îa›DÏ•û/¯ÀÚßæ8³V &ÑpæŒ>ð“±O™›Ï¹#Õ?w]/Éþ ‹ßóÎã'IÉ5ˆ‚X<¥™<Ï:jƒ’ø!íDÖ-.mhš™’–ÞRŽÃ—+ÎF~‰¢áµ=€])nSf‚ ÉݪN°žÏ¦º~J@@§L J ìÈ4ÑPûÁ޳,z<¥à¥êèaÍý/‘kfEb>h?WÐ׆«çÅ-L †q®¶ endstream endobj 991 0 obj << /Length1 1515 /Length2 6594 /Length3 0 /Length 7605 /Filter /FlateDecode >> stream xÚvT”]×6ÝÝ(1€”äÐÝ)Ý- ÃCÌÀ0äÐÝ%¡ÒŠ”4Ò% HKJH (R?úø¼ïû¼ß¿Ö÷­{­¹ï³¯kï}®³÷>kØYôøàö58 Éä”(먚‚‚Âü‚‚BììÆP¤äo;»)á…äþƒ¡Œ€€·6ò–¨‡x»€Â ˜P\JP $((ù7ލ€| ~À8 âEÀ® ÷ðG@œ‘·yþþp¹@IIqÞßîEw Á: ¤3Äý6#ä0‚ƒ¡¤ÿ?BpÉ8#‘R¾¾¾ü w/~8ÂIŽ›à E: !^„ÄðK2@äù#Ÿ€`ì õú 0‚;"}AàÖàC`^·.Þ0p›`¤© Ðó€Àþ"kÿEàü9ø¯p¼‚Â~;ƒÀ`¸»æ…9¡n€žš6?ÒÉ Á~An^ð[겿%üÞ: ¦hÝ*ü£Ï Œ€z ½ø½ n¿4 ü s{̪0e¸»;†ô"øµ?(¾=w?Åu…Á}a¨¿WŽP˜ƒã/Þ&0¨§7DSåçÖDðo› ”@<?°³À¯Æþß ð—ùVCÊîp¼• ‚:Bn_(/€DxC‚Pÿ üsE `$Àâ…ü;ú­âø×ú¶þ¨ÀJð¶ý€Á_Ï¿¾ln;Ìsóÿ7ýw‰tŒ4””MyþHþ¨¤÷ ø„D|B’b‚ ˆ¨@\\ôÏ@ÿ:‚¿åÿ¶êƒ ¶÷!5aŽp€ä_*nïo%>ZƒëÏÜpþ™A~ÛÐ׿ûßZPT|ûü?OÁo—ÿ_óÿŠò¿öÿïHÍÛÍí7Îõáà w¨›ÿÆmC{#o‡C~;"°ÿ¦šAþšhˆÔÛý¿QM$èvHaNnÿ:H¨—Ôâ E‚ÿꣿëpÞ ƒèý ¿îPPð¿°Û±»ÞÞ+^·Õú An§êŸ)Ua`¸Ã¯ñ€?ÁmñoW¢ðvN ~¿Û Àƒ#o]·ò‚ŽpÁ¯š%··Ì ∴‡:9ý‚ÿB$ÿ ¿køHâ„€;xƒ‘P/7ÿ¿¡Ûx^ÞîÑÿ þˆ„ø!#ÿÐöFܦDþî¹[±¯ß-ˆL0?KGºÔE¶ÿ¨Q¼ëË·9&û}Óì17jÑáý“7“ûUnø âL1s¨—lq]•ëTaù µ×Ò€ÓúÈ í"ðÒ6Ípb³`nœfà}Éžb}?#>Ÿ±ÂVà•g i˜+f z×öBOo ýg”?|ߨûÕ÷—|=³i°õJL‹ð²|’/É$Ñ:ìÅ{‘}Þ4+’ï>Å‘éÔéÙŠ‚÷7ÌÒx‚ö“„KQ–«BÉçÓK•ÆB^Ýô÷è-é1O)ÞMp ”¶³Ð΢ÊJ—‹§X’=nÔå­ÎŒÃ®Þ¹œ¢4zDúà×Q+þj¥!¥Ì}%¸`Æ(ñ;S8Þ‘ºtXñWß‚½»§•Ê:Z¸ ˜ÑÖÆ(6ŸJb÷!@;Žª¨x«zðJO¸°UiÔSñDáþ<)oÝ"¥ ürÂ’±kŸ‹^.ŠO±âÐ4IÔô°]-¹•1ž»†= ¨xr_¼ÔÜÛÇ÷éâÄóÑ?œ8f*M.©xTªÌKûWW¦ê™7§õóü¤‹Ùmyä %«è¸7ÉäE긙ի¡›ÁŽ?ˆDîIÌ£|2ÔtNžýùñ©™5'¸ò3vú®ïSŸÊOƒS1×ÔÀƽë7{šhhDîÌ]ïà»b%SMïô‹©Uò“b—é¬FÌànë¹¾HSOú†¯É˜]é™/’á—Ñx„Z<Dâ|¤ñ-œ]Sx„ Î~É©I=qñ³‹â™sXm?÷²·f1¹bæ®|Ÿ÷–µ™ÂÆ~IÇ­­ÿªZˆ&öµý Û}:›l˜)ïÔÏï” .VSÔuSõ¦Q:é.ö¥£z!sÁÈSK¥Í§\?¶¡k¥Ž¹|íaVúøê%Ü=¡?d±l ¾$­Ntnq3»(Ê‘X«áÌœŒh|׈zYã/ûÙ=6QÃÝy~Z?—Q á2ÜÓ‡krrw¶:H%¿ëNäúð-|õ)^å¾46.V¹Ïئ©TÐäÉPó©ì£½ß¬Ü÷3Fo’ ŽÔjŽ©±=Y7›i¦ý'p©ææ†˜ÝÕG UÐ/¬Rf½¿:#Ž´Ê ÝT5•~{l¸“$AÂ: ÆÕÿ²^뮼2˨œ´“3wç4‘:¨å ¾$Ìà%óR·L¸íÖQt%³ÌzlRÎÝ@žhî iý‘*!Ž—µLYžîà˶uM约í¾Mµ3ˆæ_¬Q=cþ׆Ј.6=z€c鳯¯Û‡Ó¬äÓB·o‚²C>ˆë~äîçCžr—<¬PÕäz¸˜®cEº˜ìx½gìXfÕ¹×uw$`iU¸Hˆ Sžªî²øþ¤Ü_2ˆ]Ú_ÉT…qî¸yE{î3«2>t2VršèØ©GUbVIEÖ)¬µäô¹ê}´=÷"w÷ì\·%*u6óEåsæïžeÀ9#þ‘™g<)í‚oãBdÖ¾¿°izç“_=ãŽkùý°´pˆ(çó…l‡™©³)‡á5ªŠE(äãbû6çž.BŒq¨6Å>©ÐµÄ6‚náåÄ:ÞNÍ5Mm÷Ë;£k{œÝ ±ôÀê5áFÉ‘ŽÖRj¨íÙ…íüuÐ’q—"¦=úpü¨ e™j£¤ˆØaf³GèÁYVõ†Ü@Üð^ܘV¥xâÖãÙ”T¼‰9Úc2é·5ÛûUüdOϤGMû/=ÆPC£¿d•"¨žZ-^÷}É#µ"†ÍxEAò×løT6ù³¾>Î#9l³”ûïå¯çiÚ¨Ì=¨(ç|–™6öåLE=ÆçÁ½ÉPô»åÓ‘]¸b27ŸÔ㱪ìt9Mç©ViàSX<ߪÃÖä-ò:Â1î˜çòT¿ß­©:›ŒêŒëì‘r¤­0'×éYÜ') ç¢xŒÄ öK|³}.ã)·Ó§møP±æòŒc²l9­'c2º‘ÑI³»nµ³…'>õÙgÅÍþQçe/–bºØL´.*$ê-{k¦MÊEô–œæ^{ýVñÀ¦SKn‘²t{®ï1Üq|Љ6ÞÎ[ .\èŸÅhr´ôlöÈT€MÓ#½Ïùh5αBa-ç‰ÏÜ§ÊøkË«W.„ºJu6¥TGüþ¯¡§fÂ}ø¢¨ØÄ·÷XÑ(¥ïîÌZ\ÚT$Û²@Ǩ˺ZËÈià7´ÊHS#^ŸWb‹ýŸøAî÷×Ù©æå&&?p‡(w}Κre-Nf¦Z‡×)Ü74™åMž‹Ý¹Ë&Ò+‚g—è§2pô.¥:ƒüȄ҉c“ŠÉŽ®~jãûy9ÿ4GY±dµþÜžw‰Ñ4¿%ž.}TL2Û2¾Æf¸¤­=6"ð•Óð{y*š¤Ï±Úö3ß¹1„÷À8#sÓŒÀß:¦žO­(f?y‚ÈË„pI€M+Ûø úìÄÛóoè~ÁÑ(´/,ø#ÅC2–h§ðd~¤ý ’cë#ƒ¦ÕàüáÞg5ì“•†±ÖDJP­ûºìGÁ{Œ$(ÛIûù|G„ Ã#üÞ]£aê£Á7?ëâqŠò»$„lÌɯ[Nãnf{¡4í­f‚ôØWÒ¡5ùõòIº´Í¨ÕÁƒ-L绚ًlnІ/ÛþõhçñîÝ (Wdô9ñPstP_áÁ{*¡™«ú¬tÈàǧᡣq)šQÄ/Wg©7mpèjzx1Õ¾}—ªÑ(šKŸq³ VËÒ0 9¤†2¼M»ßM/•©Ne±~rÙúU½=à-ef‰f´ÚxÓ„oÎZFi¼0LÝøSÊ¡ëu- ¤E'?|öàÕð+m,cÂçô™]Öä¡©ôþh;‹ßvM=gàf–àOÁ¢A,ÛOŒiZ[êuññTÓË“§ M=ž¤î¹;áÛÀ_)ÌŒIº»A«Ó0•X%™:MSk ¸žÌDÄ+ðŒ5£ÖlqÜ;¨¤€ÂÑ^"oX‚Þ4QžÚXÇZÚĶgS;;¤ŸÐÅ>åÄøì çðýäý’À]í.øO2ˆÂ¤  <\þŽ«”‡Î–*hDhGa-Y­‚G¬[mDÞÅy¼i^ú eŽÜN‡ 1áêzZ§™¡[Ý-øFÏeœN¦ó2N;¦î7]«öZçTßAÑkX}^šdHKm~±286ü°)9ÇàŠæÐ}îÛ9lóêK9CÿIœ¨ßqUËæðX×a¡q¤[¾R<¼¸F)0ûr7ëËÔP¸o»¢·÷[9”q¿ŠxëÍÞБÃÚ>êÑyÞ$ýº’úk„Žet!t!Œ‹²è;5/-±‡¥DsWß³–*_°›­êý¹Ëî×c¡êlwÏg§>Ôöô6QìV=•µ±§¸Ÿ›<ƒˆ0¸°˜,~ˆDôŸ–Ÿ9¡¯:èH2u€Ý¹ß¦_hèdHÆÈ]·_ެØQjõÃ"…) õ\°DÑàE[<ªäö%y@“G20ì ƒ46~ø 1+ŸÚ¿CÑ€Ÿi’‰Lå±óN5œt{ã95¥kÈ æ£êU°ˆ“ÌÌNíÆG¥ÝÖsË=ë. %j¦Š(QçðºõÎØ‰ïã\î0†IvÉBrÚo9‘Fb!SôæIòAщ<ëùÚCeÞ?ôWžo“0ö¸œQ&uw.Ç!uôî¼jã§Y5ÄïÈ÷ºåš…Ÿe l¹è5¸Ùs©YHŒª“ÿ\©=©áï'†‘à¡ÕÙ”ÉÔÖ¥SÙ+ Þ •(2£óÅ9Ê%»ϴ‹ŠÄ²–>weôõSêiTC×Jb°OÆØÈ¤\7 Ä K»ÅI,6ºÇú0"vä±hu̘NjNÌŸû=ÌÓWÜ›¾Y ®Üú‘¯•ÇŒíL7ºI³³ŒXU7´c2ÎtÞ×èY˛圀hÛ•/†¹æñ4W,Ó¯-“‘»®µˆ/ÂWÛ4tõq<)âRÉ8ãˆL†ì¬£ÎY?cèâã.=ø²0Ç¿sü óduœYnuæOéS›Æ¯™gÔΓ:(IFí2fÒ íÀÛøÈÑ;£}¤ôM°»AQ­#SŸ—ú±Î˜ý8÷®¡…ÐÚ¹j!‡8Y¬×côm&¤™ÇXEƒ½¹Ë¯-hÑ ÷eîË7nl±œ¦¤òïûØè;'ÓêÎŒWL)ßy†ö}ÙBXP:ÖÕè$7~H ¡Øí!8±5šÛhëÜCxs*®xxC(yFîØYàÊyFÌ¾š«·‹9|‰ýÞiI–NÜuLSA!ÎݤŒ¹Á Ï8=þ™kÜòãÙÐÁÛ˜¨^—‡ |[œV°˜?µže±”ÞÆõ”¼IrFyÈ‹ÔNái5h­œ ëEPª€-qßê¸J'¼Ž…AoÀ3a¸V{ìLá1ÑË9~¿ñ¯Á¤CYÙ±RÏ­Z­ç+éùÞ’;X£ž9c*2R+€ÆW äkÚöüÂíÇ7!‘àklö?›ŠÙ8i¬êªž7˜DG´› ƒ¦Ç†þÑÄ-¤¦“úÜÒ’;φÃfÈHXF—&‰Ï1¦ŸŠp÷;ë5§ëàê8¼%kÙJ¹ž!ÚŠœ6˜_Ä5{jèY±+ö*O!ˆ'kMénɘJº¤ñ…ˆ‰¼‰¥‹ÏÁÉç„~ù]°ó|~ËÏHf0•ÖçÄ(½D²Ž?Á%§‹Až¤¢ØÙYÖM?³¸Zý§YhR®ž?ü4¿‡É¥ý¢‰(*<ïâpâ?É0½#¹ÓœQ¿•}W|†ÒòTÙâ }3©>´å^Ïj¹/Ksú• U”ò½û ÎVêa½ìè"IÛzÑ'l<%þ²ÄXÇå ùȥ؆̵ٻ,ò©Ÿ¥©Ä9TTñZ-ã\VVWǨ=3Þ-, ‹u1‡×vuH•ÐÃ%c2­Q‡‘UG7íÎì>’§œHÜ%&%ªÒ†RƒþLŽˆŸj7ýS¥§x%Ì6÷²›ÎöÔZÞ«„=~ÔÍgP¢jÖ>®¢Z0!ê•ÏÆoŒ£$3Œ\Н¬•º¸·Ä¸¿Se–’Ÿs†º\mbß•km£Zæã…Ø'¯í ¯+IÖ«.™º†ª%ÅÅûeŽrIÄ×Ω"ú~JøââóçÝ9²eÍ­a×Â{ê“ìQünÃøàó­H‘Ò¥?¾/M9ãñÛ˜Œ°„Q‚7Uw¦Ô™!Ûq›¬&¬0¶¯Tø+ , jæhû¯ªµ‚ÇU=9“¸&ò¯¬kö%:öb¾kF”¸gŸòS ÚùÑ噣 $äi)…å²^û|i¦C×Q£U.= ñjà¹b.‘×>‡ç¥5ܳ¬5ÙÔÛÀ­v KG»;ývJÇIÕ'›¨Êv¿ÀÌÔ”¨£PsUß@b.ôdý Snj5J4-BgïŽßK^â½Ù|:Ü9Á¯oWg&8:Á)ô-ZpkfmÌçÂ×ß’àöd<<ä€ñ|‰±Ÿ¥Ú";; g†uä*BmÅÕpôIÓôØ&oÕS;×5ö„ÇšÞö K˜õµáBŒ7ý26ñ¨rQ¾¹fßâ¹QòÏ‹"3s7½’j›T™K*Aw­cvf¬mœG`Ææ®¬¥^Πמò+»= |‚VQâà§¹L1âÎxo1ºf*lL?¦§"÷s…ž‘«p™Yõ P!Õ Ì\Äû…Z?°^Í$m÷— [²$0Ê$k¿HX1›‘¨½®÷}&¸¼îªßfT̪ÉX ß]Ô&‡µ©‚¤×kˆdsF±Hž`½$XœñÚÕ§bĽ!-Yb½ßÔ[N¹•sg £°%AÖ'dŒï+玊™“½¬ýÛ =†-|ßáé­ƒçæ ƃI>q¤Xhœ 20U°\Ç_x«½ß/_ïEÿFZbÅ<ÚÏM¨™ô^)…C‘Ã>¥äÕÍ¿ƒ½¸lÓ׋ÒÈ[ö &kŸ>|Qõ¾g‘æÜ#µ³éýì½À£7½…¡¶|@åcåžý>5ÕŸÁ ±ÆPHZâa³Ø)ÅØî>Ívƒx²bóúE’¸ûÉÙ| ‰Jüò“°ç“ÁÐ`¯Š“ÃÆœ8 ͺ]p³”ë½£¼˜6ÿÔvdŒu8 H›bÇ—ÎW”œÞÒ°ÖVöù¬¹ì}Áï×¹·¡»G¢ +PžqäÔæü¬Íí™À‰¶‰ÙñyùLž¿xGÔ m–®ÑUî¯*°Ç¦0¼T@§ˆ¾Ð¢Á€(Þ®~£kyÓP‹Ô}w!D3ßðÊ÷€é])HÖôÅž´‡HØ1ß¼ ±ç¿}}^´a77Þ6Øo*Ïod°|ÔÄC‰V¶•Q£~*ã½û`úS•)âGÊĤó÷…µ䊗¾ðw¸Ý‹+R±âeát¾ÍòâõÌ‚sÃ1Ëâ"íÚ×:_²Wé÷å¨7Іj™Or x½N£ó}{ÿøGvQzïȆôÝÝ /®ª$6}¥ùN€3\Éÿ ¥­¿Î{íŒd™_êòø$+öcDñ d}Ó‹Éë•jÉÀ¦0è]æý'×ú»9>÷K]mðDÏÐT.Ķ’ä+ý¶„WQÙ›Ç_©~+k„šÞtÞ¸ |({Õò"C¿8‚I×Ïêéá—ñ—°“rýÙ #›î¸OiŽ¢Är—X‘CÀ£×yÚÇHõC{QýË<_^þ¼Ž6§6œŠ¨Äëq5©ùîCÌ#‘+)oJ%Óï ½ÍL¡Ò€§0–B;6'c_P¤ú¢øuÆ’,±ýNÀ®×ÔxIGI–…BERS¦`rã rÃ40Y¶À2ç«àóåL‘¯†8¶²¯&7ßá3fÎeÍ3>8OÈS¨P$£Ü!Ö[?å°•}žgóÎRÚN=1pVÉkkÔq/̪~Ï{Ødóm¨[¶é‹ B) 5cüìª#0CØ‘GÀK§ÃÙŸEYª0þ£sÒZ íÞãù明û¹©8 Ø&ŠŠ™Î?‰£Œ¡ªO%±Êý•ø½¶œrw'ä‚ʤ¡Y³ü™ãœ¼¬ƒ—9»ó@Õš~,·™ti¡$§Ã¼w)ý¥ÊT_‚m V}›ŒókÓݯNEqs,ÔF_܆ŠÓmã&1”6£Ë­AK¥¤M79çU?0uÍÉÚ…Þ²1¨ñ«ó¶Ç•T ŵ±ÈN¥ú7Ñ(î1K“LS p³×~yä|×¼¥t¥/(5ïãÐÂÓž™]…-Ë©¯>v®¨„åkÍëä€!¯ÔIÒþ¢¦¾Àù±™ü¹õÏ =¤ôâxݼÅ¥ýÕÝ”®á{oLÚé„ÇÑ—‡ÉD·/蜇ž¿Äy׫ÕSÿŽôa,h„í‘öî‰ mVE¨­VH®Ù :‚8À(GŠ}‘ˆb¹N™òXD¸;;#¿³O‘_„hP=ð›¸Cz<-Ô9=!)BôxŸ_™E&¯õ§éa&Áƒ%LñüÅ}áöxêh-ô„¥ç’¾¸”6érà>þŽÎ¿¿QN>zÈ?rçwe—Æ,FÎuÓk.4“›¬E¯š×q^)¯;7LC³y]‘è$ëPwrîÙzk²•QO!±p £=…DˆþËÖÉÏ“Vm÷ê–ÞÚ(åÝ5ê;õ-ée§áPÈO]ÛÇIUH<Âie¢í}*ò­¹–Æ>wýF½_¸Ž2ÄÒ´êíCyg$g)Ö7|½ˆò´vR±f5ãíÚ´ŸŠL’1…ÀÀ‹åæø§‚}¦ÁªÍûw×)˜á¢ÝÏ…‚ÇO}äì¯Ý"ºaÊMcõW',„n°ctá¤N}v¨™‘œãÂÒW ÍyP·IeäÝ?QxAÅ>8ÿ¾ö’/]£ïû ·R²ì÷½i§êzÂs,X'ݾûNØdÒN{m‰„Å«¤ì0‚?Ì«\]¯.}Ý Û BöP¥“é¤àO4ƒ¶F,Ê&7ýȸ=‘ËDêÈ+Ú…âÇsK Þ’õs¹uZçf¨'Ôâ‡ýÛa¨IOì-R†:Ì¡œ‚©/°»ÕšÅe»¾*ø$‰—S­[¤~®f§èYöšÓþ¸n¼"g'CP§2ÛÙùös_YoØ8³f‚ñÂÅÿ •½è endstream endobj 993 0 obj << /Length1 2079 /Length2 16234 /Length3 0 /Length 17513 /Filter /FlateDecode >> stream xÚŒùeTœkÒ #ÁÝwwwwwÒ@ãîîÜ=8'@pwww‡à‡½÷Ìdæý¾µÎY½V÷s•]UuWÝϦ$UQg5w0J9Ø»2²2±ðÄeYÙ,,ìL,,lð”” W[à¿åð”Z@gƒ=ßYˆ;M\ße&®ï†Šö97[+;€•‹•›…ÀÆÂÂûoCg>€„‰;È Ès°ºÀSŠ;8z9ƒ,­\ßyþý 1£°òòr3üíµ:ƒÌLìŠ&®V@»wF3[€ºƒèêõ?!h¬\]ù˜™=<<˜Lì\˜œ-…h W+€Ðèì4üU2@ÉÄø¯Ò˜à)V —ê®&Î@À»Àd´wywq³7:ÞÙê² eG ý?Æ ÿ0þÕ+ëÂýËû¯@ û¿MÌÌìMì½@ö– - ,¥ÀäêéÊ0±7ÿËÐÄÖÅáÝßÄÝdkbúnðwê&)QU€É{…ÿªÏÅÌäèêÂä²ý«Fæ¿Â¼·YÒÞ\ÜÁÎhïêÿW~ g Ù{ß½˜ÿu¸6öö>ÿF {s‹¿Ê0wsdÖ´9¹e%þeó.‚ÿ#³º8Yx¸Ùy¸@'ÐÓÌŠù/ /GàßJÖ¿Äï5øù8:8,ÞËú,€ï?ð>.&î@€«³ÐÏç¿ÿ‹àYYæ 3W€)Ðdÿ'ú»hñ~?g'@Ÿå}üX,}þódø>aæö¶^Ìÿ>bfuy )1ú•ü¥˜˜ƒ'À‡‘ÀÈÆÉ`eaãp¿?øýoœÿtàßÕÿ-U1ý+;–?eí-ÞãüSÅ{ûþ]‰û¿Fƒæ_{C ø_ %‡÷hþÌ¿ '‹Ùûëÿç-øÛåÿßðÿåÿuþÿoFRn¶¶ëiþ1øÿÑ›Øl½þeñ>Ðn®ïË¡èð¾"öÿ×TøÏF+ÍAnvÿW+ëjò¾$¢ö–ïƒÎÈÊÁÄÂñä"òš«€\ͬþ¦ŸÆ;‡-Ȩâàúëây÷baù?º÷Ý3³y¿\\ÞÏ앉Ëû"ºþ}¼aàûªýo’öfæí$'ÀÄÙÙÄ þ}$Þ'À‡õ}yÍžÏ<€™ÉÞÁõÝð^³ÀÂÁþ¯ƒæâ0‹þ%úq˜Åþ n³øÄ`–øƒxÌ’ÿAÜ,f©?ˆÀ,ý±˜eþ v³ìôÎ.ÿ½³+üAïìŠÐ;»ÒÏ;ŸÊôΧú½ó©ýAï|ê€Yãzg×üƒÞÙµþ wví?è]çz¯]÷?ˆ÷=½?è]göÄùz¿ÕLþ#y_V³ÅŸ6¾#Ë¿^0ïSøÇä=/ÐÁ÷Ĭÿ ¾gfóÈöÎncâèøß ïÉÚþ1xoŽ­‰©ù ®wÛ¿†ìË{žv\Þ“²sû£}¿˜íÿ ¾«ÿ”øÎæø¾ÞæÿeñÞæÿª‡õ½ž?dlïù»€,ÿ«'\ï)ºØš¸Xý±yêjòO ÿ3îfnÎÎïûð÷=õ¾ ÿÆ¿€@O ü✃¨u]hÛïQÆÝ1¨óŒß:lŒcÅF°®½’SÆ›Iê¹9KòR‹¿X¥Œ¬;•Äœ~ç­Í_ûì|'©÷â¸c$‘:°$1M˜{»ŸIö¹'$›Ci+ÐN#æ+sîS!ú„úNØÜ²WÅ—º®g!Ùƒ ³\Š[.¬M©ãgMyŽ6!¯ÖÉ–šk³é€Æ.ç .õç-»øíƒ¨t¥,2yŽø$o¨ýC+h¿ˆº>ɹï^P„»¢IòJpÀ|ÓZ)D~þ\æ~œ…îc*!Ž­®X@ª† ? ^˜Ò|ŽkðL£ce• Œ‹Ò^˜µ_bå˜þÀÎÙ“þy†,Â2ÚÇ\`UJ-°£y>bh ç~jchÇáçD+M¹¯UUùU€ÿ°¨ú'ëŒj3=F&í|àFÁ/t:3„ûfiÖtϼÞ⫌Ž0>MÐÔb2?ÅÏ5=;ðmíßÏULμg ¾W$˜ ÛÚô§Ã[jîŠ8EóUr·ºð¦À¤¤¦àlÅû25 'Ç[Áåå ÀNºàEþÞ;ºâvrwEEóÚ_ßÙ×nØ™š@²ØØÁB«óžpM÷ï˜èÓ?þÉÓ‚®q+Éañm/£9¯xt o÷óÕ²ü'}AŠI8…–Rª£§YËÌÙÝÐP*n.,*¡«×†G š,8¿$"]óƒ†íçT1—ÂdKm“Âö‹¼5RZë¡Í¤X:>{¤F–¾_ÝoÖX}‚Û<ٓоýJ6–p$iùÀW%_ ŠËõƒÈêÿœÉl*ó1ÖÂÌ„,¯c8•ÃÌÈ–W²Áp/‰¢y<»û ¢]ý$½T^’ùç:æá9ºl:·¹ÆÚBš@‘áë­/Wõ®äkßb‘¬ˆ2dˆV¶´]”k9Ê_x7 øu—g*“Pƒnac×·‰ÐäœÈ*ˆIêœ ii4¦D`¦ÉM90ËãËîGjè/’Ê/XŒoéêØ¨,:¿ ƒo/rE¾àY\Iì¢QëäYYªì[ßwÈSÙrš‹^ o•aÁý]‰Tƒt݆ÌÞS™×.Ë£>Áðiy/_Ï¥-GRc_ñ±µWN,>óÈ=êàBeI‚ 5¤W¨$}â\su‘ç„þûOoãXÊ!f«¡]Âî§kµaL²O¨©@_Ö5e.M-˜YµŒ™)¶«£" ¢ooKÖE´Ÿ>Ìb> T[—2àçñììvö=™шøÕÙe@ÊÆ¦;8&Ja¯ÆÀéLã>˜YºJã~îzºÞí]³´Ìå…}`›d‹BÕþ‘bj§8ÆÉ“Cù)Ô+3pmR¸Æ{–X¤”­[@G<éh%ä @¨šV쬤Ý!m’¶…„·'{M1QL󩻟,7½¼†öÿµ|)2³ÆàCŒ†Þ—ë¤íƒm‚ÏOÏ©mTKæB"•‚x J|=§äüëϘ‘0 +æ‹ñ™ ¿·º?#óBËÛÂyHoãhÌÀ¶”g]HžIC á¥_‘λ‚cÙ8»¾†_õ€p^2#á®øæû¥6cxF2؇ÅQ%¾Chï«L…`7®u0”]'¸$úb÷8tKŒtYt›]ºÂ۶дTbsÙª{þ•ú»³Kì/‹Õ••:_^$@­•9%—èr³qÔOJÚ¯zÒS8ÙÑ5âÉ¿Ž­Æðáü+]ð³íŽ–ƒèŸfi¶’€.ébz“Îߓ؃kIRà¦ò0„`S-Çq-m˜m`•:8eTôwXFµ3\ «`wÕ&=Þè¹L›Î» {k.FóFõ«) ­&ÊÚÇåIkJ;ÍË?ug¨¯k}vz ¯cHÆÀ‘8…•MY=KÜ!_¨]r:‚…óñ¯ FuLè+R‡»á¸æ=)¾ªÆ>s‹‘<ÎÅ´·7\¼ªøxÕ0I75`Kã`j$ŒTh_{z’ûN£÷Zw,ÝXዚ²ã9Ìš4‹k²¯­ûèúo–sÕrºO”ôEø Øö%qñÖÈ|¹B¡:Î {­®tœÙU„ÄÞÊ)Åž$¸,sWtlZ³­JèZ4@Ê‘Ö ³+‰ù¿r•€üu[è8`ÆcuáÉk´ Ùg˜{÷þ†èm2…¡Ê; RG•”ÍW¥Ð¿×?@Ù‹(¥–VÞ4–«÷Xõw˜™,ïÊTums[¿\ö‡Ÿì5º£³Êì|׸J¶Ê¶´Ïk8)k!¢\ µQ1L…Ù ²r]Í|œ•;¸^ÊùösÉë¡UhQÃ…ëc…A/nIüÜP_íMƒÜ r˜DÈ%ŠÓŒˆÖ/ÓÜ­hYZ†ÍÙí<ŸG8]6!’ª ˆLûz’áÚ§Ä[3]cÁDYjºÕ5ˤ“»Õt½fƒæÐ¶×ÃAB©>ÒÞ¡í4è8xË‹\r<å“ßoðÚ‚ñí…mS˜–ÞÕÃ_û‚«èw©ò-á_´3o3#i‹âõ×rÆ—‡öä}ããP’2ê‘Ô]À˜q™qãíÄÍjÆ–žÎÄã ³54¨;õÅ3Ø´Ç÷Í~í6Ú9¾•À0}–/æü¼F1•‘gVÎ’}€'tk•Ñ‘ïÒ‰DÖ\àÓNú¼ÿúk–Md!1¤œ ÕHÄ¥Q,|WZ¡£*¢Öeëf .ÿq‚U°eÆg  kiIövÌ=.RÜvžlÎïk·üìQ ;œ&S6 =‚bM33\YïiŽiÈíäÅÓuÏÝ؆Ô] Û E¤ŒrñÕ5[RÈœoce-)±ÆB-?U@Ž€ Mª¢º®áòñq5f‘Âý…ƒ“ FÞ¯õŒþ6%t׳<¿~hIt5w« záf±4ÅúƒÒ‹#r°¹ZOóˆ<ËÞY)´èÙÍŽ ¶É’7Èõ<]ÅL[³y¾m,ÜJllت¿;¸[æ·ÏÓ0N”bt Áãé¼FOØóƒ÷`ôå7Ât-jê4Ujø+¦Ø£,ûÖ)—ÒþA~{B‡Úê‹:qÕ°XôÄŸ5-«›ƒ%²Q z;¸Ý»®® A{>‰ƒJ2SCù<»oÃSKQç“‹»µžEöã gŽ Á¬“.ö)=V¬¤IîùÅk‡œÅL‰_èv“‹. úO¡<§YsV º‘½‹I$ïyý˜ÏÏ#C‘>9©ÂRj>¸ý:ú%&­6D‚Ý99_‚[£qRåøj=y~Û;®;ïs¢·và GÄG½]zÿu±ÒÚ‘Àùwl!¡&9*¯nOÿa:¥ ß ?vJàÈ+æâhàWrª\IòÒ<ÖTÝk—Äz…ŸB„ÕtQ³ß¸r‡Èkâ.ï.™…Š¥ç‘ ïÑ8k#[ø?Nmx¡ ßòð%Uv_—RŒŒ2¢‰Ì^Ç%Q8œ?ÖnddT¬\kžô_N‚6ªŸhœûbÏ>+>Ç.î7•QlßĈ«­¿,VT¹ÀºÊReÉÑŸ¼É43½æôO¡cþÞn1¶ü‘àøçšAAd‚Ô)eÀÆ,¼ìüíË“>VZaørIŸÃ…5h‹k[b¯Ol7réWv­SK,gK|–,¶?E]Ü> UWYT× %bÄ.«É®ˆDê6Ö{jÑ…„— u8% F Yå»”æ !VÝxõø9«Í6¢'ÿè“m–³V^Xæý|¯¦ÔP„nõ3Ü— i áB!¢¸âFÁC™×ãgSXöoGí©Ï¡¿c„džò8£"ÙøÁ|dTª¸±zýTBµ½˜–`µ”(ÇR¢4¦œSÛ; Ni öë5VªÐíÞz!q×èU çjPIlñè±m5—– EÁ¡bvVó$빕mõ+Ggu$ªn˜jÚ>µÆn\S¹‘SÖ{”Çéñ€ž*î=8W°ÇGâô*µ4©{HGAó²bùfÝVb/_#Kzb¨ýØsû¹,ˆœt¸!ž,y'Ð6ÀŠ»z/ùñœÓ茴|U\sª®Êª›,‰`ÁÕÙÃt—[!{sÍzœ“.hÔch±¦È[”x4µMoL²à¦×³×Ÿz‡Xâê IÁl§¼9HÛqݯÕ¨S´e~:èñ"/ë{)žšPÜ©‹ë1q»ÙÏiºÚ& ¯™/b%Å¡ý°¢‡»< ì¢údi–Ö)Vx‹–¿–Ò‹·'n= M"xì‘ÐNJVø¸+mƒBª“.` hAÌ›ÆhæÎð¼ëýÛŒ»\'vL’úë¾A‰Éƒꡞ-V œ­Ï£m°m8¯9S›*ñß°°¬‡V‹k¦ #_ \šèBv˜‹4zY'ʽ4aE:G)•Þ ÎɨBU¥>C^–C•™»È6f [šVãò´ |@ºpeÆ¿ãâÔÔ‹*°Ód\¥œ´}™ÁÆÏ‹ ËëRü®KÐW4ÕŸ J9Û'Ûºw{•«þø8E?€†gÛ†*£E‚áúdšr Á~üìát¸Bñ%ž²²ó56ò5‰ÐòˆÇlÉzˆ5§¶?ÝøjVœÇ ­F ]–þ­¡Û·†-W@Ê)zÈÎ×Åjv¶ ݬmXhôõâP6°l¼üd¤vûúÐöÀijÁnÊߥû+×)˜²Gw7fžíu'ë‚ü÷Ƶöó­ö ¤Ÿ§ðEß¿u @Ex/j3ÎG“SÖTÉ–~ÅûV W¢v?×Póñé+SqÜ„W ³éAzÔ츸p/¼;‡ôzmvvi£¬qàh™A§AqñksI þ·I?:zS ÄJ ËfTù©ûLÕ>ç¥O+º€Ú¢¶ÑÁN;t6PëÃM©1¸ö‚& ¦»˜Í)™f>]óBÚÌÜ>®'bžVë8@{’±G³åOäE6½[²€ŸsáÛçÒÑ]TRÁ ]ß±£¥ûCj»ÍÊ–‚Ûͼ±'®8tGŨ¶<äӒ޽u¾½G™Ÿˆcà".(€á¨b·úƒgx½hÚ{¿9­èŠtÑϳ“év¿³=íNEÆåN¹Ã,Ÿo†¢#Å០'+Ó·$Í Ñkž§YÑ ±J9Ù“ÒŒÞöZYóÐ7Þ´ORõd§‚È#EKÅ Þkׄ^e”‰ÕP»Þ-8HˆcÌ@£Ø>[¾e+š|Ѿx”îi‰ÁÓ~C.øͰ¢M‡¿á°÷“^²&~Œ™èܹÜ?mDÌ¢4K÷–;qF“ÌÁá¤À§¬Ò7‰}Òó€&kX#ŒáÄMqO–ÒwBZ—ú6nñû¿¨mu&˜i›-)Lø0÷»ÎiºsgIzu&4„® O«þÍÁ3õÅ’¬bhqTé–Ý>$%NgÊ>™—Ä«±ÅÌ+½×!Q}±‘`cþëÁ*Ä­`‡Ž_å½B”yôÆœO†ÏO'¡¾æqÕʽIrJà ýc;—½<·o'?fÏ9®‰4о"\bTXò²TÖs¢h/‹¯ (Þìñ ¼Ã|ÜMÙ5»©vÕ°øZötSÒýç·ÓÏù')ÁÝDg¸Ãš`‰>ЦՎžŒ4t}2¤Z÷+Aæ¤üæùª¥Kz”C_R_ÌlQËW—¹•òšVßP\7ºðŸLÁ±ži'Ù_¾"çOi‰ÙøëÚkf"aõPdb49¸`ûÖ_Vuè2¸~ê8a¾j26.ÄÑòM(¤h©Sâ›F?¾ø¡õmÿ9Ù½ýaóU}h χðz™Ñ~ž6¶£¹0u'­Ï·3méêc\°ÒF)}b*Yj›{¿¿ÞJ• \N•©:aH\¦2Ëʰs/tœ9}áªßîÜZPëB¢S>O0_ŵÃ[½†:_—‚ù†TÒk¼MËøZ9îÙ…A̸ïÚÃ]hÃà×Á2àês©ywDÚ¤bCÎ\11.mÐ)¯¹·Ç¶Ç$¬eÁÆ€€‰×‚n`ò%ÄÊÝŠO:[¹’¬}òÏ#t·ãCaùcšäóXDÕ!Ãz‰“Þ›ù[Z=Ö·áòú‘¿?ÿì0WZ¬{ìN±Z‹7Ò9>_ÖâÍÈ= ¨1®¯Äß?4LÆ“¨a‘åºQÝ2mgÇò#|°íÍ-K”SKç)‚w„tÂñÎ:–´ýþÔѽ%%'Éå–K4ÒA+Ɔˆ¼õÒ9#š H¬zÊe£ÒÊÀîì~ÕÈ ý¤¡JF2HÝoàdoº˜ÕÍV•mœþJ€žãìÏæÛSEᯆáíàG,æFrÅá‹ö SÈF¦M¯x#‹dNá3âÁ’F6#D¼ ‡¶WVj&ÀA®ŠÎTñ^„šØ…W3`Ó­vó‡b®'àÉàŠß£úÆ\s¨BŠB?ÀÿøXº¡(ÒzTÅbV³§ž[>X»×.ÛƒÔÚ…ŒT Šˆµ/U‡û­‹‡Èeú­ÚWƒf;±nf]ìúð§¤ä‰Éf"}ûP¡SÌïWÔHFOó×|«“ˆþG¦øPˆ¤õKi¬¡éˆûU©ÄÁjgù‹–(ÐHÚ,Îcëá MÙÇ]Q„7ÿ|—‚¨(1—nÑw!H–N—ù`º'¤¡¬Û±nwBÝb¯bû–j°‘7¯kH¨£ $' µÅ÷W_l¤VUQ‹auÓÎnLå®àrä~îÿvÊýŽ¡­ié‚CÎðãÔ—éÉe'í:ÜYB¬xå·Yå'¦¬ß¨Ç'c½uòÉ… è.î&ª×6°$Ä"üMħçÑh#DEíI/¶G€ ó' zZìã1c¥};&®ßp<[e~*æg¸ÀAŒ *x‹’E|‚ðóJ•n«ÔT!YÙmÕ\ÂI,ë~I±f±šâ{óûò¼¦épõê¾MVž¶ÐÚ KLìþ :¬7n—SRÅô.íCj¸)ž«Ïª43ær™JŒëü\ËKR­xGÄß>P65 q€6Âfé¬Iˆ5Í2å+< ;Þ5ÊP¦^fž?ßhÃwçÒÂ4$*ƒyÇíCÞd¸Þ€ww/ÅH`~Š’D•ñÔ/û<ìaŠæF“’¸_TfŒªp%u”9v”f ŠNò S*ÙüÕe€*eý¨a:åŽûÙ¯j)ŸÉâ˜ð׆"'6¾“2 däôQº4u¯¥¹æx€ÜÄŤПv‚ø?É+¢ßh°Ž\PNÍñôEO}vgzÂ8JcÑU¡—IÁ O`sø?8MgHÈÆ?fÎæÌz¯ÑUZv#ðóTò­×Ãoà4Zk'š`2ЦIUà0\g} ^s“,°J’È{â½\>%ðƒíÈE=—>éÛÛ˜<¿Ðà÷iecˆ‰¡%`Iu\\iÎÏ«†ÊŸ%Ý•ÔÌTðsÙ.*ñÿü¡,·ÀxÃ<#Ì iÐ<|[u™6ÓPfŒ,1O–òÄÀ£ÍØÎwŽoçmm,ä¬ã…i.˜ ÐH‚5ý@‹'_©ñ RÚYN nþûІŽú­@ù ìGxÑìDo©}i|¼Ÿþ"íQ’1FËuE¾Y(Õñ]É &nž©[ÅÁÂðaÕ¼+òœô—°­ÍÚ™/çÜ dÛ© +¨·öân°Äõ!ÂøêåÈP1Ä]ò‰}&Db8jF(fW¿K‘K!ÕÏ/*«•>¡Å˜Å„oI"Ç¥ËÅü…(w%Ÿ·VäJR~ï«’ûÖ3D)d¼1Ù 5‚­&Ä-Cæäe~ÜÆÒ¾Ó&.ò±tè{Šàxh}>q¹¦´½,¨,fÂÖxá—œ·H=ôÚñŽOÑ~ô*€‹E€Ìºÿ$ª…’ÜBž,€ËKÆÕÖìÏåŸ «œZálNêª9¯üX5@¥1jˆ©zÊ–GÈW Á'¢)èqS9”UÍ®^äz¬ë`dlxÈpÁ!ØÝ·¨¹Ö?Xr·+£üWr§êÑŠË.=6-ù¿¡#æxJŒ6v$Z߯öBxT"qŽºì ¥À‡gÎ æyuxóXÆã†Î“ßÖ ‰¾‘UF“A¸ŸùXMI¶ãYiçŒxö(}©¯Í:9ÏkÁØ‘²l} f©'à…áTw@lèüØÄ—Ò¤ç{NÐØ½ÞG,B#ƒœkÒåä…¹ó¢¯2Ò?eÑW‘½B.èD«j5'?ÖªŠÐUêW·}I—ì“í$ƒRéà‘‘9 ~¬!œâžîàM¨NǬqa Š]iÖ2ˆNNP(CŽWð”r2û0’÷€{‘/n`JoÊÉJ…ôÍKüR«2ò˜¹bé•z»fÖÙ׌LöK¦‘Ds"èÇx9b?ÔçVcÙoó*?ÓïóµÖ‰:yM¹ÄŠt;ÆØ·mþfOBUgö£Ô1EdÚ†n:!ñv\§ûA5ñ¼˜™56à«Ör/ò{F®¬ÅDÆÑ ò¤¥ýMˆÃeÿ/çƒùªœÀWŠ_ …î 9Vw÷T:ui>p’¹ú_Äe—3ãÀkÀxw¯8¥ q‘í¼Žú38¯¿'@܃añ[ ;Ž‘¬UgÒD"É|‰„¢{“D6‘¸+Émó³"ñz€KŦiFíáag$Õ##D,èj‘ËÍj¤å!So¯¿Ü@8¤—Q}/6"®¶í*4üÉ6¢Z‘·ìk@ÒÃ:ø $:ô÷š"1Uó"jðýÓéÚ e—Lo ÎzmY(ží‘F50Àã:RR,JìgRî;C|øÝÒè˜@CDZW+Ùoxø¤Æt;(éKÞó£#î_#¿Î“×ÓÜ‚WwN0׉GçÒw?µ,DÔ\ƒÖ&$ ©zØxðçð] 5·im:ËÊŠ7½·1`§›‰x±! ÓŸ°†Á˜äêX›âœ\úÏ.©{º >Ö“%éJÍr&ßj›V¾0[Àé=ïDõ[>Kâ™SÙa"•kkOªiÄ\!ºÇYC¬VèTc-Ä‘žÁ†pÌx©8—õ®«U_[Fhõ†Ì¿Ùw'ˆBTá'A¤Ðï‚MtÖÿ%’¯z·w÷×_¥kíS4R…Á³¤´ÂÕʪ»<ºýÅWkë/^Ëþ1«=¦èjÅ‹…îaßýô7!Öëu-¾Üu¿äsn„±<ú* kë ™MÒó½± {¶›zSefšORÐ6{õ ÛÈgåavÑÓ3Œƒ£©+Ã"ÚËž þà’n3Lìñ…‰hé¸Wøü6ÍB Éhå ùÝLKV åd¼æ³kµf8ùŸCþ¬•þۇΑ³¸´U)«u·rÊ¥;Që°*ÁJ=!jêeüxD뀵®[:®u’H-×+ì´¯*"®(€}éª/±åUwÖ†ÈGù{ĶzN.Ƚł»e¥Û"[š\F`¡Õ»p%}ùû†kYb"âÙüvž<Áªo\o¤1 M%åÛø8_yô1Átkà%¢Ÿ=8c#VÛåL†…L@‚R¬àN€àµcF’pJ‹=å’èVd@”•˜J³—›ŠÊl9=Yww°q·å¸^õýpò¸·™V”ëüjÖe\ޤ%úJòø¨l Ûj ™{P…9JF}lÆ\‚h—AèšÃ~IXZÒY(g“þ÷|¼…8>Ú¾5O¶Åª¤møùJ4dd2ÓæÿºI`>l- ^v½Ç­ÅƦ(>ÌQÔ>l¹WRiKê<Œ²Îà+¼j¹óP«ZJ#DÉ]ÙZë 5d(#Œq áAƒà¯ÝßWŸ!Œ £NêåWÞ†o¾wîô,—8æóùª<Üñ@îŒS¬· Ëà”ì²YEfD˜M|—ôt…#\²âÑ‹fãiŽç/’rÝô ïo™òïØA2íðÁCž°¬\¢E²µ”rž O3Q 1蔯`§fÖ‹}ó›CR÷å˃o›ÈÂÏã4K˜oGµº P׆/§¿)+ùµ›æœNÎÒ¥š§ûæ‰?(Šbbbå¹m8m4žwÖq2 ·ªøÁ¿ûxëòÂtí‹l/"ÑÞVÁ"`@åö–wÝÂ0ñüdwŠZ¥y0á[¡Û£0à=hm)[Yýiw —/KmuÉäsúÏBü1û¹/yÒLœoŠd/ReäÉVÂ-@–§2ó%V£•‰æ „J;È’¿§~ ‚¡l<²èîJ‚Áû°Ê¹º3Û(JýI¼FgÀ××~¼üäd“SIp^‹ãñ‡ýêŒT¡ŠÕÔ^ùlŠé¼.#Ã<ÿsëe[g?0l)U—c-ºÃ¯(Ðà՛!o«²|>¿¬–½Vê®ä÷¨4l±}ÐOød®ÏYˆ_5åüò …<$óªaå™f°mÏ…ÊŒ ~…ëtTr;m¾`s°[BÎåõdöóÒQ®÷vG˜ÆÃ’Y‹°ë¨âøH èì¶î2¹rðÍûÏuÆöÑ]m݉±Õ½bõ¹¶PzÓ¡R×ÃIwU؉§Ï»3÷¹œKHâ>ge` Fóßsà# æ ÷ _šž¤ #³'9Œ#%"s3ÔÝ–9‹§n:£Êéb(hžÉo6çä {Y®‹çú0 w”;æ&ê¢É‡þÀË—°³bí˜WÂu[¼‡ÇÌ-ñ‹œöT?4yòâáz½ÌšÒg6½uÊ©ˆ™Z½W°ýŠGцÕ]–f[þ:Uâ¨ÂÇ8¶ZجºE=ºõõ“ý$"©·( !¼ Io˜=š&¢9uEè×$±yŽt}¹ágÿõ›¥ŽòyÞÁŒ£øƒÇ0;%S‚/¿x˜E…ÔbF_7þx- G‹¦Ë–,žÌzwáb™5üï7#µ6Ú6g†‰z^‡×¶šY7{:îÎèÓ-ßµ¬†‘iÒ0s.'†EZçϤ™n Ý1 œ?s[µìÒdx [§¾â]HYÙYn= wú¶î¸.é;X7j'Fx.Ú]|ð³¨äÂ'²aJ)2"é"¦Uðâv³Ëã9Úu¢úóױݞ¿€A}*­azÅ™¸ªçûùz®6ÇX ¤ Ôëg€`É<ÍBnðè?¼¹«v÷J„Ð|ÜÛËÒa ¾‡°j‘×p?ŸgOQ}fœr‚›ÔˆPa)âýúÙjæ¢Cè§R1bÞÓÉ=•¹Ú a›ÉÎógû%á¶ežsx¸‚šæ™L–±/åìÙGÐSpkXíIAèÔçP½Êߦ<ìiÖ¾Áûí¨!_– :P‹ÈÚ'bÑ@õ˜[挥Ӧ<=\×&|D.3;¥}Âqór='°ÿDAÅ÷ƒÓ‚$¦¯T"½5„." vc–¶¶*\ž—ÚÅOG»•(.¨ ¡¤fß?ÿeOKTÔíŠÑúµÌó¡5'yüîY€“R ø½òÎƇL³oØ5ŸÉ{÷üCë"óÍ´4ÇÒΙ ´ÌÄGÓu BtËg¡? Žq4áÔ|‰û´%ÁÒ¸ù|3ù¡†ë×aZnÂo'H}¤Õ²m§ƒ¥­ŒÙ¶õCûdâÒÊîŠÉÁ l¬tŠ{õîî:«‘è²=r•‰Ë]ÀÆÅ-"Í€Õ“bk¾^,î>S¦¦ÈÙ¢g•2Ç&ÿ†À%‹6DÒý Öm×â>ãšSmÖpû6ì2—•M{8ÄæÔ)ÁÌ"¸bЖ»• 5DüãSz~ó5 Âvÿ7* 4çßÕh¯*¯õÒ fÕŽî‘bù› Û‹ÍxЃ“Ûòê(Aߦk38Ò™È4‚¶s'šVöÊ6¥&Ðy¨Ñc÷³Q`ç¢mò:€˜C9é?ÕªiׯùíoÔWÊ5÷¡ÆÞ²=­ ØÞÀ_ä”ùd7V°ùY> ‘ѧ(N혧Æ&ŽÖX`×'’¶—Ñ·_ÂY¼ŽE‹ÓV“é°Å½ŬåG’ù8 ð¼³Ð”¯Y÷…°‡ M¬ká–•Uê=Þ™ÀVc,µuAcrZ:"s¾…­åZa4rAþp)Š‹}±ÍàÿYRŒ3Wñ¢ fMªjY^5Y‘*¹—„Yô]ébgÂ\b‚rª<)É4ñE6]‚¼=þ‹uÄJi±#¸¹ì)Áºz/´ú zÓiƒ3-ŽëVbO¦ü*å«<×ÛâÂ/wckp2AJ“ŽšO¨·‹šlƒ`½k î1ʬ÷”×ÑWV»UɘëT´¡˜bYð_¨ÿÈN6 åtŽOî±?¹Ë&ªmŸs‘+ÃGĈ݌mg°^´.=Åí(/U Ì {›ì½5Œ±hæú ðkw ‘íSÜ5b}ldòÅ ™q q*¥AÃ2­–ä'¡`®ÖxXq-uy-lTݹ•Mý\Œ ç½5Á¢{à ô|Q¡1Tm?R¤öT~i‹ÍyÈ*…(Ÿ”¸¯a êÓUjcü‡¼ŠDÝ’%늊¹Ž£äDÍ hÊ(ŒެB)ÿào~É{§G¡Lqûý¬…þOñë6 ÝiДè< åfæSÔtÁ=Æa±N³ßvM“t{ù+uz8²½‰°ÔžÐÇ´Ç>ŠYÕ ÇÚ¬é{¤æ"§,ÒC>TÁù[tè¨Ë¶;ð†¨¿nV,1Àú©È9+ÐÙ17ý2Æ [ ‰,'Nc'4¥ @¦â<4S„Ñú²Úhj:õd]BMRÆú±Gð”œü·FgûIÑ“æúla¦¨<Œ%„Çb#°Ô ß'Ì,•w ëº,‰R^†›E‹ê²ˆ€9Õ’€Môš£±ÚËM¬ó#(è±-lBqDµ†Ö¢êÎ{÷A¡$L å>åjÓéÎtÜñØ&…߈/[.xy¬Ý“OÀ»:”@%¹m‚r¢¹¹þ¤Í_h¤-'dðeABºç: »ÄçkëéõN—&5ýæ5lfâN»sè8S•9·ðøéM ‰§äNÞ3ì)}g1­ïŸAÊã³Kƾq­ùy\x4X"‡T’{ý#å5žý)P„M š*¶Üw΋ó#ºï„Ù!ÎÚ÷Ìu~v•°yCºÁ²çL§”ñ‰¡Ämõ‡õé`!‚É;?ecò¸Ó« ´­âùø'—ëháoÓ§?ôf¨~°ûÛŸ5}(‡¾ýºŽàý©B‘Ò~ø1©7äå„ÛÞSŽòpÜTmù=LæÃ^†´#ñ©@Ót’&C%,Ä7ïÊä• VQóÂÞhíâ®û€$nr-t7znæ-À>u™ÐÓîf»W†ä˜À©¨š-,ªËÒþæçv¢cKÏ(Ž <¨3%püaqñÕäØ+–Ld¾CÖžj–]]M:ÅUÇ¡5&Y«År{ÿwŸ©_ Û9(íkªçÙ³>êùsáçÝòRË].ØÍ»µ:&BCyûÕ),ýÐóU<¾}‚gB.Ìš L yç®6ÇÏŽÅ‚í…äÍMj¸±"+­øqraqE]È\ )•Ðã'Ô÷{Á uZþðÑ9å2&:DêËñÀçßã 39#-‚Oy'0Þ¯ Ìe–­ÑòçÚ³st}H5%˜ÏÖø ÎìÐç(gºË0Û<*$ !—ýƒeêÖ<]ž4¤µ8õi2% ‹S÷° ¦[gK3.(¨ü“‰©Ý¤çG{ ˜ç²l‰0<ç&¾¡¨âw¶2S=¦—\’àgnÎè&$n"–F¬t˜.§éÐeçyq{{1ÇŠŠe“!4b–NîÑèÎùP-‰}÷ú¾½¶ˆDV£cô\lÏØ£Ïa··knc§'àje™ËOp…`íø™ Ž¿XÆ®ꈼté#D÷y\¢¹3‡‹b%ÌšSÇͼz÷è £˜æ´<v8nkÇ’èûð¬óÏ»e-Žõ»"\§À lB¾’P”Z ¼P™+²]"Fw¥üÂRSŸºà6(LÉ8ÉÀø)­ó¨%<Ц@i>á:½¨ÃŠkfÌnð˜óË IÊ_X°E½{¶KYlÔ²EW]ö9ýç6úÚ£Í(_e™šôó¯™G7ûâ. n¡ùXÆò€nê½kk‚Œ vÄ)ÂÊU(Q1~¥OÇ¿s÷!QB·j¤EG¯?7d 9ï5í"ñyZrëw£Þx † ¶f:èƒë÷hêc°å`[oè’°l“%mܾÅí"±I)Û’bP4ÍðZT!còÝâÍe]+ GŸþp^Y%X%äœ_èÆ¯#3x–gøºñã#‚zåÎ¥£ ƒò6èzÙ¿cpãS‹Ãþ(z†`ÑñþV nÄ%é|UÖfŠÆñàŠQEWäÌMº ¾„ÝÓñpùcet¤©¿­e|ÙölÜ‚¥â-¡è~f`BŸ†ëøs¢.°â\6«=¢*«w[›K´®õd\ΛÙ5w¦a¯Ò¯53‘ßßq(4ÆyƦ¤h‘9~eFéËnÿиEœ¨÷ĺ·àf0!Ï%-n‹@“îK °4ìüÑÝÛ™xÒÑ+Ÿò‰Z¬JæSù@})¶ã&QGæÖæ6`ŽÔ¿ù†³G5–œs¤žÌtÚ5W®ænÛ Ä>µž5í²Æf8>õ‹z¯Í8¨LM+ࣅý`{ª©n*”žèÔ¯ŽGs—(±ž,œy¦çØNLé/E¬ÍõAåC&êýDÓŽ<˜p…âÞ6[ûžÔ´¤ÙMÅËÉQðu$íÍÞtŽß)¤7á‚Ê—ÓÇŠðè.«VK랊­.kµŒÊ¨×>ea­e‡%=pXÌB —©K¶Š‹]M›N«¬­œXÏ‚î%íV]穨?’‚`ôå½F $Ô"…N›Œ’B”XÖ4VJ*ׂ9OTy<趇t¹[Ú[RÄgí7¶˜  ¶ ·ð¸yú\BðpšôÓ€ay çúûÀ"Ç =¾éÁ>õ,{úk.ÔKà3²óYZ ·Mt¹V…W¹É—H,˜ [†l9°^,ú¶'EêÁÍÁÏ•c¥DQ*CWGywúB<Š4UM/0â ~ÝO“ò¦WŒ<$»%ư7rf.²NL¸Ék¡dl ã{½ðéØN§Ýje½¹{e¾¿WÞ…ÁÛDbÐR¦‹¶í˼ڀ¹«ŠÕ÷so«Mè?*õÙñÝr¤?ådhè+íÐn )zøB’àÙ_I‚*|#S_‹éI7@?Íç—HÀ 7Þƒ¼è5ªTêñ9§ÛÿM·]ÍâÅÉ_ìgÙË”ú/vìœ^o²¯â»Ñϼá|x¸|ÔèSõ“´æ_zÄòÀŒWýAÕ¯ª÷3ìýÝa Þi,ddUŠ~H2ïò­’¦™EůW“óóI?¾dŒpჺ¿lîkcžÖKõ_Œâ3 Ò \ÞøæÈ X<È•%ÖƒÀȃ)¬!bŒ2êÈóë[ËKʼn-K™^*ú çf LÝNç ³‹Ô¸È³ü!Ç›ìí§‘ë7ÄØ‘úœ‰» ÙJúü§žÏóôŸç}R“ æÌ4¿ó@6¹š@@æ<+£7N&aìå”ñ“Wª`0"Áfw;Vo4®iöÎ)mEŸ¿DbF`ý%Px‰¼=ªWŽÓ„p˜Ìóµs¿G´/±ýZ¥Ÿ¶øH—º÷ ‘§A®8×ÓS¤¹œk5ÚZÚâ‡~ÇÍ£ÕwO[)¢“íO=\ùòoILÒåK—¦_xj?U 0GÄãeK´èõ‰h!ž5b{î:ݽ¬^扣$ÖŸóà.”2†øÈ‘>^! C¸ư[”7c‡ÜñÏ|‹ÔˆÙ7ü9êØ1ØXñ½ É~í†çߊ]}­µŽÃí’£ Ì5lBù§¨YëØüä2¡ Âц1·X0PX3¶aŸ'ýhqȯ´5¥HéÌ=:2ã;OeÌnÑ-“»¤ò+9+? P¥œ´­Ľ@ê0åY;ZeK¯–Ÿz<5E¡–{:ûyAÎA†Zž&:OG[¹™‹oNèøý-î:WI?ç6@£V‘§!ø¶»jK´:™³í‹ŸI ÚÑk¸„  Uªcãö0É#=ëæMì¯íý@¯,;‚DV/» ,¡VYÓoŠïú„”Bé}L"‡3#|ŸŸ hƒ?$²óº^ ž¿VÊœÅ,r Äïw-0 &Bè°¥l"¨-õ@ª­I̧&¶ŠU±tH¢¥ÛÆÉŽÊ=ÈH½„D$~j´cg¨Šœø.ªaPŸ¦>¼Ð_¯_ÑWfOa¥»œð‰ñVf¥có;Æÿåý œÆu S‚¿Ÿ aª¾6Jzý©þÅ£ûÞ¹0;ÿ:lgŒ÷­>üš33¼áfÍ;·no¹ªc[5îÓ ÖŽ¢Wck_AÜÛ)¢­ÇK@883 ÆÂÝ®,\tÀ}“¼po«Á£_ÌR.Ô+©ÌÑ»|7kV¹%¦´›‚cXEÊ‘—æhHÑN®ž»¯Ä:» ¸cÙ.)G ìwtX嫨·ø`x•ÌR!”|'d»›Båg‰S~{5i‚?>¯6¼hɨ!MBõbïK)ëÕ[Ô 1Y߬oÝ"YQê'k* &‘/u@ÀjO§‘Цó 7vØ1µ×K—â¥d1“kB›¸O$šfºÜ°øpsÎ[GŸ@Cu l¢á‹HZLTY–·2fü?;¤àY¶±áñ.ãGêÔífM_¶ðuçmûK+åUÿçBó§ÖÒãZ^¬}ˆNŒ”8ýÌv-Xø Ue0ªÓ5i)4Iîð ªJ?ùó iþr¹ëÚði.$x¾¥eã5Ü¢jNÄ;ü°(å³–.°@*ƒàATŸ¹l1 HKº/lª,4¤y lRŠñn¶K*ÙŠòªPÙ#௫¿hXpT˜¹:!n¢%é[÷_Z] -aËñC0óa,ú7 ÜþΑdü»½Å ò•:© |»…6}ô¸ÍBiŸR” kž-Ý›K2äênŸ#åù²ÞÅÜ'®á¦örOÍÐÌï?½F?ð4Q`?òj@»>|÷‡G^Ð:ì•kŠÈßÀùñ‰£ƒÚâ >Ñpùjö>¶ŽÆT3ÑÍ×$=ŽI›ç:ª,‡äAùžùÛ¶Ñ#Ý>fÎ y^› ©/4@Ç¡ Ÿ¡VéÊÒÓÜ'ƒsÜ` ¾]ã ”|J9<;³jù¦åä[ •³ùÇGºþSžñ®¬`||äàÞ¶óKè7‰©6ð endstream endobj 995 0 obj << /Length1 1407 /Length2 6147 /Length3 0 /Length 7102 /Filter /FlateDecode >> stream xÚtTÓíû7¥¤¢t3¤ÆFJˆäd(’ c0bƒ1ZTº»ÃŒRJ)A¤K@PJI ÿSŸç÷üŸßûžó¾gç|w_}}îësÝ‚|w %Ô$ƒÆI€ E€ª#¤    ç„üKM#h‚ĺ¡0hÅÿå EÂpD& GôƒbÐ]w'X–SË+‚@)HáoG V  ó@!P @ƒFºÑj`\¼±(;{±ÌßG€\VPÿPsFbQp…áì‘ÎÄŠp˜ÀG!qÞÿJ!¢lù(JJzzzaÎn@ ÖNETà‰ÂÙî"ÝX$ð 0@æŒüƒ H#0²G¹ýÑblqž0,@T8¡àH´1Â@bÄâC=Àm$ú³ÞqÀ_wÁÿI÷Wô¯D(ôï`Žqv¡½Qh;€-Ê ¸ Ñâ¼pâñËæä†!ÆÃ<`('˜ Ñáwç0DÍ#ü ž‹rÁ¹ÝPN¿ JþJC¼e-4BãìŒDãÜh~õ§‰Â"áÄk÷–ü3YG4Æíû—`‹B#l@¸»H£Q®îHÍ¿\ˆ*štvH@tM^ú€t ½àö’¿Òy» «‰ü|]0.["¤ÊIü£ñuƒy 8¬;ÒÏ÷þ-Ñ€Á ŽØ íPhš²ÕHÛ?2qøX”ÀDäúõûÏé>‘^ ÚÉû÷ßó•Ô‚hêÝ6ûƒø?6uuŒÀ—XSBJKÉ€òă߿³üÿߨkïÀPõú'¡Úƒþ` ^Þß8<þ¢…È_+# øw } ‘ËH€È?Ô·É‚àÄøÿ{~‡üßxÿ+Ëÿ‹úÿÝÄÝÉé·Yä·ýÿ0ÜQNÞ9©ìŽ#®C\ô»š"ÿ¬2‰@¹;ÿ·U#®‡ÚŽHq ° $óGrƒ ¼ˆ;(Üþ‘þž±† ¼ƒqCýzqˆQ ÐÙˆ[w$¾*nĉý1Á܈+ˆû=Ü_2’¸dÿîC Ç ~m£”¬†Å¼iˆ„ J²D~×ôúÍw€$ÁCDÌ~[ –æ×˜Á Y€$ê—Žæ_yáîX,±ðo:‹þ-ÿ^y$Ò §™žÄÀ•BªBšŸ«qzJ,*ŸÛN;4“’|ú€ ×­5jµ˜`˜5s‹™îC8´é«»æ|x÷Ý÷S5o·Ì¾/dÍŽ×&nòç>éx¢ïוIúz’|ÓuÅbl7ÉîÈK¯¨o ìº é WuN%z 1=ƒÈë†6ë·¾zþ,K…KÁdsé.®Á¦×hYv—M8wÉ96øc”exª~Æ•[Ê­G4 ž•—zúzg/wq·Gêz-xŒ»¬¥ÔË¥)CYi2[pñ$·Øc#ƒÁ×F›QƒÅšÏw—¦W£ ©a›Íò„ŸÒÌ!+Ü>‘fƒ¾¥ co H=’–í¾–š;~å‰]„/Byr7 µáÝ“¾QÖƒés }Ÿœh_ 7‰dñ?´/{¶óÈÿ­ša¤CZÜ\hš‡œdÌïb¸ê Ñ4hƒS•½rºŸî¤µ†*Û [þÌ%ð60ÝEqsÏ`lèâ&,D6;^Gñ”-äéÒ©8“æ7„G­“T0ü)ûÅ÷zGrUV¥ò¢«ïÒ)tç0»åÒZ ¯‘yZ0t<šÇn´hŠ—Äô]%[7ØjzO5+ õm ?‡ðrtÐ&[®JCÈ|Ÿ†Ö¥ƒÛ|ÈìxP:J•ˆ1XÍ L« î³ëªß¯¹2Çs)X %\e‘p¤+xì±>ñÎÀCM‹×°ÜÃ>¥á+”2ÿµlæmoˆåL¤$ÚÍ7åê¶T÷oƒ %ª&‰}ÓK0Nq€£¢ÅZ³êèSô¶ }è2I0¼÷û}ËBÞ};ûJfèÑí÷âýÒ\É%ëǺðX+år|ã\!]9- M+å§:L9ež­îP¤!¼?Êí~§/NOtðôÛò»Ó„ÑPaçìæõBÅh '­@èÑW"ô©>a¢ÌbIä±T:ƒ5tüçL T¥Þ$sj“ªrÌÎHïØ8íxvèŽmô¼<ÍΖ‚µTøÏ_nŽŽnsÈKi<•HðNo5s£MŸÎ|ŸÄðÚ·ç Nš½übH¡ö¤'f­«»Ý{c ÒòãT"œWq aéW5Ø[)óbK!õ¦&?ïDä˜8JêèªÄè'ýº\íÙ2û{ÐAö­Ñm7Íë3) å†È}a«ë)ÄFëcÌ•BY¶ßˆ H0Jùy+)°vmºt;)ï™ß.êÃ5lqQ ÌÐ!@x{‰ôºF“P› ×-¥;ÈÔB?úØÀ›@¬ G¹ÀZ‰R ëÁŪÞé79ý¤Ú…›¸ øL1)sÚ‰Bôg)oe×·5Ë¡×köÑöõ_cÜ ]ó‘³ãIñõW®)EYz´1e(öóå_&ÏÁmH/=g~)©¶Ncÿ3Ì뎧^¾ÏZÔãö³.´ÁÛŸOÉTIL1VnR¸J™Tî2Ã\ìj²y‚·í¾¹†4^þ3KÐîK!ð'„_«<àüùh_´,~ÇB|ƒïâkêx®–êòâXÜN4mŒ»bÇÕï·\ËŒ#γrý3,[Á¢pØ?RE¿ìGV‚ÓæÀ·Óùs£–¬ýe7õ*÷ãv௛ȷ'âÈ>’€n c¢~¤…f³D†©ŠÏò¦ëžr|iàtT—Zqg˜2>Û`Ïw¼µ3š«.ö Ké¿ÀÓ4ŸÎä3H +Á<GMÈêbHë’™†2¬Žv¿pà'ÓM_ì@Íí«´U ’ôü%µ¥Þd=B4ÚÉæpì黣s@=Œ|ì¬OR7ôÁ׬¾e_zõ$÷µc£Â×ªãøŸ Rª½žŽ?IB)¡ìšßr¡È oøqÐì¹qÀVÀÜfÑh˜"o,m[è£YÎ=¹ÔÏ+4'íµó1ÜB݃3½#§ýz²‚œ?ìµBXe^/ð7±_-<F¼iÚí³ãÌØ¯Í©*Øâµç7Yh´Ì”vž·pÕŸ»¨,âû™ýVªTÅß–×"ˆì›„ÅTf›Áf”§ã‚Kª›ÂËü =ˆá^hWãòk¯ag};\¶è¢Åe_þ,Û<›ú•÷ìãÅþfQš:É‚eŠÖÜÎ X¨ä”΂Ã`ùEÌ«˜×Í‘I}%Þ?ôvœGt†k)â$ÍÖoö¯JµŒ5/òU~­eí:µ@Kø›ŒV7® Üx·(€içg6ù¢a÷Ã=övšö®½ÁCvŽãxŠ»/òåÝ™¶VÝ£è*4»]7%¼¢”9 w~9]¾³#w¨³^(¶;Õ5ËRœÎpsÁ°cXˆíûˆš 0p2á 9vº/w+lDE;„`8ÄV[J›¹ÔŽª«\øpµëyšýL‹w¿x\óÝj?-⹊íc L1Fï•&šÔ:|ï€é:»{ƒŸJL«¯|¬œ°éV´e-5» mͼ«¥r’8­o¨ ™þ𙤒)õöB¹è•tèuºV75eä»gÁ5qóÅœ e3ÍôÌÔŠbƒ4ãžFiâ„u2Z;Uà:'âe£½}Á [mIËÌO3–ž…ø1ÝnäòO&o6å=Ô8MlWãW'Œ2ŒÅêûdÔ-{ò¹)ÈŒ’:%&,I,O~»»¬ÒßCg1™aú6~õüN®î ød žÛ…Õ$p…×þb®'‡Jc/ÂçhµŠu†ƒclü þ%o€äĞĉL]”{NU¯Àª^¿ö¶ø9å¸m±pãgÏÆ¨¦Ód ¾õù)wõ|³áüñ9ƒ­¬WŽÎò:ÕÖF‹2MûÅÎã v Žn¹Ó’úE)ÎêÖe1¢FŸ"+$LÃÉ„lÚbð¦¾ñxcNÁ‚c—G+%™t6§Ú>AÊ+’T¢l„™ØX!õ s«5r'V|m ôIW–— ±J}糪‡lø– m÷‘5eÍŒ{!b…çÙä¿d~n,oo$'B8]—Ìì(R4lRbmðá<wÇ¥+âd6IÕɾÏ}ªPH b~¤{î! Ïû’œèñ:«l=#¸ÔÌíû¤ú f­8ꮵ6¥½7MÄ×£aݘ h¿Ò¤ØÛh6­ñàâPnr6,øþ ×ù¡Ç1ñLn1U@ ‰¸ÆrÇ`iöàˆ4ªº†—Û"îö&$&EM[¥ý¡>Þ»ƒ6#YJV~Bu'î2ʼ1Ô`Øñ.öyàsˆ#¾4ÂÈt×zè20XgRk§Ï ìÐH‰îlÒPµã+yô½Ïcà§®“[GbU$Ï"D;g48"vm¬ —þñã Bò›*™7¬”eAŒ‰Ï81³9yàoŒ!m;—}N¤Èb-zÙÓ¯n!2mz–¬-qi(šà&,>òl°~tæ5lEùé j!¥6¥&Ý”Ëí|2%S@g«÷Þï;«™Oç:댞ǡò¤™ƒ’¥à Óæ/3C§j·­ôø¹)Ã>Èþ­¶Æ;Ì¿¬iñQ÷³{`*ýˆucPÛ`¥DXèC=“\ºA¥Ê ù~}Šº$*\<~ó9Ó]ZÚ3г&øT•ºÉ±K@®îÊüŠ’¯b¶ÎÕZ4UzËY_hpVd»RN˜²&lȹùçSgünbƒ‡ùƒBPE¨c­ûWÿbé¨ ÄCñ%ü½ƒ`:ŽïŒ+åÉ߬‡HµkY§d|œ' =l6mX… :Ç®Ré\çB?|÷} Ü•4çö«bºç,Ô.F®¥ã1›Û›å^\IǮܢÜÌ<¥O±5Î/T‘d±Œbó?ßKÓ ôèÌi P=êßOÖç4¾N¾ê íµ:#a~d?±¡ÅQÓ àš%¤ÔPË_èânNkÍñ&‹e&"ßÂÛo› uâsV]Z¥œ c-ŽþO’W_Ü»4x¾œ¶ùëô(®>„5ù¹Ç3”Ó{¾€?ÁëÆÎó¯æAÑ*åâEo5úÃñö‡ë4¼8SÚÈ„ƺ"‘6­O¼(ê0ª»³z¼Œ€Ž³š—ç»&†ã׬Þ4š…Ó‹R‰rƒOsŸ)6I¶…U¸Ó½Pà®yð± Ê/¾›¼zÀà-ä»öî¥ée…ŒïÞɇyÐô~åkû?á»ï/Gâ?²™·¦*’íÕù ó8f£]ä:L8 /-w+ ÁIzàUÅ2+g'ðÛöcãœíÜ?êÏôiú³ÎK<>IânP×­;`,õm•½°©€>ªž¯QbmFä’Ì›£v Àz ΊÌyOO¤6T?‰Ñzûß,È8N¯ºå~±.ÖÔƒE~G ŒÕ†T^(¼¿„þ;s•ôG‚óÀ˜¬­o8×±6œw¥.“#ÓË ÖÛCùèíe2 Î-þµ/¬‚mátúù¡Cöõؘx9¹ùbíÒ~n+J6¹èwA½nsgü|®×ª…´kKIÓNGÏ5w÷´ë5áWƒ–Ò#-WMì¹>fÝÚšêN”Î ::B¿„tBb¬7—d\6TšZ6Xîïˆr=ˆi6˜S /|ö°$ïÛLæøú{M¶ø–¥US{Iï{vÖj‡b9ñ®=Âr‰ÅZ7κØ&áa©BÕÃõ÷Ô…ÜY:k„Å$F_Ëž‹¿¼ã ÌedÇVP´ µ¯ï EÐ…}¤)5˜¸›=·àD'[üð bÖ#œ[Q¢}³CÓ!÷ù[¢mLÕ’“·R]lçB”ÎÞph¸[4nße“—.–%IÖñq)œMf™~+.ÐÆ¾µß‚î7äµXÃ>ƒðAeó½û‰ñ- {Æe=ráqv³uí»í‡¤™)]çlî’¿Ì×>óKíGÒZf¨±_OØ€óPo/ð,õ'yÞR;Ë+~î[lgËãN¿_ß}TdQ‚vðƒ·ŽÌ=?–»{c¿y„ÛÜјªi|1<}`Òê4)××bgª¯ìp/zšÄ2Ÿ£_QjNã1בû4¹fz€L ¢ý©ù-1©X•‚ .x·„뎛Y/NÕÊK¾a¡é©ï]è’7yÔ|…ìn‰¬õ*»ÃÙõBÃ&Í»õ„C[÷ý*PlI³#’ž|/‡¥äðq›gQžÒa¯u¦˜;¤·F6ÃVѲ6©å{rûªQ-ž—Ìf´@=ÔD;³»×îû®ÿ^HŸ°›u´mØºš¹žæ¹¶ûŒ›2r•ø/>TLÝwwÝyØtÍ^ÔÝ:󸈎%·l­î³¸’m`BWãîÿu×êÕ͓Ɏ—£ªÅrA †^ÊÆ™¶±Û1ôF)Kj¶˜YAÎÌÅKìbÛûÁð츓Â4ÙŸñ¢†Å˜[Ò×¼L1M—Kåßf­WNfE¿hSœº7ªÒ3  }¿eé°è¼v!¥f;é‡\\Ñî ¿´hüé!oåÙüª’²¶.oÀúT!HpÜ•»ôoÃvC¾7àóÌ‹§­óýÚs½µÁĹù >TC«$í&Ç}%Ã…ÿ5‘‡ñE‚äÏRgï€&©‹ #2䱪í©èË~(µ&» áøÙÈlK Œ#GÆF×ħl•dh OÎÚ½§€ž¼ž~øh%%^]²‘”ÜH´øJ.~àI‘ •Ò5 ‹ª~½îI™ÁÞ—‚—¦³’]cIª×N¶Ò«ƒ÷´ø$PÆMƒkOœÀϵ4¯õ—׫Éh Ñ2}šžKå/¨Ï>ÿ}?t¨”/"'“ö艗e$ÏÚPǹHOS‹‚üÅ6*kÿg"SfÏnZ½Þ–iâ+b¨½)Á,¿üXŠ»ÖYAË¿Ž¥€tŒZ¦j-1}“s8„Þ2߸È+/öÍu-5úïê· ÒØÛ¯7É ZûÍU y2³‹ƒom=»”ÍB[ÌPÞXà,Ŭz[FäþáÂ Î—ÎÆf•FÈ\!?+þèšá«*êv3O sÖÕ4òôõešýÀJTöÚJ}uƒ5j® OÉñ>MvþQ@jøÒS1² ™øÑ”³xeëi>ÂÎÌ·ý›—Ð}¬Ç%߀Eoß•hñ@*nFßechg7ÿ˜ô]I¦=#®ºq¹GMJ$®s<-¾—ê+%Aoœ®ùÅŒåm»@çWÑ•=0YÑydA ;ß[u€·©#ÈÄ¥)d)ö™Ü/žä|B™„4•Î.^ϼ6ÔtÿÍüyMsP,åè\µï½ÃWÌ;+o®—ù1®W´zV¥òI-?\ìÚoŽ<=kÌ~2M¦,»éÕÌ|ƒn±ÖBÒ‚üÁ;*Öµ7釢‰Ï1*¯º/ uï84,Ö¦}-û0¸6Zð¼Vð1Ûáz.‡lbî$çr÷“)„û-OhÃ@Çû•œ7˜ì­¿>Dë”~º§/ßòê•G¸ ÇãÖÁ-Ž=š(é5–lá/øÁ“[9œbC)¬¯‚%.²Ôüˆ\Îùª~Îf”Z3F_øTþŠ65{ˆ •?Äé¢íÁ…Ñç^íö²*#úIÕ•+ÔØü÷ºóªm,iüÚÚ»}É—wûãOíï¹<ºàÍÌþM€$96ËÜ*}‡BzT„åXM¦¤®×Úàlkƒ¦©øÀ×êÄ¥>ÅT¸lîi㇇ŒÁÞÆ˜90é:½;£ ”/¢¯ˆhŠô9¸¿²ijNÏ›5ãÊW X%o¢Ö‹’P³tÖ¬N šèÃÚL*OÙ&N†q–ßÖG'èÔî¿ï¬±ÊÑ–SWûÁ?ÌžæOYÅbçõàB}ÞÉÑYÔ –O’ú’ i  ²¢ Ü2á5÷ç(”YaÀ)™Ã(áOfr‡ŸgÞuh½š_4ù‚k¼NGéÆ2¨eÀУÈ2ßíã§‚‘ú¨öÓ[xùÄ%ºyÏ[ç|)¯ñoüsïÉë endstream endobj 997 0 obj << /Length1 1615 /Length2 9170 /Length3 0 /Length 10231 /Filter /FlateDecode >> stream xÚ´T”í6Lƒ -]C ÝÝÒR 0ÄPCw·H# Ý-   %Ò!Ò) Ýð¡ï{Î{Îùÿµ¾oÍZÏÜ×Î{ï}íH­¡Í&eåd–w‚ÂØ¸Ø9…2ªªŠ‚NNvNNnt Psÿ-Fê]Ý NPáÿ0qƒ`O2YìÉNÕ Prwpñ¸ø…¹„99ÜœœBÿ2trÈ‚< VUv€’솔qröv…ØØÂžÒüë`´dp °þqH9‚]!– (@³;>e´9´,!`˜÷…`µ…Áœ…98<==ÙAŽnìN®6âL¬OÌ v»z€­¿ ¨ÁUÆŽèØBÜþ’k;YÃq Àùû÷ï“ɽ¬œ Þÿ˜ÿ™/‡¬¢ªªË_ÿ['-íäðeãæ°qóq¸¸¸8Oÿÿóïü«ø?R äïËqþQjíxŠò§ˆ§îý«¿yÁø÷Î0þ;…šÓ™ÁƸoÌÉÇiùôáúÞ€?.ÿÄÿåÿÆýÿ½¼»ƒÃ5ãýÿG r„8xÿmðÄewØÓ^¨:=môMõÁí²*Ø âîø¿ZEèi?¤ 6OgãâeçäýKq“‡x­4 0KÛ¿˜ô¯Y<åp€@ÁNnßOΓ'çÿèžÖÎÒþéYq{šØ_*ÛÓÂþ ÷7?mÙßCjédõ{¹ùø WW7ú!žÀ—ëio­À^à`‡:Áž\O5û¬\Ñ™_ð‰c¿E€CùÄàPù=Yªý ò8tþ„„–ÿF|¿ÑÓƒþ-áâäpXÿ|Êù(à°ÿøäïø|b%ô?àSf×ÿ€O¡ÜþÜOÆ^àµÉÒÝÕõ©ØýÔÃá?Oì¶Dÿ6ëd)fWÖvU'EæÉ¶ùUù(ãÊ€›ík‘)¬WnÒl5Iû]ö‚r…ü·.yS»5i—«œå¹SߪFoÞ 6*ù*‹7³ðÓɾ—ä4³Ø-pùúiҔ¥®½p±8Ï$¬lzµØ~ õ_æ“=é_”É (…·©µwÖ•e«’ éý\Ó‚}´ÐÙä;#fÈ]sL]3ŽNWˤQm¿FOò¬ÅYéXÄí¡èŠ VòÙüEÕ —åE­Õ[,ÀºË-õØÏÄóµPÀ—!ÔVͧÖ"F)HùxDl|G‹j`—m›Œ¾OŒý¹ s»ØÖ)(ýš‡¯;T0=wš&Ò&Æ×JtI^+¨ýã\äÐ$Ñå7ä•¡ ŒÎñVÆlZ?Ûª²“À€a)íX»ŒK#6vý<ð,~~³§%'ÆåG®tQ¯œÞ¢“Œöpa][À¥ ˜æ-¿Jú‰·9¥'yJ6™»¢ý®”GnW¼{¼vÜê($"Ÿ_£ŒMÏ6–œ`=ò¬2zvD˜^nŽaVб4Rp¡Ì·V-&1 ÷ù4êy5å !*7,±—9V.¾k’Tëx†A¹p#´®à•d9´„+*:fè [Õ—ÖyW6(m‰¸Ú\ø»h·(†Ã`zdÁÓV 8\â³»ïuõ<Ÿò3Ò[8::ÌßËà¾á8Ós  ZØ}sqm\1C¤Ö TnEÕ³ÌÑ ”µªØ¿=/ÈsöYÏËT9Ê’h2³‘ÑÖæøŠÌðî"çz¦ÑäKÊ%àô"ÆìÄVÏ|N‘ë@ébã~ô[E ³hs®¯‡ÄåscòV…Žt“«ÝÝlqYÀ3Ø(†n íÑà(Q(kÍÂ-øsÁŽ€i–Kæ‘—vGhm¦I: ½"eG6VÑíáÅ ƒŸõµ˜Èb¬ë¸Ú¹¢j¶Ý³;='¸Mà®m~é€&ð1‹Ï@t¹¯¢Ê!™3S…,4¬çÙðî§å£¤kÈ¢ ¤·ÂY·’9Ž´p WDë§‹Öc±Õ4às>j¦1~©’pö/O:œeŠ›b,·ÈÔ­­½m, _QÐYÎć·3ÀGÌ,ušÚŸžzžõœJoÞ£™-Ôɵ­’5ZŸ„õakà>Û¥Ò„¹t6»‹[r²Ð Yæ ÌðÒŽðh±ØÀ{Ãó𽯹_ãåV+o m¼pÜÜ[Ò÷a'+°Ù¤¶‹—B"Í÷›óx-”ÆEr¹^êó–åÒý »¯;ÁÁ.}÷b³.9{‹<Énòm‰¢¸CiYYw}…ÍöD²³ÎV‡$š*‡ï«V‹Ce.5ýœûÏd7¦s0ü ÙRŠAºï'"«=q¬¬÷áÕ{MÒ†š|<(þšínZ€Öa?^ PÏÇØ[ÊÚ(1Á¹r®Ô<ãFɈÃ,-…³r4iâ©•~t€›Â·K£ObvÑþzè>þ޲{.a ,°•OÒlL”Á|„<í«›Ô–ŠÇÖß²„ PQÉÕ¥BͧÛ)Ϲ{;&¾§ªEô~{œ‹ÉÊ%çÄ*:B¥•–:Ù-]jøÍ,¿>-¯ùãô—H^ù >Á ³‰A¹Ä-¦Ä% œ²QKThœ¤¦ C(x¹¶fÐú!x§Et‘kþúÓ~ªýŽïÅ ›Bn¾£‹K¸k"žãÒ´ ŒC”¡ö"ÅÆÒèˆpZ>Òº†BÖÏ¡lOåáu—´Ý¥MõMx]V©¿yí¯õì:[:¢Ì-ºÌ—½lx ¢_lÌä |„7.G.o;h^½#n@3.“»Ø8Ÿª´èGEÆFÝÿV±êI²ÔøÚû4ÿ8þ–Ú׺" ˜Ñ“T×_µ/Œÿ _šê-'ÂBÁÁ~ïr}Ó°j4§œ'Q•×Ë×fÄ@‰æÙ/±–|Hƒ^'J7ˆ£Šã:÷")"ô¸Æ7‰ŒÏTQ|íµ£à¯[b” '¸Luí6,vÀ¡üÜ!,µÂ-§˜µ<ôl¿ä>œp¼j»/ôèÊòi–T>n³¦Ýk½D=[dq“#2âÏY¦¬™[kLܱX`„“MF="°Ã ¼ úþã‡|EçñV¡zGíŽ{T7&8I(DñÍ´ôvÿ íúmÕ2­Ñ2= CÄÅB­?nx—MÕ«íí¬àÕ†Öµ—ˆLþÚS¡³ÓdÞÌ}*Ñ.íÁñr?&ó ^…UƒùëÁú‹“Æ\vÿ._R“¢7³Ä5Mψ&Jqié4=ä&§ô>“¯ôæJt#lû“³…®§îuq9OHú~,?ªZ>û²ÖÓö™Ëô¾öùî´U%¹!±Chòuh¥èÝ™!n.¡Žz‘¨Rý†Á¥¸.uc²ëviE¤À:?Ï8ÁÕݬ©Î¼Ó"-É÷’ìÒ¹þeHÅqü¡Á!ÜC…:aêe½d!$Íǘ&[IzjýRôŠÓ#ÜZ\§·óñ K’e¨ÃÒ¹$4s?e’ÌB²‰lò–ÜeBûõ“ l_öÆT©°¬u,]ÈÝ^Éd*j7Ç41ÌÌ[}å¯aH3=EH¼HÔZét×›ó¢=É÷vŒý4›E¿‚rîõ %÷(6ùM6åšw^„ýuSûã´½×ËI³Øýù虦œùF!o´Ç€Ki •bév(^|ú†²Ù;¨ÔQç-¢ŒÁ×àYÛ/üñÑ…l›ó𿤛n%Q H"ó¶¸Õ÷µ©w‰•_0×-ÖR¾¾ÏhI}2ÝFÇ:> ¡æd&BGƒ)4Ü¢·?9Ô *b¿ñKZ BÿTɧ,–@q4ƒ·x|â˜j8UÞ?}¸g“`j¢(EiÒKéG!Ÿb.‰÷´ÃœÆ¶¹^H%I‹sÊVÙì ©ßw„1‹sß´Œ+*ÞM‚kp¦7£‡$á`b×Íë ewƒíìò&§Èx÷Çe.T¬íFB>ۤ?zøÒ1ôÝ^~½±CÎì3qËræ[Y°\1¥ß3뻺Îäö’¸ï¹æ¸3á&ʃéeO3ô«J5\q¾q—¹h U÷ëyKÐ_íÛ@,tíWÑÇß*¡$²ûÏNbo¹æé¹«h|t„üìÞ« 7m;šÜh-¼#ÎWPY~Ï+8îh”üËì>RªÙŸÍgñ3aÁêHDÄëiåß:§÷Ÿˆf3D'Ç~;Ö"\½ØçÛ…JX–t‚+Ë~–,øJõÁñ’\úÄ3åZ¦‚Š#Tv@áOˆ¬‘VepNlsÈŠÐA*oACè,Í#Úñ««f2ÙñÙÔ«VUÍ;¬¶ÈÇ>b;ö×i7ْ٩‰þš¿úYså©„fdgò‡ËÕl<ÃŒw@.è ¤._Ø4Ôn¸€ª!o„Äm­¥ÑryÒ±ó7*zeá"ŽXPËÎO„•‹µí1M±†šŠ@¢c¸‚³‚më;—>ì8ñJ4 õHdMëʸHöÆÑï®Ë°ß2@õ‹BIOôĉn9A´pd9˜Q1$‡þ&^w!ZÖÍL°BœB7•¯;E·K2nïâÍô%i{v>ä @ÔÓÚ;† J¿­¤Àè}Qƒ, “­­†P½.¤–‘¼jƒP’„WN£H…žwf‡šJÉ• |“ ì<%޼ȽIWm¹÷£ÏYàjX?àq¦ U•¤Éê?È×ÓDDÊ<ŽJB·^M§?“D< N!½ð‚y¼É©`Á·Öm ÃÄ0õêñuÜ…k0xsCE»lô}“uôø^óöA«>¯zl¡ ©3:( »ðL¦=`yÀ¹ÚªPP°Å¾0µ%ò]ìò0e¯NðÂÍ{¿£‰áÔÈGÊ«aÈÓhvÏŽLáCŽºb_„@L ëߦÓÖEùŽ÷Ý¢“ö’%@7Ecss)Å@´÷òl©/÷ÖñÉ-Ì«V÷¡A7‚œxíÅÇÀïšãM³ÆúzÜCÜLR´y³8Ȉ¾%¸wÈ î6œò²Ä¢Ä½Ð6 rùål>QCRø+8ÆA¶f%eò-'/›–ç"gªð=Þü^7Áäí˜Ï¯®Vb•Q44OÔ»ÉüLeÓYµñ×Ç©L+ ;šN©C|õgëºïB¶Öq†£˜Ç¤Êx»¹\ß8¾Þ}Ä<Í3ÿª(zŠÃ¬W-Æ8,XpEËrŲé-°+•ÊJ¹+T/gˆðä¬>ð!š2Û d¿Ü¿ÖáB…ƒRördàÔy"4˜k7e%ÙTH’ªÜ&É_z´y=“ÛúÒ¶`Ê”úÉ9i2aê4ûWÝMzC/Ñ®‘G¾¼ô',…tAîÊZŸúöX?ïBXΙЕ•Ú $O–±>,'!³vVGå7ðPø`ƒp2‹x¾p|ÚQè—Í$Á—Þìz‹‹ÔBÀ߇>¢’–×ÄšôÅ )cƒhùs”QôNYz6ü:ø¼)‘÷‰ê½Zü'íÉcgé{ÒN"…I€Ð´×@ƒ,>¯”ãhŒiÙ<¯áµƒnFivÀz>Ï«Ë߉ÓòãjèJÁÓ|ÛËj¹Zä6½îbDLˆK•Ä‚ÒÑÆLb½ìZ^Ú)JáD[olµîšueݰ‚£\?Y¤y¶äòùŠ%ÃíNZT†÷9 nàZ6 7C%®öä™O’Ì7@uvìíZÒë8ï2¹á‡c¥óã^•“µ™Jn—YÔ¥';wŒã©Óâk 6n&—_)ÌE²ðP¦« õàÄZ–líëÃß%'è *]]¨â1§ Ž˜~óÙ·¿Ç«Ÿ—cªÐJ}ÞAÎÔëÙtœ¾vLE–5Í“†û™ŸÆm°Ýq7”BÑ\ŒÓh3îujý‹(‘›Ñ†ëçyK“žˆ€÷!Ó9J=®éÑÃP2ï%Éã´EbàíL”«Ë#º‰Lc¾¡‚´_ongà¢Ð­‹8º±ùqÕ/.¼S'¢CuÖG„2üâoMÔg‘ûÍSìªw¿5pá°DEfê„2X•¨e®ûÂWê𣗫¢FzpA–ØÔdµ°Íí„¥K…·Ž+=¢Oó­.ž zeÅù …ÌdibʶGÌÅd=)†üCíóÒ;—)ÜÔçv›W]¡L¯ ðx뎱¦°ÆcÛH0À~3äÞ2swÜPŽØ­d§Vwq³ù&Smä 6Êp¨§ÿ=+F”‘Z‹Á¸ üYí%†!F¼2øƒO÷ôÅ/ž¶+·& ç ñ›^ºç‡÷Üá£Z/%ˆØùÎá%¹´],j8ÝDé7K`q“BWâï§Š@oâýkI$¸r([e]qMÏš6ïûoÝMÓ¾Í_gã‹ ½"&ú¢~hV,Wþ—»kŒKÂŒ'í 3;þ–¶|„1`’V¬¯‹t,ó<ùKŸqéÀ¬÷Šæ×&¾ÝŸf÷ÎôZ|ÝÑÚJ³¦€Ì¯ÓÍ®g©[îs$1¯—1³“Öß0åàõ¥pU±J— b+„½WŸ‘íÇ–l~µoÿ:lÜ0¢>PzbH'ye ÍHf>.ÝjŒ‘Ô”ÈL ý !G,¤}j\{S¾XšÏÛÈ-® «•i ¾9 ?UµÕÔLÎôRK+ë1o²ך7wqS3YR¹ªTÁüQg­€v‘ætÒö;YøÜ1Dߌèm*)1HyT§¬‚ô”nŽ6.ò#;òÞ! ¸/ý†!"Ùq;è‹›1ëý5ÚBü„]XŸ½C¸âŠ$ ,+¸÷GËJSJ ipóÍÑágqs×nJŠLœzŒˆnNˆá aÝZÅpáÇh3`†Æîµ›¼"Öœ þ×`a B>‡•Û‡ ÃÏÝ#Xô©Ñ×5Ù$õ™?Ñå’½˜ ³ðP/Êèæ7»{—J:Wã§ JòrN+"ޏRøˆ³Å J¦.lëh·¸&äGâsÌ¥ªíQûµ%ìZ^®¥Í ³h?—m6ayY¬ÓËGô¢;Öš ÑX/AØxȦúœsਦ| ¢8YóGÿÒè$ûÅûÄíQœez²Gvþ^pñ†ï‡ªÃjÜAˆ6«äQ1{×…AÞòÒÀžðî˜^TfÓ(Ʋ?í3Ÿt+ ±]Wi쬂> ÷L îžR«ªÞò¼ÍµšžÂhÝÆÈ«–µõ§e_©K‹Òép]ñ›5Øj|˜ ¾FŠ%¢> #¦­|:dsð ë`š¯q¯¹Y·wÝ^ÄðeÓ~ÞÚŠÊOJ¡&Ú@f~gõãe´Ü¡¿o@…=í´‚_£Y’|ÃX‡ó sœ,]nw‚BŠ™x’†óì:ƒ[•#&®ø»Ä EûÌDi°Š£(z:|güш(&níiM×б6<#òMÑ2{r"L{ýônK¹ â×_ õ^à~<ˆ}9½}Šk”ŠŠv4’³¨&;ê¤g)œ`éüú]¯x»J×~<¨îçÐYßÑXl&÷€°&FÛ\ÐÊt¦¾¯ |\ßֲʳñœJw™ïiW|þ4Ê'½¸"S]ÊÁ%¦Þ‡ï'c÷? /œæ™[‰¨1Èc(žrt±E>gxýIÞ,ì,K€÷t¸ª »ëGŠvu’ž#Z"[±*Ã;Ï5û²ŸÄP.=ÑÈ^5ÌçŒJ)µ­>æúèó!"WYñ¶2úǃtÑ㣠†[_›²Ü™0q•ãé'ÒÊÒ:Ó’ù¯³ÞÛœP]çŠåûØ9ñ¥éÖö´~¦îÆ­Hu–=œüœÆ~Ö±õŠ-ß[8äMLR>vFr¶œ%€SÎâ×33ÚVŠx! Ÿ(H‰Ecš®4ã&5(–õ„J·Yƒr] œãõZ±Ü™EÙ|kÖÀäë"e+¿žˆé…vmÒ1ikåŽÃ& aÊÁ¦Ï±[K"i!JøϲŠWw“UlÛò‚¹m\jvqšÖoÚÔ«÷»4 ŒÁ{Òª\·U7/®|&ðƒÖÙ¶Ôú°æy,"†*UŸøègú°oZ3®‹Ï¿×õÆ/Ò`èY “ËøÊä…‰TÜ¡_õIpáùêí߬êÑÖ1j‡ÚåK–ø~=¤ðDX¯Ã¹ã¬Å¹ºK9uþÇ8(å?£°æ1„Ÿ;tU'ú¬Õ‹~Š ÏF ŒÛC“ÅGX·íJP>ˆl™H ¸1[YR— ¦%tܺK3ûþöÆ,з ŸÉ´{“Ò\O…ªØRë+F馡Ðç×UéƒÕb¡õæ¡ýd‰Èð)r–UÑz#IŸTœ+Í&Í™£¹x¸!5(ÇÑ‹èÒ]!Ú>ƘÅß_Jè—ÜZÍ£Žâ’k4m¦® uzUšìgI0a kÃ2I+®ê—$mºÝ´×Ú“éÅX™3O`±trÐs’šnU@A…¤t]¥N U%V‰w ·SïþùոܶKŒùÂd‰¨×~Hƒ¼"©Ce9c®¸¹ güiðÅÒ\üBh·@mî Ýâ#S«¾Q”€£‘†Qlœ”ÿ+÷©(Ò¾íÖU·T¢Øðøù·ØÒhæŸÍÒïœ˜Ò Ý´Û¼çÙ1¼œ²W“×pSéåHÈôÜëv¡nÁù Ý;aåJ´=”üA±HrA{îLmÀw/å/å‰Ù¦\#¹DýîGY$ïOÎõp ±Xåt—W$7xõÚï­âšÌv³{-»“–Gë¨ ª>2؉ f¤– kÎ FURÒ,­5e:I—MBbÉjÉš’–òVAL kM?#›æ…ª_Ë´© ¿»ãÑ#¡|É U<ú*ªw|Õð´ð‹ÂÆÒ‹ìx|¦9ŠŠãÃÑ®o 3…“Öþ™ã(„õÃìÂÚég)u÷$Õß©¶”éœ NSLÕ51s„ucU{ª ï­Æ (˜ÔT¼EÁ‡9äb™P%¤ã «ÃN–裸"ÔX®w‹T“çÑ+Xz¯êeËÓ«°¶ÕÂÞÀ<ÎS>=»LÒ3ßÑOS§ó@úÖˆwih¶ÆlM7)éŠ D’’ÆÇ¯›âžåÛ*Ì! 9dwüñiÆÛQ¶a~%¹È³dþF¡ˆ~ùuK°óH”úObÿ;eñè¼K¦<¬ˆ›-ˆ‹RŸéÄ1 ¹ /k‰@X%ÀÞEÑVvlè{ź™tX#̽$àPh”œ|ÈÆE´ë¼*¡dÑý6Ô”#縳m{Æ.Yˆä‡x´Šr\À•´ROÿ’sçÆ›ê£m¾%ʹèÁpÍïG¤ýÄæÙ™úþÁ"5«¡½ï trÐI#N#«=Úì{‘ªXŽóX‹bBSÌà‚³É^r“Oôú¥~Ak+⩎𤱈 Ç%J¥Ât*P­j#ezņy%²,Ç­4£&š+Ú4íx5þøˆ1óùu‘&!×sô”ÊQT l-0 b±÷9Ð*¼9¶\OËb`R­{ëA¼4eâè£oáH¤Tþ—FR?N5Ûĺši®­ª‰Âñ×䵡߯λgÝЉ A!–¨Ræâ§z\©CŒÊÛ 7oÎ^#¥ô'†åC½^Ïïjèh‚Ôà[LØUs.úÊv²©0aØ2ÀNÎÓšÜ瘖RPÓ}É$Y²½X¡s†M´¸l¹„/ %ÎîEÖŸnŒ6]³Ë¹AÓK(bŒiÛkt'm]?°¿ýÕNš:A‘…± ”v'ѱl`RsVâ÷óòj=Oýî½y¹ØäpWVê·‹h¹sáF ¯±I¸·æ¾FF ÒWI5%m¿~fÛƒ‰ÖU³è°¨üèßp"ø×oÛ†¢Þ45Ðu.ÔykEJ½(·ÌØÐ`ÑkƒG0·Q²#zO-+ÑÛBxa×óÈû0KÛlÅåA²ý ˜Ã:±·±zÕhºÌ²›¯¤"X*`›<1¿å×>™EßZ®k‘ºÆ×-@¢äö!Ì2¯ì­~u‚ÜlªÓ\{~*å!Ö˜i9 ®6QÉGâÅ„èa¥iÇ—&ˆu{šÒ™ˆÇŽJa {bè µU+KéºrêEÛøXx[.S' h;T›«ÕÑ6ýÍþ„ÎHX±&šV|ýŒ~Ñ™½I³Åë½¾tè(5d:ê=Ïþ¹±û¥H¬|s¹«J½378Z`Øê’rµ7Ø3þ9sž|C-kr…®c©%Ò5¬¹“ÐheûCîÃyNÐvbÉÍ&‹f·ðx/T‡†t3;Ö烚Ìp¸u·¤âާxÞWçT.˜ùÆPGLÃß iÊ”_¶yœX}—øéçDÈCfa?;ŠP`ËaEq^£jæe:­UÙÔÛ± 1t겟*€§”é@]CÌþ@…"¼ùéeœt¬µ;ÖwKÑÊÖuÆWÙ©½/UT^µÃtѯFÇ ío÷«Q1Ú“³:µ¯_œ•ƒ ÔÞH´n[í|}‹L˜eëÎÑ—ÞøâV4S™-hÞ‚y_­>€ÈÑ)_îŽÝ=öÀ»±v#4C5"¸Òt€x}v¤Bò>¹öóÌi2D+~ÛE\CÃÄM5=#™ÊXÔt&¢b#ÿåÍ›y‚ò ¢Ÿ>áÛ$6],7×¶ÁO$ïeI Á j ê9Fª[Á?{-}ÇÔv $²¾ÇK'JW2èΪ…ï¨å)GÞ.ÆfŸÌqOáôßßnCCö$èÉâ/³þ»îk{IjÆôlwrü'˜`znhÅÔ÷y.ºÜÙ÷›ñôëA²©{µ „…Îbã_¸|‡G¦ªÓTó 4¾jõGEC¬¸#æ}|·äÖšRt¨µ²”©z«èhz¾`ÏÈÞì™ÈÁÌbéRIànQnV;(‘bCö\÷[˜Ý®“>þ+@͇×ÁçÿÍgò] endstream endobj 999 0 obj << /Length1 2159 /Length2 16997 /Length3 0 /Length 18299 /Filter /FlateDecode >> stream xÚŒ÷Pœ[Ó ãî2¸»Kpw—àÎ ƒ»w‚Cp î®ÁÝ-¸»k —s^Éy¿ÿ¯º·¦ŠyVËê½zw?SP(©2›Ú›IØœX™y¢ò*,Ìff6FffV 5 ³Ù¿ÍfŽN@;ï?DÍŒœßmbFÎïqòv €Œ‹ €… ÀÂÉËÂÅËÌ `efæùO #/@ÌÈh gÈØÌœ(Díì=–Îïeþó 6¡°ððpÑÿ¶5sšòFΖf¶ïMŒlªv&@3gÿ¡ æ·tv¶çebrssc4²ub´s´ ¡¸-*fNfŽ®f¦€¿ŒlÍþ¥Œ f tú—]ÕÎÜÙÍÈÑ ðn°š˜œÞ3\@¦fŽ€÷âUi9€¢½è_Árÿ  ü»7F–ÿÒý;û/" èïd#;[{#d0Ú˜%äÝéF Ó¿lœìÞó\€6FÆïŸÜ !¬ 0zøoyN&Ž@{g'F' Í_™þ¢yï²8ÈTÔÎÖÖ äì„ð×ùÄ€Žf&ïm÷`ú×ÍZƒìÜ@^ÿæ@©ù_"L]ì™ÔA@3i±‡¼›þØ,ÌœÌÌÌ\ýoIq‰é_‹ÇÊÁ 0rt4ò@x¿úwÄðbyßPS3÷¿GÀIJs~O¼Ëó˜Û9"üu£œ&á¿LÿB\&Ñ?ˆÀ$ö_ÄÅ`’ü/b~F¶¶FÜl&é?ˆÀ$÷½ÓÊÿAï´ ÿEÜïLJÐ;‹êÄ`RûƒÞªþ_ÄóÎù§:Ï;§ñÄ`2ù/âx÷™ØÙ¼wø?vö¿,ÿ<ý_­g2ý|kö‡á]Í¿îýO+€ÉüOÀ_ÈÎÅñþw!ÿ€ï-ÿÔWbéaoiúGÄ» øø.Ïúð]ƒÍ?à»@Û?ðý%Àô‡Šã=ô><ÿð¿«±ûSý=ÙîÜï§·ÿã~kÿ¾˜vÚÁþ.ÆÞÆÅéOƒß3\ìœÍLmlÌÌÿô…ýÃñ;ÆòîúGƒXÞõþ!d?³“‘“å?ÞÏñ'ý}þ™œÝìþá~Ïpù|oë?à»F·?õ=Ûýð½j¿§zš9þ‹û–ËÄÅÑñýWçï×ßûæýÿýgfænf‚°´`gÂdUÔþP-Œïư7ñi–bO3•†ÁkɱÃå 6‰¦*#`Ãñ—pÒpÊêŽ8õÐ2ñ‹×IK=lhk‚rÛoïgƒ8•é½6„Å)¬É‚áº~Bx5¡}ïo/Ö-à?d(r\¸‘•òÐÜú$ÝëúKWÆBö”÷«8eŸKg¢Õ£t¿ÍQägÎãÂ83ÂÑ¢]ºœ»û5‹–=ùF,G‡àsÍVèõy“5æqÞs­\Õ© —÷3!äÚØ4¥—Èa² öO¯âÂÕE÷þBâl$ú”UÆCÖô* J$¨©·Æul©“e7' D…?€¾›PSÒ„aàHªˆYÕf‰î\ÃfmFxØi.²ÖþK£ÛÜ*…`™g¦î 0‡¤myâßÜíõ»Þamxd€á>$¥õa¸id§ÛG³H°_ÀÂ…VÜR'bu…70ºÔy¢KÓL…~Ù5‰ûÚ(˜ß+àJä e»€™ù37t/øÁ9GŽ÷UŒOEÃ¥BçæêO74½À·@N…7ã)——¸–lâ†!Ô¹éâÝá¹ë±TÊ|µf s¥L—›XŒb%ÄrñÛ‹Wƒä…ìÒ’½{?+‡#t<¬yòÏ5*ÔÛ¾rä+“ìžF2Œ6| îãùez¸ý«¬LDóÈNãñ²Â-Ld8fK+(7¼SÅ?»ËI1MR8âûýÎ|/¼1Ù™šˆ+‰mSìGMµOO;ã]ߟÝèK¥Å(¨ —äûeøC½—ôÅ {q«ý…°ÂïšüYk;¨Á>d ¬ÅPdì¯@’t 7i\½â‰à«ª=ä‘yn‚õþœß!Þ!÷²©Ð-bïkðqD¥AÚÄQ’üÜñÿv³ñ‰:*âÕ<¢y]ÝM¸~™ &}nÀlãth J„ ¶ƒC`âT PPB•±.WH‡ñ¶eµí™)ôDÛü©ÒI·vãŽ?¸ì“n—68ù†˜`˜ú1üÔþ3gRöŒ»d®2h° ÿ[î.°Šb!1‹äç4‚+vNÖ7ÔÛB?’(ó`­8“CÔH8°þy*Œ¡ÚØä+t%6ñ\’ ÞT*ÔÍ×)ad™UŒÐK}µ¢2`2Î¥`”½^\0_9kȾhLõNuÌ/HÍã'ÜD2•Œ Kü´p#•àHŒu»R #÷®zûb§Ì?q0‘‚ˆ8mèÛÈŸIÄÂ\â —öÆßvd{Qßô¸˜±>ly¹ž´Qqä×ÐP].8Œk(xÕ|‚…h0–­“ÔyÃí®ÄÏÎ2OxóÉyòA lù#gZK³£¬ ËÛïoê¢`ÐÀoXõRεӳ>¿ù0ˆ‡+;ö“’•Â"ѸÊ3ô^f 7ÞÅÎW¾œµÇsÝ%>-'tŽ“ö[íw¤þ¤²é7žÅ‚}ù²‰X&48£“÷[º—ÙΔ‚%;1“}·¿A0j'n ûíä9¦ º¢ÍéËŠ¿&… 5Y݉¹HäLg*wðíN|wY4˜¢†D> ÕÜ>‘0ÇwkçÚy>’Ÿ=NÝúSôUü˜ÆtÛZßbÕ³+íÝT¼J[Ž~t9̱=—€Áæm`A†[L6…+òà¼èZ^J áÈ8T¯Ý(KNf««²$=ŠyŽq> QÅïR½´K?[*<Õ/xí*¢SY å\Mæm1¡ ß»(‡HåOmû„š4çC*p *lW)˜—R¡iŸ ¿Àöå&l$0™ßõfÚtP(‰³æòiÓ¨ŠÈ1íó—bs —Šf çoÜgÚðUzv!R“µ.jAƒ$`âIá"ÁRÁ‚¸½TíâQ»ûÔ°©w 4/!Œ…_ýd½íä ÐfS4Q7^ â:ÊËÿœ’ìÿü²¦i[þÖê9%áfSúXFÚ##Piµ¨!«)Bàs AójUuhˆKŸ{ñe½èB ««°£M"z²´C)“ñ°CjÚßýê;ŽÎ„–F*öàÍ­rN’šÒÛk`Î#‚Ù}¼ýë2^ £ŸeÂSs‚ ÖÕ× (C:/<¸{3åû…¯BæØœlxRJF®Óž¸êã˜ÕÙãŸËXˆhKw£ÑªbåéíýCø¼ÖJÇà¿T(³ajhð-涇Í"#¡U*2*fméÛ¹¹ËˆO{C‚-²?é~Ú"•Ø|’•xPË5þשñ%Æ†ÚÆ¢²;sÙx¦"z¤ù°t>y~Twëåш]™»zÌPƳí QØ\4VˆwÒ·>Ës2I!{ÆuÃÁVäð.ÈeyâêÅ ^–:"F敺*ˆuFÊKrñKË_)„-ð·@6œà¡2𱊠×ü²ð{'JãŠ1ÂÂ8#®! ~ë36y” Ú{?ë©–&À4—§ö)»ò˜¿È^q1¿1áK3.ðÆYx=¢܃}žÂR…óÙlàŒ×:9î-ÛkÎ,Â.¥™ì…'uØóUYÝéLÎ%ç fx8–bcµkˆý¤i$D¾»e|t\öºnî¸hÚÛ’úkâ•㫇 ˜hÙ«-É’ ÷[—GþÔDÂlšÐ§ÏY W¹]o\èÎw–HŸnø.éý<‡ë§)ìÚª6rÜ!‡˜SP†pÑ4Y$Ü'ÏçS6¯¶qÑ îw ˨ә¤zdž¾8)Eö®×ÝH™„!qi¿û‹ExÂÉ1AÍÚ¢¢,O}Î¥¦Bd÷ÅÜ`SÖ ¡s‘²Õà9³|ù]Çs 6_$ž¨a£n"¾ƒómnš¾–÷ü>¯@yÞ màøž›´Ó„^ éÔõ‡¿A2ITÜ0Xã(Ïr³c¸S9aB¢ÐN©£o{5мôké4[û½ÏOžÓÏÑN<¡àT†;DH§ŽËš¼ ‰…§CN³wƒ‰MÄB0æ2ô 5ׂ)YÙÝÐJl<÷ÉçX5/ÐkÝÖ‚NyŒßò÷H¿g£ŒköÒJ é­1}7ô(R®NÔUNêÁ— -]ªa]Eê+~™äË„¨R¨Õ)´ÊrÅVÁÑ©¤-œê8¦?ißõ£Ÿi;˜ù´×,|(Œ¼_ÔUzºE˜WÏ;½yºœ• ìšÿ(EUÛ þYYhâ£ôÒ¦3Eþî[rF—N1 WeçsŽå(óC î‘6ÕÜŠQO£Zï•–£ßÜFÈ”)#—‹…G,„P{3:õ ¡¢AÐKV¢acåRß:Ýx½tì‹uf(W•¯·bT ž ÞÒïõ†æº}!·±ÚºŸÇžpË’Jî‡îh+üvÑ3ps ú¼I›Öö©ä~ÄéîÒ.ÃXÈ+ÎcŽDT”8Ò ÛŽQÓïsãéÑ>36qÓØ>ØÂI)Õ”œaZ÷WÕÄ\:¥¿ý(´æ6è¼[|Ó빟‡û’éÌ'==Š]‰· jE<+GB³CnY]çÚá` ŽoÚï~†öjå“pãÎØ"$¯„âX¸-‘À"À=píIÀk y¨êù^gC¤U<ÚØ‰,•'À'gº’0?6EH$|XÛx:/ß0Ò 0Prg÷— ÎÁô>†Õ|®ç[‘$ZÀ@ÑF'e¹åXºyÞØ’Ò%-Óy`IžH;3áPxà)µ`å’iy¹ipb‚²êù¥Y)×§"¢O¨"bdóãĽΠç§v&o-‡|QÔÆþù ÆE,zL[ÅÇ|¿âßLVÁ›ýK¹$>놉ç'b”šþC¥» ÊZ-ä0REÇœ¥ *Úáý†æ—´ ®„A˜eŽÉ(·§ Õ/=pHŠÏ;ΠРrH äÈAhƒu,}ƒà Œøß,¬X¾hC¢ê©³bY‘ÐõKN³¾ÆîU⪸fÄC›Êöq!xey~³4]!™ …×LÑ|°ª¸Tô[îxw¡dj¬„Ž1ÜËêÅ©™%Gø&Z1W” bJ­Õ¨Z.³Pø²ø¿:àƒw]¾8Ûȉ²$hõ8ÆñRâ~ö9Ì~ÜœòdU¥ë"ÈWbéõ%2†PeGd+“I–_ J²¡¾šm ‡#j5VÞc²µWàå×|1‹ð¦é]Y\7ŠJ®ØüÜ2[Åî­îó£¿ï ÷¶C0M2š¬tz öH2. 7§½W<›+KqhR(^Õ|Jô;ý“ÈÒ˜´¾¿* Ë=€ìf¶ÕyLG9DβT›a/ÀWÕñÕÈ ¯¤-Y2?ÅGÄM U2­ †,Äá¿¶1M‡ð'€˜ÙØ4,&eš‡²ã„éˆྚŒ°ÏØ#°<µPU•;iR¹lÓÇG™\Eưü­úÚì+ùô®„gºaÓ`“`ÞŽ´ ˜ªe2ÿt{ü9”™+ŒýK¦DîŽFM)[ÿQ…0‰‡GûïÕ,F– I¾û%tr€ñ¤üëBø“¹ÛFrúÉè÷ÁRÉ’dÔŠ*sy§iØ9b-MõŸç_ MÍÚ} Ñúˆþs?)¬ÆI¤:/"¥Þà†Çcˆ #ùCk'®ýâ¶eš]s‘k¿è­’!/Á–~\¡µü‘ƤŠóBØv6ZÝ}%”P“ ÿͨ¼ÞŸ#MØÏ$"äÈÆN¼^žú:Ƭ©ˆlÅðçHÛËjÅÍÛ•°Ò°•JÚ&çÅo³†d¯þ9÷nV©gäÔ+1F¼*õâÓ„½Ñ¡>â—EËEkHÃ̦óôû‡§Ü.«äŽ×Ék7I.æ>&½tݾ$/kzó™Oø]§ÈêôàÎ94û@^©ëœNÅà¾êJ3Å/G„¯S0Xå.‡›} ’¼a[W}žYÁéRŸu)bÕÏ\»Àˆ¦áTjl ¶ÛbÈÄ?`1̲Ýw~J ­~ýb>øbݬÂx’~÷âJå?hˈF5®ºÓ#Ö6¶dãñLŒÃ•€•÷AûnA´®¢ßö¨A¿±JÒ…Ã@2ö¡a‰åûïÎLQsˆ¯›ÑcÛ—›ìá5, 0ƒßb>ö0tûæ¥<–ä„OÅýàzBò†‹ú3-’²¿ø8Ê` ÜOÚ v¥.„‹ÙÌ…6´Q.åþ=k»½×Ó§3hÚŽ(G„bw¿xc£—M‰`U !× ÂΨNJ¿ÒcÐl·• ·ZnOòè̹¼Á©àðÈÆã¡ö©É–i‘ïºY '4*êlC¸Gâ; æ{@IS'¿µ[¡pÈ•Jw™4øx[u‘ÇyŠm£«Oö|ukÓŽ¦ëx)ÿÌ;qqÐ7YПÁòãºÁÆoɬ ÜÐåAϪü”sa5ì°þÛ€þ2'þ9S–ÇôoC£Ë\´ïCH:U(†3câYù=nxÝЧFDør=÷×rFAØh>V#ÕÃB¿ó#ö|úýÜ?î_h6BæíBbR™A´È^ÈU6‚ŸK‡ÓÆc.¼(l+›Ó­´w®eÙ‘ÂG/©Ã·{NßX[ŒíÆ|u©—È™NãïE×zòXk.-Ÿ‚x¢m‡²øõÆ.¨Åª×ó•½XêÛx^úÏëoúÝSrfvµ©êg7¾î ã㧸Ni nÒ¤@_³ Z‹+„¹H¼ÄBTø™X_äûoö¾ûÿ¶æ‘Öº7Ï/ɘ†Ü~›|ùM‡¾ô]Kü´(eˆñx‹¤kª—”VfE• ¹kY›¨ ŽàúÂj‰rfIøPæ]Ù~Ø–68´e´OwÉ ¹{䜮µªxjÚ¨ád+8•r)oìEç‚é`“T¿Nï{ý$°M5$åèé°œ0Ë%_ 6õ™šKê{¡†[Fõ,|üLTî$Vâ,ôíÞ í[zö¡ü¢€ ¿¦¥á®|{˜ÀÛϼá7ß-³Í3 1™yï”ÖV­>ÓE¢ŽCØjCÂC‡ˆæ8/©ùñ‰J>|Ф³í²¿fÉ&âÔrš%îŸtð^îõç ñ ùÒ໼Ubº}HR.sœoÊý/S©T™ÊlCÆ|îdÍ1Äl7Īc¼¥Vƨg+ÍÎ2q°L#¹Šo焎ë_zpÝõª[`Úh¶/²»ôüm2!9ì:Qtr§$øPè(‹©Ð%º5 ÊÝÒ×Rsã·SÄ]‚j¼gB‹Ø oˆ°ªZÝkÌ5üå4m–›š 0_:ØÍ[$Äš,cWëÔ hôU¡§ˆ‚An>/ôˆaŸšÅ1§DÁo«îµ£U Í<{æ~]²µÏè"4.:Ÿ½¾joqÆbKø¤»wGBªgyGRiÅ7 †I }T_@á”FÔ%N :Xý%ðÌ;¬aðbX`þ;­4³Ölƒ.©×"&Ü›ú²çÀÕ°Ë®D†9äØRAðÒFñø×0îÏê…On4•—裘s¼›¦Vd…-U«˜a–°ƒˆ…íNvH -Bñ²’\±;¤ÞÊS¡û¥O{€ÏמNÞÁ>ù}róõªè…¼þæ¥ó¶íE=Âl± —ªˆ¬}ŸpãtêL›že2tWë°ˆ*®±LN—qüŸ?zÃŒ:wZ±L¤ 8¾F`VvMW¾âŽÉ¸öÐË{ƒÃ_×O&i¬ýšúœ®T¯³ºÎ¯Þ­ÅK°¼"hB÷‹b³þL¡mUD•ƒ'ä!°»<º4‹´w¡/£ÎâPí¨}mW߸D³f…º––åSþpHƒ•°¬¡@âXÑ«íYÈ_B‰í˜Â'l*-ŠoÈöÅÁ Îé©;jsýqì%"C–vü‹,îÏ5ÍBÕ=¥ÈñJáRIªÀ>¬¾Õ'캩™1ñ ÖÅ))%®nì*¢3í]Ía†Z‰a4qù¸Ÿz߆D·³ÉÑÀô®X)ø•[ö·}÷!-õ·ˆvŽÆN«ýòÉ–½L¿Û»M‚Ÿ€ÇÄvp<Ž ãê^ ÏQNU½›OJ;gX_ÂÔíÊjöÊ… *:E÷Šv/šŠœ¥Œ¦[xB$?S…õñ*±d+WE›ø(œWǂۘ ÷Uéš5ŒuðêD¬ÃbÉl5W˜>+ÕùmhÒ*ÀûíL'USµ¬²¹XÀ’ðÃn3€>HÍh€zÁ¹ ®^ëGk"¸àÒD--o1œi›,s>¶RŒ”” ¥žÙÕ˜àc¥ß¤\™~u~tbR_%-ïÅÕÿ*Ô´ÞuØ,üú,ê_~òbÿ}\y®-j^z4ÁwvU@à}ô¬>[…Ò( õÔsõ ö3Á½Rù¸£T<ìÒᢱkL™Ž;¿4Wâ4%F¨g“)èkH"+çd ø6unúBþV*M¯RÀ¾à„,zÉ`²½èO‹Ä¼edÒÀ÷ÿ–"~E½ŽÂ³jŠWÓÉ6~Dñ9ÐhOsz8µº/ŸÁBGó”.’Ï5’ÔúÆð©b=½æ;¯ä1`m{æ7îì}g3Ž@É&¨q¥ACÔA¿ ÈBɑԗ¸’6TÊ­›eÄ ‡z;OÅ÷ðix û±ñ‚ªäFGïÇöqÅ˶m vVx$zÙø+Y]^-âMØaºBQ„0Õˆëä7Z_ÖkîxõjiK [®âÒÍîñí´øâRvöBó†*¨úóhä6pùÇr¼õ1nWD(GùVìbâ΄À>MCK/ëñäû¹þ¶havlôÌAËx:•6GImÚé3TÆž8׆;Ç+âd¿ü^rAàŠZß;§›«Qÿb€ùÜ2‘ºËßhŒxIÏøC‰¨Ý"Zý*(û!\€|¥{4Y,&ü«ýç14fhDn+£ßŸ¶Ti…¹¿ËWÎ:¤®|[m 2c™OÐKeÚҾî0 y aßeÍÛ"žZ¿Òô¶ÊdÛX5 3j<†X†ž!³Gô¸8Ü´9’°fá3V7ðþεó#q…ùDHO}M¨o#:Å*‰X„ŒÖ¨y“ïˆÅ‹›7ºìižŒÒPN{܈"þ!°W(5èRezEDÕEùšŒKây"º”CÖc¢QRü*7a`Ä2‹?TYˆI½7æÃz\fb´ÕCßí"&ƒ—·|xk›WƒÜöªöŒ—&¼:W&ñ”µ‘×ÄVk¡ZЛ—ÝIORdèºR^óJ½ì¬uPf$’öþ…wƒ1.Ûª6Í/²1ûy¼'+{\,)BúbÕÂgmŽÐ†{é 2°AMMPÎîÐå••g~ä‰ñ‰‚äWlåK·|1¾ÎDŸ Åpþ2JÂB§7Øà«O(·³|Ø¡RŒ–Œ\auµ>ó÷ ÖÖý”žäT;ÿ)yݰÅÈSifUµæ$¢5CYæ+¤[íF¶{p³TB;Ö<{Ì ôHrøÙ¢¬D†?™êî @§ÉgVM«1#.r%·¼§ï†*øP@ÖÂè•­ŒK_o.àôxË‘ÀãÛΪ#·g®Í˜¤“ãr¸lŽ&œÏ^¡O.ÙËÊþyxt&„›sŒ£Xr{àÛN™EžVç8ÝÅEXÝ­›*6Úð÷öä/o<’ØsA™~Ði¡¬$àn5¾ªû°8(š°X…þEìÐã݈’ü¬…Ë]&íEZµ9ô÷…u*búøÂuã}èVÌHkŠâÍšŒÊLgE{³Ìµ&)á¤Í«‘¼ÄEfnŠ…“G”Rq©z–“?+ÜäÅc†è|*Ø4‘i"rп ¬tO 5…)@¤Œ[¢ê¢HQŽ¡t¾!ÌcÀb^õ‹é*N}ÂÊ‚3’y¡4e…[VB6ƒwŠÏIW €}ˆ‡¹ˆýøñ"¼^`%/;Ÿ nХЗºJ„­ÎÖtC¶O´©†- üR¸ªB ob“–‘mH —ÃöIx+‹ê;8*bQAn®úðµÏ"b‚É{ åÌŠH†´Bò»PÏÓå®ò¡îZ­}ê{×m$d0¤N˜5¥3}K,­½P«Üó¡t~4F’·pÄfJ8aÿ¥üo*ގ踕­'_µy'oÛ›ä2/i©¦ ¤ä7l`d$ã±Wø/üɶôÇ4ñ~jýzæøc 4î·uÒ«ÔÆ5^媻üŸz,"Jñl˜Â_4ÎO>Sî(¦ÙÖZÙi…tLBeø}“÷?ºÌÂù–v3t”¹ ¯Ê÷È[,O©}d¥çàš»ŒÖUÎÜL„KK‰í1âbCnÆj­µN^I¿]9ˆÔãâ{ŠS‡5\óßÌÛÿÚcáAøÐzÓJ{£ß½€IH´d!nBtñÝé»ðnšè¯<ôò/µ´ëÄ¿= ,¤v­Ð⋹{¿Ìr™£òÞ,ÈÌ`…ñX¼5‚òʶµA*ëµN›ΘLé“Þ2ú¾¥Ú-]»r§uÐ ¾?ñ3²Y±²¬pë1Uu€bítœ*¯ì<¢Z$ô [’U~0¢þd’"~YqÀ5 “`–l¸RÖd’$q±ŽãpV6ì«·Ù±QQs«¦Ç©%Rk±5íÆ—Žøÿö0 e>Nc+a0+9[ *ëoJHºãu@xÂýã*‘k@³i\+$Cž&L€ú‹¶¯¿Üø,1À—°ÞËîA5EPj”ù§õr±|¥“f¨Ž€Û*'•ZH`—ÃSÓ…D¦Åc3øî…Üàäu5½]Lôígð32²óˆØ"âR²æ~ *M.ä2q€hwV’¥=PN"(¼+§¤«‚ͨDAWÔQP/œ½ 1Çù•ÌŽ*|L¦™ÙµD™BcD ê…¿îãXùü‡4ȆÃÚ„žÆÊD k'à ôf΄=¥fƒHŽT¤6Øùi`Ò¥› 4-Wâ’k\R#1‰Ðü¤qÝŠ /ä\¼ˆ‹¿ì*–±f,óøØd€eœr˜ ŒýU{ÃÎSÝPv»«8â× W̶ÔïQMžÙ!Ó¤H.ÆÂ‚%tf®ÌE´m‡y-|ÀÞuоa·Ë½ÎõVúœ¨|_ÁfO B§?ðgTIá¨çæ[·X§…‚lWž%YÊ­TŸu®i¹×fW‘`=Y^AÏ­àÝ+ô$Æ/˜zH¸©^&c½#,nëò¾pG¶¯4ÇV˜6mš™=„DÉX2"ž  ýBlëm<çZyÁÐü¨YÛ·ÙáB<‘N‚ªÄ¿Œê„[˜eqŸ¼‰:[Ê¥ãâšÛØ„c¨¹Z?‚,ß:ä`ÝQa›ce}™ “ªO|V•â7=·›âä§´ÐWôµš]ªi! SòiAÓ¤æXêþÉÄJ/ß_à†:%ã=8›eç¬.”vÆ!ˆö¶]Pbö°nl>è›|>tÂÕ•ÁS²=÷Á²µÔÆ_òXy‘üiá]¡P¯9¹`UÛJ5iûu o$NÚTçu-Aj>Uj¹ÅÊDn½1d¢?Ø*íÞ”hÚ-a_W 5Û')(F¨$þ<-Ê)’Üïæ»”æÍ²ËÍ•ÂÝïsÅóÉiŒ ¿¡ÄÏ’`ÔÛ¢·~â1 [µr .yèy.i_ë-ûÛâðÉ#>ç4yCW­œUzÀ]Ž‘äòÒ$×%âÞð:É•üÃ7Ý+pfWå=!ï±sqMî½âÙæÓÐëî´/ðxžÐÝ1,æH,ÎÌ[ôqHÐI?TŸ“ù_VX:Þx¡nüC­kŽs¶¸áb¥/C÷ü'ô\Ëâ)ës®Î_…»W#9èñ;²ö%FGí–GFA³Û”9»é³\‰…RÈœN[_I^X SÎxa;ªEk:gný]6¿|¼÷¤SÏ}x»ôn©`ß=5nÞ|%Ū&NsáæÎ\ÈÏ}¶^Ë à«YƯ–Û :Én¢k.WÌ£ßû D‚çÅ]dP¨Žª•ÃámŒ ô;ùÕŠ_|±Ùy !Ða9ôÙ0ËŸåùŠC«Íoát‹FCͧ7#:{ö'ƒùdùÇùR\ñ)òùÑD4쀺2ÉD´ÊÖò/5FŸÅ±7F‘¤ç þühâÎz?i¯ÉÆ»¤(n«Þ9Géò™3¹4| éó³ŽlÖ½e¢WC´«n ÒØoŒN_rçðÆ'IBS}»ž¼ Tàˆ×ÊêyfC’@s35Ê51XeõW]"gKÜ®×ºÔ ’·X¿Gë…@:5àŒ]3t"Ï¢é È<ÿk뎣Ët§Oû¶DwA’›Ã³¹Sæ×é+°¦£ž¹b>!äØ7@FcÆÓîB EUd†öè¸,ÅNÁ?•Ä› qÓR¤Ø+šRZhyj/) ™ü¡î×Ĩ]°i˜I\vÍý^?Z]L¾„À1•¢^!±5ÛEZÝ-í¸:§1”-kO©^ø•°ð³Ó¼$% öK´•{æ Ö1Ø8XT0¶aÀ*l›ýú™DSíµaìf{ ñg]_˜µ(äã®h²D*_éúù‚öö¹ö¨£Älv(Õ÷™r\=ßñøbkCèS5£&èÙ7¬â_,±«é|F!“8Ç ìýsÀ"rºl¸1С‹vA–^ÑÈŒ6;-­Ð ‘Á-ã#ÙLç–ÅiWÍe»wJêÕ“ÄS0|çþpY…y¨úŽQ0äOö|ǃ§ƒX]ðêW¾¿+.+{i!·²"6™§qÓл&ò“–è €¢Ê…~Ë­>D¹—oôJsPÐ\ŸÒ }ÿ¯ž@.Ì­ð¼3,#M£ŸäËÕåSB„èsæÎýÏwÊ›v¬®¹5T’4÷×­ÑLosÆTû¢!K¦“oô.îäÐMvÅ^¥¯t8¿Àæ2ÝÙ#ÂÆ8‰/A$­ª2pžf¹X›Zô˜ôšË׳)ãDÌ@øN±PØ”–[_:šTTü h…1úCˆ»¡Ï9\jÏ‹634w©ö‚âÁ±ΓS¸g”Ã塵Y§>iǘ ˆŽû÷QMû’·îȦé˜ÍõÚ’^¤ú\Éah½‹uÒºë šû6¥6ÎûhMèZÈЫ²r¼Uã¹´öE’Ú[9ëì( çé"ì‘*BLciº{~¤* ü„äAÙµ R«ÿ‡ÔƒP3{WÒ#ò¬Z”‡røßî]¿t×Ï´¦’X8·VºbIÚ„& Ô”—zO"ƒtgò i“2Jâ/£<ÿ®…<ÔyóõF‘¸]¡¸[áî›Ú’ðLp=lÛ-ÿúÝLAEf Jt"ÌcÊ&Î5•‰‚ š/ÿé™Ñrô³3 í\ýJ›Ê8>UÌuIq*#FO\G§0¾Ëã0lW–ŽÙÇiNsh‘Þˆ™–Yù©ËmðUÝ6n] ’毴Õ7ŸVV¹Y†¥±éK³=û±Ñv¸²rƒq™ÍµˆºiÚ2 „‘²Óï±TptEeˆ¿ÝzˆUi÷P‹Œî¾èdÅ=¢ûN^}=_BÝÎPÛòØo"“0ôhgeS}Äë°.Eƒ&>†Ÿag±rÓ¤wµp'NDîðOôõŸñBpö é¾™×ñaÚÓÚ.îžV³z&‘ ò{8ž…– cÇi¥ÀWÄH E/Bö´|}„…}P]éåË[Béà3–˜£<€¥v—Óõãt ìäkUTuäèŽáùöD™‰@6y<Ä~½×3ØÃo&W2xêUOÇ•¤-ÿ’õVt=Âf6N²nZE’QibžÐOˆWÀ´[¬ϳƒ®‡T¬i+ôËç*Îß5¨I0Y ã-ÃÛ°Üì¿þº é‹<žmÕ²9;’¾6ßp’ÞÒµvà½åÒÕ­-0¾Ëî\u4cýÄç’õ¶™rv1É@þæÃ­´q”˜ ¶Î¨ù#wð7Z»b$çòÕ„Ù,ºzf’ùÉ4ÚÕŠ9v~QÔ˜²™ú‘¸­×-¾X$lm$ÉdÈÅîÌqévì?Í&†ß!Î9 6ɸ5Hvá]‰VÆÕ[ûWpd¯¬¸µ ÷ÎN²Õ¯]uJþ¶ß ŒE~k9ï ÇYp Á©‰ÖVv”Ô¼•1%†{¡‹-Æ,~Qøý2‰¯†Ÿ¹‚–žgs´ÖZlTÓÎUš8¶¨üCo›fµö ÷ƒ e©±kˆ.r·ÞõQ¦`vŸ±¹gZ{tôõœHÿŒíìîØa(‚‚ò©!º:TÔèÕË%Ò`péäÓÏÏÌ-/xYx‹è©QÃS ÄGÛÁ´X’<'ÂOpeP¡±Ò˜–¸ÚÉ¥VJV•|ò‚¼ûžÒW XQM‰Š/ ~¦†…òÆá€-ùnê`Û"i@B\2$vñ|à ¡Ó+n*~ •äݯYÒ KÑÔb/HÿcT*×\\­ì'BÃ’$à™Â•¹¬ïëÜ“}¨Pÿá¼0Év‹{'ë^Ÿpᓤ)%/gd÷ƒ!×x¯„Ù àE¬Áô›ZÂéD]n1­g»M¯Â}¸b¸îÁ‘¢8ŒD®YBzL>g1oqãµ¢} ´O´Á`)t€É²C`?7ÑöNG’ú†£ÿ}ÂòsfÌen"+OQ=ŒÇåyEÓ7©™Œ¨?òÀ‰"¸ƒ˜Ã‹Áã/?c»]êz-T.Uúé”ÈüðÍÏû5ï²ôþ^l ¦zE*[ã¶°A°Â?l)ó×GüzýÉ@Á©œ› =K5J¥.¨¼Ö¼âŸ Žé=K¹¶ð½‡X1™¢kèb?4–ôñ8‚”ò«Ñ‚;;[³°Xò~¬W¥ù9ˆùبv”zË9M«ªµ?ï ßL\Åsò…9 ˜O{†Vs É1î#éÏ< ç$D`Õóâ´_Þâ>bªDü0ëÒŽX…8¡ØÒ㳚¬²êd ¶,â|‡MÝñ08Š‹i!òf+:nS!0wXæâµ)ËÓ)HuDò#² äWûß^-'q.©œ7°œ7ú*Ï¿p‹¹o…D[Í5< &ÁkÉã„n}’ì³â—–fO°.0h®?%*ÌPNÁæ~c1¶Øªî¤WÄL}v =ÛP¯" ßËÌi¦ãp¼{txƒ.—$u­IDŽOx¦µÄ{]rÅX½ OÞS#xªù ØÈØSŠÞ)€­ú”»Q‰‹»Ÿ¯Ë`?»2y›Âió€9w­˜?è((Ûã¸T+Ñé&~:Õ«ýë`Åì·Ã õsädzÍìáÕ(îb6çRAÃS¾›­ƒžA7¢·U~Yåªm öô¥„áÛÄOßx~q;®EǽEc;³eHÚúPàDW³Çƒº,•m4ž–”k@V±ßø•‹º~îdœ[æ­Å§Ýuä'ê⤠­‹-l‹DÕÅܵ¶¢±¾ fÄ´x%™#z+@Îñ‡P§”lx¡"ƒr%ù sý ¬YçëJ4FІôj¨‚EhÍ9 Ì`h7ïO?²z´(·¥c £”+xÔ;€Ø<} o©l4eÐKkXíÐ>Lûžw¬Q§‰7‘O 4Ba×äôÀU‰­dV¤¸xeâi¤Y=èÌá” ôS¾Ì>àÊgy.22°cÙ“>TA/‚ó@æG¥nô³’Ÿ'v·”ÒÙœÊäH¸fê÷ÅÁçíBó 7 ý"Ž_øf)Ï{žs·wëÜá_ý Àû’Ä[̯7^2Á#%´ßf%pš9·.ê±’™:úìò¥‘?¿¾ÃKl_Ûr_ƒ¼<.ý÷œSâ¸vÇý“q3Gë²@¡AeýmxbÖCB`—èõŠ…ì)¿ÏU,o±Ò†A—On:F†î‰¶›A$ØŽ·6‚ ÛN~Ë™ECbKÌ=|ê-µG/·!C»ó!«IaD+3«>mFðÔÞ,¡š~Ñ96ž_m!ÒÞ÷T–ZQa]v¢:—ðóàVã=mZ":^#oUT56«XÐħ—Šî›•ç^wø_1¤ôÙÇ(º5î[ßý4ú Nü|oɱ†J9¡Ü¼?S|nF¨+B7°Ü÷X9!ŽáMÜ]xCQNûs—²ŽI÷ºõPÔI ­5¢JK#ò†íŽ.š´gŽûº®Q áŸ¨Qè3aHíL–kQY èVݬ¢³®\p.SÁ—aÂwÍû„a++%¼ªç“%¼/ÝÏ'#å4Òç <›&Ô“Y,a}uªÈ[§[¿Œ­ÄÔJ!j±b4·-ue ¨ªg#I:ÎÑdÛáþ­åO fŠCRPAKÏEѸì'Éöh>™V¡öhÙ;³Ú1ü‘»4*7í[RCsÃ.É…__#ÚIc—JJ\µ_ÐTìÞ]§=¡YÑìæ>B! þ'³HéeýÏ^®¯Ì¿Q„_ª„>£ü¶q†ˆ‹ô€â:´Xpk£ÀtÂD6ËŒ‹)à^» ¶#åîÄmßÒÅ­dfg®YpTÕòá+ú'&Fý´TĤ ø¨Pü ÞA#ªNØs:E²µ³fKºÚ/È5wß|`Š„õb¸üQt>¸¢L4©PþËc…ÁµEò ™ÃðéúÁJ—Ʋ8œs-e€TêN¹x_£ŽzjîO8åW¼Ç[ü„ØRû>‹…ÓŒcø¤§ÆéàëE±p-•x~òœYq§•,”0ðSÓ pÒÛcŽIúëà·°„Á`º ß; ± g÷ˆå&œu¹VX”@X˜ ì0Z¸ù]·h½LÌ2Ôkè¸ sÊ[‡ˆóŒXÀ÷ò§æ=õM=Îj­4øµÇƒž Ǫýؽƒ»D}¬³dTI|úþk}Ão–¤³~`HYÖ¶8ì´%*º¢Ð-:ã1'ÅX‡µ[Ÿ/É’ûÑ2(î·çÕ†eÌZ¬Z³tËGˬGeQ÷R{eÌ o¥¨wLÄ«e·H¾.[›˜s×FÐWÂg”DÜ»÷œÈ–Š oŸƒ©Tÿ€—-]ÝŽ¬Z4n†5Í:ý8›œ]£†Lf§évC_ε¢Ï‹«8üY‘’æªNY`hÜâiê¯âGý°»AU qíh± iõC/²ÒKP7T›½HìÃ";7}UÉDš¤Žž•ù›‹S$LšŸ¼a¢з×Õ%×¹=%¯R(RpÁ#;=»Ì›Íå»E£ùÍÖOjNëA Ÿ‰9ô©”†0÷¾Þ‚ˆÑR Ð=¸K—ס²–›“Q·Æ ù‘1‚v‡&/[>ô»°ÍÃOŠp”%¦ç›ãÒÄ©ºþ¡K èõ´v4¦ÔæÔ¯ö›Îµ/àÑ ¤r|7¯á‹×P3õ›WZúí%ù …l·ß‘$ô§Å Òð(a§’}ç©U+òm¾âtŠ"æ¿<2äÌ.Ððg/‘'ãUÜ^~¢A@=‡§íû´®Î)–ÍÀŽ>Ñ^QƒùQZ‘»º-&ÔaT‰NfWóøÓ¶#ß`´ªç1°#ZÄQžh ü‚ÄSñ/€B'[ßà—x)V—§E’ 1(BÚ&áëb)±?#²©¼Ü(iÈîqÏ¿£Ð 6é9ï‹ëc.æ) ñW©.ï…ažyK߃­å“l wÈîP±Ffnf™R; £Ö¡á+Ö»°‘­±n”Ýbª4È.\ápG½yrI-lGP¿Eܘ¥¼±ä&yœ›Ÿî©ÙÞ3”:á{©b•/‘ó[Jr´Q‚&a±{_ô …ª[Òë .~`²ð9B:?ÅS} AHü.çÎÇ~ë"è'8€B „Á½0à§ñ*‹Òƒ¥¡tù¾·Š|]ˆ÷@FŠNüÌf4+F‡Á¢øƒZmäÊ¡ZÁ)ßâ‚þ@Èz5ñ㊢u.oý«Ÿ[ËÏM·²X¾¿MµÜ6þYÓZ3Ü&æœéAÞá Ýõñ×õcÛë–± JÎz;Ï^a}¾Oh×Óù*°1S΀Ž/Œ§„,)b½ßª"žÂÀnçÔlͯ0z;£¶);"S˜¬Ò^-À…í+#¨äKyný#©íìWnPQ,%*[6&„ƒE,±€þ¯+¡\mžé8¾ux£n¿†(“< "Üìj:ÍÙØ >Uq¯ÁÐ~ûÚŒž‰Tõ*‚]ÅÊÊyC×RÊœ\ð¼\óÐ;¦q×ê»yE^ ½#3•K°ÈÄ@soä*…Y)RUæ×s`gŽËƒvJ7úmò²º0دáµTSúŽ8þõo¦£¨Ìò_”+Á¦î;æühfžèi½6¬ÙÊ_^Ýù=‹Bµ ‚n\Ëæ»ò={?ŠŒŒð@‘ÚxõÐÚÌîÚ§9D­©‹NI(78祈Àî·¨5Uò67OàuÇD~¾áÜ1ƒû$Õ¼÷ì{âÃÆš\ûýª\É„ýBtîSpèÔ¢% pO…uÄEÞÙWIÚ©¼Uðî¾ÔãÀ:ÖCᎡÀùgtç‰Bp Ö|Ï"6àjµªVx“#jlU·uNB³ê”†Òµ½äHAXÿ­û‰DpRž—xÇT@*ªmÊØ³?8Ãp¿ƒ"Ç\Y6¢uÔà þ: ‘\ª y}N[ó³b-Š>ƒ„êX3éy ý'fu¹Å²øSWM6´I'%Vꆂf³Æ ±Æ¡uÓØRÜqgµÔë„"Àj±ÊˆäàŽ)ÕÛe¸ Ki Ž£þ\0å7y{|á£\©‘ 7GÇãKiÎÉ„r¤õi6®ªíMá½qAΙí˯Po§q±>’e²cȳ-Ñu’CQÄeSBš`Ò^ä\ÔÀ²qOåØë-Ñ›/îÒA Kìâ_†ÞN4‘9#Z&3Ý>‘<‹‚”RõÀ™uÇåüÖ­\:¾öTw½n¹nI¡—…\iF\‰T>|]Ä{9tÏ“2€ÁiÈÀ”9¶Ërñ•L…½'øVó¢zUçäÆg!´Ù ×¶lž*Éæu›1[ä÷Qž·(oX@Dô–n½‰ÚÄ)ñußFEÚž cÔ˜PVØißÜQ]g¹„Ҟѯ“L"ß?Õ…`b¿u¼E#õÚ4u&ãüþæ FGOãÐkHM=QÏLrÌçx²…(3ø¬ølž¼zùMÔ%ï¡ýzvòÓÚÌÀPçÒÆXÛ÷açÞ}ÿ›ÓkŠCdtT¦ÕT‘æ"©qQ»«š¾ì´:£Rl N5ÁÙ”†„¤ä˜w½¤àMMUÄÆI>t€¸FÏ!löæilÁ’ƼyöûÖð‘=Ç +Ϊ?§ï:fõÍ2Pç—o¡«ü­kŠ–“.j¬þ9ri-:Ê·ïDŠ~óþ!©Ÿ$XÚQ¾íz§íÿ6n€òçJ[\Ûðë§.$;s@¶4JQ‡ƒ²ú`_4ÊÀS¬…Wä7¸¢þI`ö{¢«]i¿È ,Ì9N`Á‰£F}îö&Kóò0ÛN–‡“Ÿ° ÚQ¿LÍÎ3üþ–yÚÒ”%8Ì5 $Ï1!aÛn?ƒÜÃguñ¹ÒR±ºú%uŒ‚ž†yn‹}ý™€„MÊ3¡L>Äu–é“.ѽ»Þñ-çtÐyÚ!d™¸-ø—µ¦/<=¡9´¸éo Ëìø“ŠY?.4š^™‰²ÕòaŽ[ïü{BÛ»•Êiñ].V0ó8éËâו˩: uU¶¾*Ï'B~^'?Hšð­;h{&`×PZS{¨(z²†B6èyå`aó µvb„0[õg}D2Gg^ô¶×èÇ Û?Š´F¸¥“üÖBZ¾ÃrY¼·¾ñ@eég;]QïNMP¼+ì®m¬¯Cvp$\ÃÒéñ™,+$ÍDL_OáÉ>àD½Ò±Vóí¿¢î¥ ¡&jv=…ˆvÅܹNFsâìv¡ÞFÄ?R† á| ÖOé{➆= o.㟒MÖê¼-NÜ-% £ôÒC~ÜcµÑa&Nª~’à1l…ŒFFB„>«þRÈ ·—¦Òrf¯¿Õf\ÀðPL1/ïýþ€ôL–¿Á²1êG…‰â"E8{‚Ëó ËóН<­@†–‚±‡ðï¼ÕøÚÍÄû¼Q²êäu¯% ³$å.RŠ[ïKå ¯·„Óù0jœ{j=¿©{JZÐÏe…åÒvnÇp q;XÓ“Ü‘˜H¦²/·eØù~ô¸%…͵ǭ˘²þÖ8­ÖyIEo­(]Y@ö$úX·öm¯¶Ú­ü1‡ë`$ó“A¬€¶9Q\õ䦬u“lwƒÕ¶v«²ô¹ªqI¶ºîÏbP-ÄCÆê.IŽÝS¬’Ó$?Œ"ò4žæQ'RɶƒB\>¬ù¬uO÷oÎn_\–±f?V ²ÀÀ»»ßµJ«t¨B¯f,ä‚ýˆ®* DôC«î#ÐU±æìp’ñ癸q9NFL~ÞîM(ta}i„m-ÿŠ­b½‘·üÈwCÀ¤o‡ñÿøú9듌:¨x)‹ìs˜<Ç&׺’%úÜ¿…)ŽYëJB»ñª„2 F-Mr7l昈éÊÓ¸>Z 4þ6„Š~Øjõ‹Å‹,"ö]L¡áêí"ŸÏìfO{/ÅèxsÙˆÝ. 1vû/7uàY÷ÖDÜ7îbî¸à̘üì èCÜ=ü|ühÙ³#4&ã(¨ôFÄ…¬39¢6¯ƒÛ|Ø‚Šíä>›•EU:þ=¹!¸Äú. (At`-ðy æºô=é¬ÁêƒñioÍÎiSÍùVوܗŒÃ`XçìÁhúì>n½˜ê¡ÔOÞ#¤õ©aÜâØ[¼ßH¦Á f!ɶH9:ê†`VÓêª v -}4=Ç›E²=ÎZöt‡¢ãõÛNåì t9¹©GØqÙ¯?ó÷œ4­šRÜÞ¤s}°áØA@[¬fÎLØüÇ`­‰ðDý>Yìzô.éàí9sÓaÂöλžÂv³þ>Ã=“1c`uÔœ l´+ëë1Ñ7wXÄ«ˆ,uÓ®R­J u ‰óéùtS÷þ¾®º€Q;¾rOxS²åº)89ãXå¹^ÖL«r;ݯvZ'\»VùkME°µ’g81í×sÕñ€ Ǻ÷]·;Ú|óÂÿ% é<®ÅšºÖ!eqr!ëtŸõƒ´ÿRã A+pE\›¦Bäö[(Žy˜¼€˜ò 5¹ÏíÑÕ+OIáàdäüéÅÝõ?(C‘$À5›Ê—1èka|y¿RÈÍõA…uJPŽ…KÇÒ™œáV½Ñ«r”¹!E~ˆn/†^¸œsÊ6pLÚ7iÖË‘jXfuÔY•>d,h>¹Áx@ ïüãðøPOÊ·¾5–€^qXðÁ„lAé÷*ù]LŒyÙ7ù—ÝLY”§Â:#|ˆ¤™X¢¢\I÷¹KšO¢AlRN°:èmZ—gÜße@ri•àåbž ¤y¼Ø=ªM|Föó•ê"šR™Ke[¿vàO÷uQAþšÍ÷–*ødö…eˆg´ $ü$-.'…QtyÔÏÂp_¶ÖE­¬2n£®ê`(»UUàKíÊ‚mã'¥=w%j /€ÿ¼ÒÿZ5œÀYª ’³ûʨa‘Y´ô¢Ž\ÿÅæCõøÃy3&œé°òq>5àW~Ð$÷!Š©yå—tKøßüåU¬òcCc.Ôm*±gX{êèý‚8ÒøAönKNXrÂù•,–š$±/å]QúTàCœ¢Ê̈ÇÀ°þËã mÍm*jL<1бxÃ2Æë{ß¿—î;Ô¥À«xûC†æÅâ~S—êßíÖc?ì[Ðð}œÌ•«­1ع>'/Ñ3,«aâ¹ÄÀB·ËÓy¿W ÂŒøcÕìùÁbðDí¡ÂzѤ G\ÇßdùÍhzÝñc#u:Æ¡ ɬϿÏÄ$«ò}™z!ÆsuãD`å¹€VØ Ç… U<|bª{ËJØVéL_Ò ™Â¨Ì(_±Â§áG±™“‹ûy¿´;.UÓa4Ua,œV¦&¤~z-mòÛ{ºœìñ]xzêîP*f…'Ìg-+>*G;ž?¨!|}•û“ ~‹V—=²þ[½¥´KAŽñBF*áRòU:hëÿßç¡€h¾v>òOØ}û¿]|£’xyR¥³™M<4p„xmµC…Á*È[¬¡)^÷Záüy1Âd5Joã*¾§;z[¿`Þ›')½µ$y¸Mƒ32¨’i]øàoÑà&¨äú÷ìkék9*ˆ â$…†ôº¦ÊïBGzD»I[Ó“nHæ3æ)`1t4PCñ9½TnÓ„Ü48Uâ˯b¼{Á‚Í£º/A1W)ÃÛ3;­d|õ÷Ö¬ endstream endobj 1001 0 obj << /Length1 2864 /Length2 21660 /Length3 0 /Length 23253 /Filter /FlateDecode >> stream xÚŒöPœY× ãw·‚»[p î.¡ÆÝÝ=¸Cp·Áƒ‡ ÁÝ!Xp'ÈíÌÌ;É|ÿ_uoQÕôÚºö>ë«¿\ ðuúoKI;{Ó_÷Ž‹trz"²‚åÅÎÅðf_PSÇ_ʰ0ÛÙ»€Sàñ|föNˆ¿N”› À"úËô7â°ˆýF<ñ߈À"ñ/b ð·›À"ù/âakô7GKÿ‹À.i ­íïTvËÛ߈À"óqXd#0[¹ßÌVþ7³UøÀl#09¥/˜òo&§ò¹¨þF`.j¿˜‹úoæ¢ñ¹hþF`.Z¿˜‹öoæ¢ó/âsÑýÀy¿÷ÂŽš€Åø¯…\ hë¾~¿ž«ÿ³r‚9Ášµt¶þ] jü‡4všXƒÀo>3—ßvŽí_ÔàÞ&ÿ".p1{°HÿíÉùËòç)þR/‹éÜò7s°8Y@ÿéÀÆî Ö3ÐÙâ·ˆ~å8º‚ŸÿNü+ÈÃÄhûGeð¼f¿!8ÇìÈù ZþÑŒC.Ž_Ðí71¶_†ßý¸~…Û»:ýÑ `þ‚7aîü³+¸ãï8Á²°ðt°Ùý¶ýÁˆ¼ «? øÐ­ÿ€à6@ðAü1;xÉ¿+sSíÀω?üàmØÿ&N¶ÿ<žÃo7¸˜ø7Ý4ÁÉöõ¿Šà³+ÏÒþáWã`ãêüG}°Åñ÷qþB® ç¿oÿ*‹ý—ÑÞdjlóŸ¾à×Ö¿Žÿ#Fî<ÿçûÇúß`¶_ øãüØÀËÿÍ œä ²µü¯š¹~Å€Üþ83.pgðkùßQÁ›v¶ùS«ll`V¿Û‚_m,.N ?$Þ®‹»ý à®@ðA»ýÁÌÜÿ-8Ûã.ïù/Ñë79p%/Óß­þóz0qu¤Ë_/pð]ûþë7ä2A\œ³7±ª i¿«%rgÚœ¦ÚÕJ§cò^têp}@…O¡«É ZwºMîA_Ù–¤½Y"{ò>úÜÞš¤ÒöÓçñ]‚êänâÂ7܉¢#Ñú~b&u‘ï>OŽ>šÖП!»d©ò]yQ• °îÜû¤=êû+–GÃævU¾×pË!=VL1ÅhDë–ÎPågÏâSÀ¹0‘¼¢Ç<ó@›¹¾™ÆÌx!“M`@ôýÃQì­»Á{?ëµZ¥ÎîÜMðš@Ÿúst’Ú[l?UoÞ»¬xÝi4m·clÓ6™ÍfŸÖkWQõÎéàšj‚Ÿ–Ÿ[æ}ôzëÛDÛRòD8Îì³Ùu™ žÏÆÎŒJ‰–/J6<õ\ªH|»_rë½öáiqê´éÃU-pRêÉìz¹ÂI së©Q# wÍcðÖôMVGV±[øP$I>wl™gÕ¹¬ª“¯x ÉÌœËzME¸lÓÛ`Ÿ]™|°èú>æljK`™BÕØ$¸_Ûš’+Ä@ô·>›Äõ†ï3,a eJVfÞgŽFe¤Áwu»GHtjöÛúÝï"ú·±+4*^Dk>æñfa!¼…‹½o† ßsÅ•þ¶É/±†¾)ûLVp©õ±çr¬óòÔ ‰õ s…¹š²¢M2–nŽR¼üét~,‘!_C/ö3©\+=¬Ï‰bPÈ‹wo$`)< bN’q ç§c;žP‡«ašÇQjJÿ3vïÁ±ÿAhd»%ò°§î°òµK Ìv®Ð˧…‡=R¶@5ÍZH߸Aþ’îµ à¥)«Eß¼·¿ÿ[¸Yv÷ãÑÜÔ‡0œPs®?è Ô¡SÄû`b">é ‹€h¿‰ã˺7j“ø(¡¦]•P²½sxò¤Žôﯻ¨ˆB·ß¸Ó°å9^*J¸6Eç g1K÷5¨Ùµ{èžž%âzMøÉœ­ö>Iኌ.lùÍpsô‰Û“ò´Eå6J¥w»Î«Em}CR·æ®µ½ÛǸÆVË .paw/I‰ùg?Qrm•+é¸ËçWóíÀåÀFãÇ‹¼Â€&ÜIø§0½ÙúOüìÍ$mä•ô—.Ø6d ;ë~^û ã¥¨þB¥¡ÞµmÙœèzÑ\ºœñôÊp½>¸¶*ìLÈ^Á'XÏÓ|®k‡ä³Õ\Û– ,êAÖöÖ2¬ø šT¦åu¼X)“.2/¢ô£…¯7ÉWÌÉT¡ñߨAW ¨~Ñ„8ÖØø!LnS£°X5ÉnŽ¥´¿ÌŒªÞÇ“„ÿÐä>‘äO'üºXüÕz^ª¦16á–õ‡œòkY*DÅîdúK”Åiâî’¢EŸ‰3½¤E/&cÕëû¨Ãe63þ›IÜS™Ü°zì‹ëßrãIÉt7Ü4®2·lÚ•}¨è4[PmÏZç+³I01©Ûˆ{U¸W²±½Îé!ïH Gë3`=cý }¼Uƒ b¸ûrFÒÄÒâx¬dn áñ†ÒÙÓŸêØ‘¥TÈ/é"<œH"/8‡œ´‰ÄíÌ‚'€12£œ) ‡ª©m·1mß°:á÷£Òs$üiA†MqùÓ¹ñôÔŸ9Ïœ¶µ=—Àç5ûD¹+D9%™`ó­+ãÐîä¼±æmƒ¯H©à|Ë’TØÌ™¦ºô¿«óãtÜÜ®F#Î<£±ÏýJpt4VUl×!?XQ ù›9õGX¬xâÝþ×þ>³·¶TPBêÖµ›¯œ\CkuD좚]ǵŒ¨„ ÑTxI®Ü¥9ÌIžÚ‘L‹áZVlFìÆ?³?!'il^^»vso¥‹Ï½§"ì×Q¿¦Q½Š$´š‚ȵŸc#Q¨°ó•Žc€8KâWznd5º ޛΎÝÅÀæl‰m¨”ED C~?:ôºR8[ûA4ÁßœWF%™àòÍš\ÚO7Ÿ7ÇÜð3Ò‹;".1ŽÚaÑB›Ãq2x©jiIµ¯ÜRF¾óø²5ðAÚTŠÖÈ-U@’qc¼JM5Hú‚Îù°ñÉ&áê7Î%M*ÁÑ7Ž#kzuä&Úêrƒœ^4n.Õ&½/´’ˆÊ’s8óÂèE W G‘auŸ+†$'£mL¾Uœ33/ß !‡÷DL_d ©t…S&Jô¨Þ=ýìe—ŽÚf-^Vkæ¨Å´˜òÌíiOŸîÀÀ|cne£›çDjáB7.ÌÁÏ^ì²x¾èIM$•AîþæÆ‘ìõ¸¶MŠYaÕ¿|S S”ÕîÁ8±ZØ­KGqœA6m`»«Ÿ›:ïõ?ãß ybR: ÝNÔBÛ_YÕ2«ï¤ A\‡ãïSWb„óîÎäz}êÏ–¶àë¡0Äûx Š^„åî£KnØÖé. œ7û4u2Üliû’ÃÉIÄb\­øòƒ†0ãZn¹‡c·ãüâàS`¥’Å„¬è`Ff}»a)&Ÿ[ît¼'=<Œ­KËt5¿©"åiZPa²ü4Ñw ªG^/yè£)y‡*dòÿˆÌFúó<¸À®¾ïyxjÕý¦XÖ ½„‰Æ¯k4ÏÃ* ]R9}-¸@ ko#œúÞ~”)fTj†ç¦Ù(&ØœÀ°)¨' û€ò¦¨tˆ¿Dé„@QRÏy¥¹ËÔFÛL.ÛØ¬Û驽ŽÐQFnPã5¿"2ÏÜP~ƒÌu 1Á—$!ßÀõÎiñíîÁGGó ÒR§½Ò ô}ó±eª¤÷€*ÓîÔn¼Ñ'“£þô‘Ö‰ü‚GÓUÚzþœ;ûS£ˆ‚Q…eãè0&»¢„ðƒ˜DÊÆâÈsêáiPYÚG´ýTc.S¬Iz%I®x”Oê«6n]|mDïè ïgF_;ˆÈ8"Ag¥mQˆE˜m_Rþ©ù>QÉ!dÐÅDܨu6o‹õCl_]@5/W•Ž(m?ÍAb›l&2a Vò´àˆ°¤Clì&У J¿æþ†îë;ÎE’N_9ü†FÓ9!C“5Í÷ܘ¬’º.ŒCOØXtU–7Ð €YýÇé\.;Œ"K^1®gúï!iv"d_$BI(¿µæ^cË\/ÿ0l±[ì"éTáÜåXSnT» qèÝlxKê}ÚtiÌÆ%Yî&ÇhŸî3uªó.~4ENÜfLš¹0`XhJèˆ_Fóú|m‡á sÀªúC£ºKî<š˜‘z6p逈¬VŸpàcüÊη6y±ÚÊ LJÙ:ÈÆ³îËçÞó<JÌ{’|îÆjP­Îýbð^ñ›s™C ä™ìægPEsØÜeèËcÆð&NédŸ/–´ÙPýE)Öí´ FÏÙ!Û8CíåH¾(‰3á*Š–o òá™s kzŒÒÂz6ô½,åHú“Ö~YráÅC÷UÌ½š“‰• INLìªÌ,&ë"ŒÇ†Zƒ  0ð…l’ÂîêïNX”TÇb²Uµ|ƒPÒãÄÄe<ê''5ÛJ܇m‹RË¢ÖÂñÖ$šƒ¨†[~÷‚RºÑWÚÈ’–¡e‚ˆ²Ë–´À•ë™À[OÄ‚Ü:§Ùº]SzµXú¹÷"0(ÞPÊ—ŒRY™è{lKÜã©_*¡m¯ŸÕYrVâ+)7bÍY¤ÜÙ3:¼>NÁÍ@ì•nPT.V IdÄœÏwL>jø¬Ž~Ô53'´Í¦•v?»f&€§Ä#ÂK„t#×>^ò:®×„õ&0e÷J#~¾Ëeh-w¦B!QC„¯FPGSïQÈÌ[;áa!m4íÝŠŸ¢r0ê)T¨¼û^—i@@º¾iÆ‘åV•N»iX w³]Û©Ç£º¾ïmË­ŸÂ6¨T÷ y\yǾ28cýtE}4…t ú$Í3Ÿ[,“zÝÁªbö…¥5á!ê'Áú釹ږ{l’Ô7˜¹x;œþki«øð[:?ë”ÌÑEÑ÷¥ËªBâÄ­ë †¾a¦òb®-´îéCýÔ€YiYz´Ó™NµVì}qû®bKÅè9E‘ôè#ìô[³š¾Õû`öµÚ¢Ë9§|žIØ0*â,¨É1Îbž÷Ǽ_›C>…pYûÍò?wdK¸;PT X׊Â<|D7RSÕoÒAýÄ<宸÷$þ)Áz׫ÒoÍõ-å-/ê„"O=À mEÉ\`?‰UÁŒÐ{!ñ§ BRL°šû[;_‰O¬ÇðGWž×;@³¢à€²,QaÉ›XfUô\1TÈuØÝÀ4X“ ¥‹2†Ï$¯œ&Ã#㫉ìâŸö¸ŒFS 76YfÎ ¸„ ùFÎЄT²ç¥u-ძÖo³ÌÓ½æߡ e°Î¼¢ýÚàªÕ1]ìåóA}´a[SFa»ÆŒ~½0„»~Ôd¯zÉðMZ–*ט“{5ý®ÚB\Äýe*[fA ²e¸ðNA¬˜YhAö‰j ¼¥÷Î[ÊN $ÚPÈ<"ó~¿vDÞN¦¹ØùÃÐŽ1l‘;Zßð#¿ãªgÁ©#)¤e…(üdtê0‘oäíýLó!+Â9ò‡!3ñ+Þ›“7.ó‰|Š™‹_F×mdÞ’ä­:g÷ ž:ƒÐjG·Faðnü‹ØdÇ+Êécæk»Êåõ2šûbœéM̯Eül­ÍÜÊÄyWG±BÂPPøÔtEâ 1‚G KCò,yš+Ù›R‚Tä+ëyꊺQšqMEöèT ¾¼X/éÙ†:Sþð(Lce„qÿ.lïUñ¡yå•Ì–«¢Ø[4šõg±xýšZ8ÑäÚÜ3 Lí¶K_ç;ϱìÌcÚe_>¶ÈãÖîçÅôˆ>¸[WØÈïWx{µÎƒ…Ò(žúExâ²ytÔëݶ ‘TD0Ûy£]ð™ú0¢]_¾^ð8ˆWåÊ—bËŠ}f½¾Á¸þ êw_hûÂ-ûÁMy‹Kºæq{WŸ ­ÎÌ€*NÉ%Ð?îóî6¾Y»¨5üV>¦Ðð\nèf#™o“HÄ»‰æºíØòK-lê½2:XÊûñù€ÚÌ蹟 ùx¯‡ãÙ¿[¾Ë(Ëörƒ95"6?40aØœŒn i€¥¹o¬ÞU býÜv›?¯?6ô g?@¶|{iÛª‰XÎX¬®×~ W¸8 9¥éwŠ]ê\ldÈc>py×8ÅHPÒ£L·tù­4lj~c“S+Ôaþu±†7 StSÙdX$Ñ% 7:ŒÐq)/£h¤4êã¸iš›¿¶9Îq@=ÝÛúzóåÒgJAõ¡™É(šh£¹\€û»ÂƒOn¯¹ßEÀ­ÀµBï“Í­}ûâ ÜL 9a†$Ú÷¤æ–/s! ÑþW¦KõÚ6ØqÚ®dØ9ÒHŸIÙ @Qv#éAóówë–ªËÚ¼ŸE÷Ó$íÔ0SôUqòáò<Ó$§7Ñ?ô@gôYM<ªó±áŸ*'•:Õ4-^¨ûôMº²fxmh)D©í ÖÆ'A_ÚA®OY¸ÿðÜó 4øÓ7{G&Z8'•½`ÝÀb¬½½_ç&³zû}ª :_s ó2RâÓÌáåOë;çÔ ¡¦L£Ð„\`L¹r-­Ÿ•ruXËаb£´–MŠ|à¤0TFvøNãÙ}É ÌjB9õ—( ×kêRQȰ×èÑA13T±|&úÊÈÒ´kÈý[÷O×a›?`‡»¿`§L¡Cx…ÂGç¦1P$íµ`/µWhn½ÊH¼^"hŒa“^ʽ}ëµ¥ƒÖ~ ^76U9 éÏÔë  WùE¼¾.Ï‘1šÏdg :íí%þ :¼UØS©UmŽù;Æ:¥Ñ£Å aÀ:!Ëš]ôƒÐ.5q°aÝê>ª×¤ FäA*ݹ•èjG¸±˜²é›šíbéXÆir´Þ|·Ù]Û$Yò„Oôoª?±¨ÕA õ@ *Œòùj“è-«rl>ˆ²3(›Ql¹AHq#H^'ê2£åOë**I‘l÷ì‘YàãDúažÉí qM½g梕Û|À™b€ fàlóœ)ÃYƒÍŽý&6{¢§CÖÒž|PEÂdôˆ™œp>–@^\ÊäS~­ª©àÄ`úÃ*æ¶Ò½D˜Ûú1昖ŠÙˆùæÅ¥; Ñÿ|È?"gÿ¦!ÎŽm×€fç5¹ RÍÞ ´»·ÝÁ^Sª…z^ ÃwïqWr¥W¼Cµ†ð0‰ÊÎxÑ,œùÂWõ¶Ç‘·–}¸hƒã¼`üâbÞöÃUA0s Z&Þ5ZGT‚~ߤAw¶±Öz>yâZ±Ã"°÷„5Ñ,®Ý&nÕ®mQR"¹Á~_܉ÿ¼ö’cwæ‡ :Œ`áDÂ>öÖh¶V#4.¯7i‚­¸ÆB³@³ŠË3Ñv¶^u”îz&†Õ@fƒ´ 'ÙÐwñ78º ‰…<û݉PçË9^ȉ·•ÙË0# WoÓö?Ÿåíq@gX¶}ô íuà= ${qÄžjÅj””D}ƒÚâΑ ô5c?w&…„¬¤†›?…>#¦å¤U<9·‡6}ƒh¹@ˆJ‚ï|ԌϕÕñókQŸ½Ý˜ñë µj·c‹Ç¯L¼žc_ã?m4=Ÿ žY:/wG“9Ñf³ œ‚Ð xi4#>?èFʳòðfÈã  ÒF$‡+,RT|IJ j•·Òoè²Ëø_¯ [ëÒ™t/ãtèGÛ©Z”Öñ–|»¹‰ LJ‹q=ÝGá«/œà¾63Å9v¥´Ãsh #P®Çö«:”Ô ‘´žNÓW¶º‹ö£|ÅŠ8xYû9F=Ÿk‘wC÷‚Æ;ëμ†UÊN™jñ5P‰Þb€ê©h»Ø–Pn±N¥U~v*B(ÛiÕZ“3BäV¨žÒ‚Â0Æ¡ŽJ ‘YÍ´Y£úà@¥yŠæ'îñßÂÏÌôÚž^ê-ÂÂô¸4 O,6ÊÏc»@0Å] Gß\˜×kÁódÈç­íÖÀ¿Š`¥Öä~¾'Ѐ2e–J¥–¾³9¼ïg¼SZ|BS?žp„g•J©<[ÞŸk¾Ú0E6U=éÚä>Ít^n9ïêQEo#軃ÜáŒl¹ˆ½&ž\`£A¯¦ûÝ}ÑöÕ%êlÍŽ–ªö%=¬›b¥aÛÚi7±CÄ^ÇVTÝ#Íjò lFãr+ÖÍêÍÅ7aôú̾²°ÍyAr ×JäA郀…1¹Bï›Y¿ÚfoãMù·ŠžM&Jh¹[¸öϯ?<¸Ô¥woKÂ+öÞ{„ùæEøb8ÐíñÍDV¿_¯æ$#4sÖiO&žÓñ(aŽxXnÇçáGü—Ý Ö7ãv4üeÅ×PŒEìïÞPNÂ¥Û¶iW§MÜ€+Í)#kQ9g¤ŽÿÑ1ÖòÅ­øüx«CÅÓ·pÕSCÊûä°¥¹]$7úb¾ ý­n¬«3p´Hñ@‘¹¬ß’êÝ` ÏcР!ª9Yo ¢k·}NCÔP’ Û4Oü»›oDèzw~õ‰ÎaÑNß_盢ac}ÑŒŒHUÒÓg°"|°¤(”¢;tú‚w‘ ¢§+n ~ø$¡ŸXݦ±CéÏöx¯Ê¹`q :Z xÄ:SK»DpŠN9·uF‰YDu>4zRÓ ¥–Ù\â¯Û“Se™mD“y Ò÷ñc‘§S¦óHÄKH’µg"dŽèÚŶZä$i‰¯Ó:~­–b×.×ó/t½å­ñÖ$÷ÈyY½çãqý‹#)¢ ¥J3ÓÔ‹ËŠ³ÖEÕ¨ÙsO@|‡p—‹ÑÎ,³W/‹¹ö°V¢ `˜Á°†ÂÔK½Ôš÷mI{}ØÔYѸW6E¢ŠIäPx±Ï¾Ó¨°inûv—”¦nÛç!賈/$Û1N.®›ç3Q3'iÜ×Çó€'X¸¸³\^üUe~d 2؈ƒ=ÓúÖF2k;±¯œÑ€_P’ÿš›yTÁéŒ]_eç2ï'I’ë2+9—Á× #,Ëp—/»ò´ìoær>JðB±E«6÷È›7oP*=HŠ—–Ió'T,¶&,*0x @ˆk@Çü`Éׯ3b¢ÛÍT÷1ù â—8‡ v,5z!²š{òÐ,›?Q°h1_ø*7QÓ”Aã7|íMú ® uûFn)«Ö:"½ÐÃ#¬#÷w~)ÿ†)êûÓ¤Ðî_TÀ€ * Šg|Ö°´„€½¯×ƒ2Ìw]çAD‰&aª•؉ÐüF½ëóZ„‚<µáòR®rÖa½­6H_2™è¾žäŒ¡ým+Èïlt‰ÁÆu²G—Ø·Ù™¢][ž»õóZÃ6"Uˆ‹ÐžþO›“Ö3á„§÷9‡˜Ê ËÑ6ç©NEˆÄ°ªý3ò›‚lý#Üd˱Ôµ¯Ÿ‚ÜÛÐøéˆûdöº[ÇuûɧNZÖÅëPñf+ñ+`Ôd€;Î ±ï!rß6çîâ]*”X„ûθ9©¶$ÖØ¤½¢!hTCŸpNÆRmü~+q RÆâÎ|7²d½X7‰OÃÎ;ñ8[•©‚BdžÝ‘¼¦m7ü>X=S0|ï“9¬?ðR¯&=pèi:äA“ë½¥ª2j޳]Å6zzpàèì‡Øyõamz›…Og¶^…ë׋”„ç0ª}§¾sçHR>&¾®”‚‚Oêe¥½ Gk_‰Uií/¾¥5ÂB+Rk¼[#交¾‘HVè4íaG­èK”ÝÇ‚|ÄÈýJBíÅHe±ÿÍjAÐÕÁ JÏ"Uæm™C×ù4»äÇÐÔVGé7¥ì…¯ØÑSGE((»Ãw¿-o.—H—…ÄC^·˜JCôåD×’<'´Ýê¬)M¨©$cÄÔæ0F1uÏsƒÃ7^e'K:j8¡ØøXnAÙ"o>E¦±~TÊ/.iœ<åiæ¿!AxÖ¾nÊ4”f>øb (£:ðæ}‰æÔÇPS8µ_FKgWÌQ¶jÊõ£Ø“´‘ZY;''Üáù¢z`õå\Ë*í¶§HátIt?´Sµ_bŒ'¨$£‚$踊ë[‚LD!qü‘e1FÉ"Ð$I9m7Ú+VZ=m\‰DŒ?Z}ÇÉgÌ#?R‚b"cgW!ZþÖÚÕ~íŽ3±áòŒU‡ºw,–²Ð:Û/m;vÔRª¼ÆOLN¬ˆùé˜V­2+,×ÐT=eÎp¶ƒ¾¢ŒVHβÄ4=°šBÇ)ø7'´— (å– Ã]Â5©bžk´@ÒGeÛŽgöú&XmHò†}<á;fÊÍ* Í<3#_NeÍ ³µl÷÷ä M™"Šˆ±¢0¹Qû03ßi[Þˆë5'ŸÝµÒ¶Í\§èŸ!¦'õsc8X¿AÛË%̬øNpˆ9MüÊ._N=ƒ&óýãûºóסÖa'ð'R<ª-(3=ÃMÏ ]õÚybÛ’P€ƒÕðh4Zw()¿¼>G&“HšÏ• š“j‰K eg~çáëÝ.S(öž÷ÚÚ´ã‚øò8*ÉÌewõ}¬]Íýõì‘ziAŒbPçÎRív@Gù¶ªÊÅkÆ\iÀ¦!³¾µ+a©UýꂊùMw©+-œÆQk»'ÜØ¤}*Œ†ÿ u;näk¿I ×xó%‡UÕagEëì“ç éGÙ*ÚÝ{¾ô–¹D¸C0dꤑ¯Ÿ,€cÈyeN*¥‹õ‡€ÎDežÈi>­&4ZˌԹd‘ÑÛ¤ ±uý^B :æðæTÕRKAg¯ž&]¶™q‚ïφ~*ÒÖÞ:ïܵ}!uÁ[fk†´ÅLµî‚.•¡º1r&[‘{ ^;áÐ]Ò+¾ÀÜÀ£\yŒç¡XÿYWa¦ÏÄ^š¶T)9Ia«Ksî˜ì˜¢ï0Ž3&ò­õéüšn“Ûz`‚‘V .‰Á'þ2³kËÁNK 9¾Àgû‚È3‘%ïkÜýF’–æbhûÓ¾‡6(wýþOn9€!]C¥ðŽ´¢&YXcJ)CÈÞåésáWƒŽÅ€h¥â ™®Â$¡ y¿ÊãKkM7†¤¸ý†îŸ:.&wÊhO×Éx?w LÞm /§.«•(pPXf’¯N,Œ¼“ -ü0Õ•æCB Á‹[Eq—Ûâ„5“æ7ÇšÌâ±01‰‰H©?®0:Ôuȉ úÔ­3Ï”qƒÑŽ_¦¿½¬ƒoîÉÉÛ^+DF8Ð÷aQ$1 Gù4 ;›Í¦ðrKŽ¥“[raš)]»fq2ƒžD4Êácͦ¾xÞ†ÇÎPgÎü[2ß¡Û%† ©œ:¶'½Ž¾«W?|çÊ·ô¤Æ tq¥ïA¤MÄa#åWÅȶcQRW"ŸïDUg;{ëoágTNë¬Õ{å%œ•^¹g/²ŸÂä‚UæJm™Ì®»½ŠVåß ‰ý¸/F©Æ*eS Ò4pYÕªMäzX8_”»%*™-õßGóÜlšd–…ˆ¾¬ü¸€AvHm”îÇ'9eä&ËØ¸;;)æýç®—\Ož¶€—)œxÇÎ}ÅÃD>[±“éÙ­¶&ð¯h¾ã†5e¥ÓŒ1ÒdèçÙsûB>K˜M½Ý¼Ëªa¶o?·Ðï‰eÙü•"ùG®Vzj±–Ò˜d?æ\&¨f^ÁED|Ì­nyîÂ=æÈuAZd b6ó\|ÎmwXG‰”—w"Î7\Åh y—|<Ô8ZîF¥@;¼yd!—¨ÂoUãíäX.©šYzÀ.£1+2ÌSækr݉<¥§ñÍE ¢{× p[0k#ûゎ36í¡ä'nÐÉHêçAX˜h2#ÓZöî”ýÌ;¡FÛÎèyô£ Î û¢…À{(î7tZoµôáFjÊJ$Q¤çñ(…bØú¼M2ao*°ö¿&ôîàŠo룱Ë3C™ `HÒ)î=•ºÄ®ˆBö+°¢¾ŠÇÜ@˜éØ/ˆïû‘MºÚÄâQo¶®‘è„·þóýÓ»œ„ví‘´ÍR}#uÿûùí¾PÙGª©‘¯õÏž–ví–ë[ù„¾‚ÃPX‚óꦙ˜ý\ß5-v¦E¢½×Á‹üÈ—hŒW\›AÜèàI—™ð.¾ø€¢Kƒ]åÕÐ-3ˆqÎ#Àzè˜^ ´ñ‘Õkh½Ô£M®Ö†§Qt¼ÍbeäçÏD8â~‹›îRÂL8tÚ¡ç!<W!¥ðž±Öéå¶­Åþíµ­›à¹ÖN‡v!ã"l§†Dª¯óôX/Ú¦tÖ:ᎠƒØ% ô{NKnuBô÷ðÅÙæÉð_ÏUù—ûÛ?ÉLI DD&}sly°Š|¿©Y’ÆÈЉ R¬Å‰ï“&74QcÞ®æä ÂìdÔ×XÏÂ4 òYÔË}Ô¡”m3ZS¿Ë þð ]_Kd¼ùÃéå›1’ –Ü$å¦R‰:Eñkµ*ñªË;øòޤV<…¯=çsåF3Hò2o÷ó^~b"^–àâì†@?…+§&l‡ßvÔŠÅÐ*Èä^[žÚtî1>H² ëØìÚˆš@,s<& ù[wJ1 ˜@ª±¡fm¸•KUºZóÉž¼»=Í6{ñYT ‰Íl­*ù»U­Ž4õX^qÔÏ‹ï\ÇguI@au3gÎc‘ëqå:©Ú áE‡@ÎÁI7Ò12ùZ51ÁURöÖTç–‘Þä}áÚHö±ì1nljI‰=AÚvr}yºWáUø¤˜è8b$·÷’™D?'Ü’fŠò>S»ýâMÛ~Ö§ÈÚ©½WzÅ«O÷Ë¢Ühmñ‹Fµßq~ò›lŠIãnHñ4¶šS zd.·°‚ñ­f:gÌì²Õ®¼¬VÈÏØC¦òÃ(ô·—¶‰¶ZP<)6Õ÷ÝgµfM4½©”w`t~ƒXAËv~£ASŸ(îÒZRÍ­#6!êd(ßÊ?p2]Nv€Xi ß¾÷|½í®û¹”ó?|û$Å æØ°¥/€eq/w²²Rn;jVòÌIû—n¢@ K*O¸æÚ9( }EÄêkéíÕH„ϧYqýÕxqk:7 0ÎÂU¶CJ8ÔiV'@sbØCq[Û9ÉᮟÕÔgŽfü~†RˆuW†%Tà• ½gP¡ñ¨2Î}ÂÐv§W—~ÀP¾]Lﱇë–a;-Ä$z8x˜T©p*p‘[¤Òy[`+Ît+H,ÿÎ~f‡@dÄ6™Ž¶)L­OÛn2Þ•ØPz¸¨ÔÕn\Óruâtn/ûÆ•hgx5Åý@\|jñº®){eå©Ç’úòÓ+¦ÃQÊé=|cGXµwûêÔÞOVC2³Á2EPÞ;±P2Ø5Ô¯ˆýÂÞóÏ0.õ&žGQ}WäŸÂK›2•ͼø‡[ã)·’o‡Ù9ŽÌÛ÷pômqhˆ|Ì¡|‘5Ô|œ7 »‘¸WdPÞ‡ôvžV§­›Ç¶E*g¥¿í½ì>U ¢ÅPf¬Ñ±#´ý©KÚœ ¬QA üy¶prölµ%jq±çŵƒÑãzÿkËkXÎ}úQÛÁÉŸ²VÁoÃF³˜ÆÃæ ±ù@ù°…›¼î(¡]9Ö>y %2Ò&kóÁR“ >·N 5ÀŠDÍ©fy.–:;3ŠÝqöö²DN#Ë¥ï"”]ÀÊúS6ÁÉÓ©µŒ¹D—GEšÂ‚xv‘¿ž`YÑÆ¿&­§ŸÜ&…ÄŠÚ€e ôÜœ<íkª×ÞÑ•á<Ša>'MsÜȼ…SnÒ˜h°€>«”å…YCþ@°$èÄÚ¶ÍG˜•lº} €½•]×”3¯Û ,7wž ©[xØß ð*B$M°ª#£¢|}ªåE\ù!L±sÓŒ×v¿5Ø¢ (ó¿ë<—ÂÞFeþ<Ù7à»}(ò†=¬å+Ce… ìhZþ™‘^ä3žé'¬¬·^^ùð–Ü^HoÙ‘Öמ„”Ày;” Z›}( M¬½¾Ë¨R‰-0Ù~ ³§¯ËâËöb²o.Ü6ý”‹éÒ}ä7c„Zôó oX.Ø”ÝJ¿º-’ùkP“pd ÀzØó´+ #­x+פ 5óÜbÉúCÕ!’8–¨WÍ\6ˆ1ް‚1›—ÐßR!ÆFYGyi,_h–3ï”z>òšqbHº,بӦT«£©Ô!X˜‹Ò£×\±Ÿ£¼º~:µìvœŽïZM:0ÍÂv÷ËÓ‹K{¼fNOp""Õ—Ò ý(=Äi/P¶%€ÝAŒ"ƒ—HéûmtÜ2:¼ü¢Ç"Šð= Ï 5i‹‰¼SØnÐ_¦xÝh2ÞwmRŸ–8h›`V»Š!à”––û‰ènŠ6JUkﮚ͵¾^ô•‹—ˆ­n·tÓeÕª²\YÒ1s@ØëAwÙ´ÃÃw®vÉî6¢ÒSTEgñÓ®V;@>‘k‹-Mñ[Ay[W‚Ké¹L½œe7—ñ0÷Q½©ù¼Kx2?ã4å]v·æ­B@’çg4†å–›a”̪Aœ\öápD‡šWžÓ0M€Â¯¸ù2?R£ª{Ǿ¿šRÏuÀO1hàe-á­ ÒÕB.Åý¸1{5ÄYÄÊÑ%PîÃþ|¾ÚÏ·é¦b³ùAà+²Á¤û$Êí#áà;'_&]Ób˜°ƒ|¯á—ÅãøØ=ˆï®hÏÎû=¶?;[GQÂ0šíÅö,•4Çiˆ‰_#õ§s×4ð÷$×àˆ `§z¼‚ö»—y[|Ö=Á ú.Pü·“ÊdwÐøî Ówí˜þyyïpîVï0ß©käu7GR¦c4ññƒeCò¤º"Ï' mßï¤åYAŽGG[y)fÛ8‚ª°»3¸^¾ZÊ>¸rTxÏÇöر S°üz|Le›>Ý_Q“B¨È›ºYR¯n22˜I‰¦•Q7¬˜s^üµµ¦sŽÚô°”yiÛ†g&cji0NÑßµ­Àæ_Énj´#=ãQÉÃõuzŽÛ–:o]ù¹f>Jw? %]Ö?ÀÞÀÙ¯6s!˜ˆž¾‡If{Ÿhgç,FºÙ5&=])ûá*ïöRK¥™sá볫\›ª6æ²<"¶ÈŽÙMï³_nx~Á58ekDx÷ƒj¨Ñx³N8de¼WhܘµpÐ2Ööˆlñjò‰WÎà¸+û(ö«×t¹ÐGš7P廂ƒº¥ûÇßÞ† ¹Þ¯jfÜBæeÏ R¾‡Ö}$\’塀ö·0²µR¥f_k謣¦½ñ'ª_ijÁä$ÌsM-®o$JhÛ±ºLG•#§|`+‘Å3k‘‰.¡!Õ÷lQuë„Ï~™xó »ä*„¿™;P´ï½mfL”›Ñ]:©Ôç-OwfB^Ü »+–¡™ÙP•2ûÊ’œ½9FëG³uMƒõÛ•D”žv\¦¾†¥‘Qµ94Á» ¦ôV]¾Ï@(tC4WËÞf®¬GŒ.pu*ÚŸ¸,ámowƒ°HŒäÜa­Â5"¿^C@oÃxr…p U<(bšf€”N]à¬Ð 23X¢ÕÍjcÕ¢R5´åÝzÜîœ\½Jœ–p‚è©`W¨ÖKìHÁd3%A„5¨  ì^×Ⱦq·ÏÒTýŽG5ܵN½27ðªÄŠ}  ér &á>î1”Ù¡Jð;äùö-;Ô³°Hp½âM4QARyË/ʽݺ^ƒ¹ÙƒöÙ1âŒc/òÂÈ쾜8¼véu<]½K~tw‹?€û â •ïÚŒY»1òÏÛ€™ìsO¶ýUâCË}-C¨çk·/©ï±,VëbI³Ë¡jm„€$m%r‹ˆÀ˜è)ÏÂ¥ŒŸÝëU›Ìe~ß]ïÕ+•‚NΫ­”PqoÉOÂ-jOmVpEC„&«È!à_O)E+C±ˆ6°Æí²î*¾+M'킇XRfÖq8Ù{žÀj’S¾'š][~‚$ÁáåÂÜÉkRÉ k¹½’Jk:fá;~EéGžAH5øåÒÿå7…euÞâ‹pùžƒF† ~ÒÍHî¬ÜÔþ¤ŽyLA¸Ù-Û³ãØLhó1¡^b:áî ÚõÄOx“ >Ÿ ÙÄuöad‡H÷zK‡»Ä_º¼~T|™”šSéêÕÞ7Ã+ú¬»9‚a2ü˜Ø?© Ú…ÛÝ7»¯ð*ìtÞk·K9êÅ&‘M'Õ¬3’â´ó:ó{˜)Òyé»õð»dЦ7wp»Lޤ¹<çD¥™¼³t œ¨ï+Ó×*£—Ó,‡0‡47ãâ}µãÛ5gN±ÛzX)e'üÎN·{t1yÿ@v¥ûcd›wôè1èâ-¢„-€€’bul¥ÕO!Û‹ì*"^õtËaýD0‹$§æÆÉ,d/ÃêMª:/Ú³…}naï0È0ñGôQ‡l\%—NÒšêY×{±qÞÐDx2u˜°6)Ÿ„FGv:ÙDLÓ&W¯‘¢ –L%g<Ø ¹Â?i¨X›ôû}$:ÿXµîónâmÂNTü¨¿òo5¡.‘m¿|É<û-¦ºu‘OOȘ¦=«„1•7’þ5‹2 JVä¯,p éHýiîï„ÒÉß¹ –ÖÉݤš“ÝH/ÏTª¬ŒC(%Åï,:L ŠÖRz7“Ö•¨Òí…¹‰U˹ÏF¼«ÿ3³|ŠœcÐ;ñ¥zNC¦˜Ý z7«…ñÍðæ €«àV»Æý4UÜ3›Dó!Ea' lÒª­ ‹CŸ„Ä.ôœ¶ý._{2›ѽÉ2•#z¶Ô<‘2ÁR +%//éû‘÷'ËÍ1µ†é£ÐÍë4E£Mi‘¦B4ïÐÄ0ÞdDP9æÔ¶°:‰Óºå9¬ú¥*£ŸQ˜ á‰îH0Æ`³‹0yè©U8¤šm‘éÃyÞV6I<Ø¢MuŽ×8¥p¾¢ÈÓô/è-WÉôù¯«±ƒ¾¹‰®MÁ;é³jÐÏú:²Û3ˇ—µ,)<R.‹çi/»Ç[ª»3>ÆÖtu‘âm—ÝY¹-¡Yŵ†’ì#è¡RÐZf3ÑÎa²‚„¯wØI™X¡¿‹ÿÞÎ%àK‘©«äø8%CŸPÿ£…iÉTË‘Н†É‘Ú¥™hoø:¢‡5­l"èÙôµ%gÄ@Õ\ûw‚ÉBÛ4f“IìÒx|x Ø\k߯ï:¬»=d+’YЋ¿®é³-_j…¥ ¶èŽZ‰ðÏÆ±D6£¢yá+2ž•š (û”¹ÕŠ4vHü+\I‚Gâ¥@Ð@–if®Ì]Stž‘ç·=é§ÂãLöÅ ?¿WØ‚´AœB­¾¾#°'3«³4RQkÒC7Rç‚Ö™oqŸÍBû±,$³œû)ûýK÷–0MÅél!·úûÏbI¨ëÊ+;€ùwâýflœj$õ.ìª75Š» ‘žD™ƒÙÇÏ¡?A§›+LsñDõdöúz­? HßûM¼‚›Ã /Ù//ã(uQ™Ó÷mÙÍë¿qÌAÈaØtUÔRÓÆP뼟!íUb‹3;œ^…®<Ò“ˆ ›a‚U¹ l'¥:†eñš9XmÑHWÅT£Þ®Lž.vƒ!ÇCs™WèÅ m¥ÛN¡´U¾ð,ú=ý”Ÿù–jb¡õî6BÏ«¦x“u“7ZÇ&QY¾GÚ~9$­'3J&¤WR J§ú •Z\I+³YìR; Á•R¦Œ³©õŒdóúÍp}#¨x•zl¡«ív‚=½í(a¯~MA_nðP ¦ñ*"UÝ#{|“uuöçr‚©nóðJ·fGED<÷¹É—êàŠdr É„U˜ˆÇêŒîÛ2ZÑ­¦/L´®8NìΕ¦ó¤£.žàIJo5ûà)íf3|¾>S¨îrYB)è”yŽ5\†N üÜ{gÐ`ü0¬kZyã„$ ‘^§Ïß8)|ˆQ¡ÒLYÏ_ê„¿1.áÈã¬LT˜€u×é2@‡¢#’(Дqy [ìeêeõLðê&¼ÄfŸÏ¼4úfœ(è©’\Á"rkØeðQ„xsT¸/ 1ìögý ÊJ¾ŒÃJ¸D¼ºhpÅ¥±Ÿ¦\ÌÓÂK·]AP’›P‚‘mÿ!Ô)²ÎͺO¦L6×cÊÓ{YÕ·d¥ÁVg%¹ÐIô…œ._]R¬l|OV—¼¸L‘!}Á¢»çuøßqëÃ<­ÄÎÝA±–ûÒç ä]ùßçGLà@ªq7[ºFËF4ÂIq`΄†øè ‘|5Ïp§KÅ4u‰gÓf7Þ¿>z•5×ÓZ;„ó*w¡êr¼FÜ*8˜3/Q"†ÀLvg؈Hú¶œ2ûµ’@†éî]ÃÕö$ö°®c±bJ ›°í3}'ÁˆóÿÞ!çúnÕ’/§2D„c€šæ‹x óoðáOïõj [Ž=˜É/O&.ÔR)öuö€Å˶XÓ\»Öåš{F#í© äõþ GJõ‡.C!^wCˆÑ¯FéÉÚÚÄ‰Ê±å• Üu÷»¢u YŒYmM-0òü`|j…2‡Ã¡š Ä6¬xW(mÆ ]]‹$7õX1°íþp]ËWe£MKåmâ,@슕2ó±6ïÌÀ£‡«Í6‘¬@Ù"Á–7²rmÆy-8Ìk'7t–<‰îÓjN¹yo…]#é6nn-I‡»-_d¿ªp¹I éÏ8­)…sçô °Êýk€øˆhÏËCñy)ͼe¾Ø–šîÔÓÅžå´üœR4©ë®úŒ š:áuMb§!X­Ò–«Š„®z=q6ã¬l?3 ÙÃø°„[—U¦ À1Þì¾õfú0˹ª?^‰}-— ;Và– ýÐ ÍžFÑÚÑ6âoöx𠇤¦¤u)ÜV+ï¾Ý®XÅ®ž-ò9”¦•K\{Ĺ,mÕŸLµQºIÂùãךÆ<)K[set 4L´Íáñ~:J¡ÎôS#¤©W™1\ÇDJƒÃ*×ý´+$W’ïD0°kÚÒûkF·ÐÒçEZÜ„ºëG[Û±d_ˆ…2¢~ìÐ~¢vŒƒžÄËÀ‚'±¶'¢ÆñÊ•ÇNYÚÔ˜ßÐËå9Öø€ƒW¨Î™ŒÖïôY†—åvrþ\[†z•e'ÿˆAÒq#Ý™¤‘câMs€ ­¸‡gq;R¶¹ÓyÍÿI4]tËmMî©7® | %¡Nû™›è(ÛT0j"Ù|K^íçÇ.Dœï¶!Îþjh˯æÀ¨B» PäD‡Ñ¢ØFÅ m´V[øŒp¬jŸo¶þ×èi³0^;-•”øŸ¤óÿ;¬Øè¶FÚÌš0oÞûYazPL }ín*¢?:`…Y[—¬˜ÿ¹qš/$èVÞjŒ/÷EP‰ú:šø}„©ì@f‚É€¯ÂlR΃q’°åV½';í®à{º dÊŠ~þ¢ ÀL6¬ÙÙ@h?G9èҋ؃1ŒÆŠi¡xõš˜Ã91IuùzS†s‹|šÞØØðþÛú{¿ ô´/QgÄÖáQ¬¥¸!;(pdÇv”™¿ü3¥`Ψ4ÄgA¾Ø7ó´Ù š~ჯÊç<-!œdx†ôƤô)Rp˜4sð;Ø~UD¯5z2Í2Ôë°‰iŽWE~eøä&Ž‚¬kºÛÒ»P×E•Œn¥ž/ÛÀA6.„€þYN©¶Žƒ ÍF4E#qLéÀûòÓ\ýì`Ä twpáIï*zÈÏKÌŽÂÅK[U3’Kžæ¼Z«Ð @.ŒÉ#“/ÿßhÐݸþ¦ ]Fô?b£YÇÂM8žèfÎkù.F;#kM¿yzQ 窎 N³¿}ïAÊ; ÖÄ·^ìÖXˆ±·/­Îì:±“¾'9lÆÒ0’eE*LaN6Ö_Ú¢|wä>@‘û17ÃÌïs]çdLÐïŒû–ð±ÿ„e(kÈ‘†ùv˜•È>bÏFüÔ ú*Eh$5Xn‰G eöõŸ8“NS»äFUÄDzî VéÔ¤ Ó53^×üeªºÓ΅ÄÌCÈޱyw?c=‘1%RmõR,…Ò ðÅBM¿çqâèJËèÜËC . ü)®Ìþl T˜Ëm˜œE†…YÓOÎäöÞ)Ÿ É3é½;éCý];šfÎ “Õ8Ïæ#zÁ¿6 E®¢ž=Å)‘M?_U:äÖsôž@oý¤1›¬L(äåðÝБxÀ8ré” Ò7¤“é/U2Äö ðã…K(“ª‡É²jÐi½# Ñgç8·7F9è7¬G³xÉ1÷Ì">¼+eÙ³GiŒ–U¸´›j;(…5£Ì¬Zj(aÉõݸè÷ß™Ù@ŽŠ¸YÕ„½ÌX¨ÑMârQ©‘Ë/æIÜ󽡢–ðh,é>V/1Õú/Ò²‹Q—_Ë*žY‹]Cú†Þò»øÝ2E}Tbß,ÓØê8o·4ä%#àdŸ¼ënËg­1$ŽâˆI›)§ÌGÇtpö”Œ´Ñ`´?(³Œ§ƒI·BÝZév÷…± ¯£Ì)¸ŽKàRÅ=Õ˜1*?\kÉ6ìœ+_aYoòí"8Ølæ ì›HkÐÙ ‚‡m&½Ò…` R©£zÕκŽŠEiñiDº¿¶î6€ø o-ÝžWªS#XìWW¯vj¢è‹8,œÑ°:3CàÏ3ƒ`T l‡7¿ÃS?lAqyþ•.1´ù~mh‰²¡´d}ÉDpÁ¸uÒÄgwS ÌLL¶Tpœ=hðŽNú^°z ç¢!½sq] 10R¾–Gñö(XIË“Öð‡üæEo½”k]´¿¢Ú4}ËT‚ʦ”ÇFïk²¡?ï oxšü‡›ôõÜcB‚£|`x*…ËRþY©Çn;fjlò—Çc©\#žKu¤V" ¦¨ñÉ:3þX^!O42ƒ‚)Z¦~äÇ6¾Uë»ñƒ&S'*}V„š“ ^Õá-Çk\ ç\ðžìÃÙ^BtÇîÀkÜ$ĉÈ"~ëƒökènú&ê^«ñqÇÁ½šn,À£9;)À?EËó4a:¦™ Xäk|tµ„ ¡ÈEC»—/¯°8prø‚KåO•@F sülUw·ÊZEæka~PAêæeGáX§U*mÕðêÐìeWí* ]ά°Ä.ËDºš;í 3Ñâ_ü®AÚŽç¬ø}(ÈË&Nœ™Ë\âèøºÉ‘Mï¹ÍyÙGþ)ìëh VB˜˜õ“rC™çÝHñ\ŽB}xù3уþÕýÏ]ΫQÌA¸¸Y²Çå´ü=;¡áˆ› Ê%þ¼­H¹‰#óѧö <PøÙâç@¼Æ®–2¼j•VK©§ã¤Uóæ¯pn:që ä­Ðñ]<ë ºídÅâ4<óó€*¯h뉵±1¼Õêü'¿2:Í›ìmÚ –ŸÒÚx‘ÙÁÌÆ:ìs”{‹¾N&ðØeÍb›ŸÚÙ¤º¾à’vzØ2Ùݱ-¨”MH{¿‘Z7 ¹Wòu«4ïø6ê'ϰ"©Dï!V™‚æѼö°Ÿah~û&8…¹ ‡‘´ñu,'ù_9ÈcFÒ“NìY(Iˆ|ÁÇ“¶¤BJ`|´8††ï·[ˆKmíé&ÿ(üW¶,E9|Ì𳠑*^@,8òN<Žä Î~a°6ÖjÚ“ñ "ËÅ3&NF#ÌׯîfÚÖ»ÅÐIRú)[Ô€æ¥× %‚4&f#“›¡\~’³Ä"¦*8Ý; Ӟ჉ÓB¼ü=s!A¹àÌ?6K™, 5 Ë$ðO>Ÿú=æ©?v|#ƒƒd*-W¡ÔŠŠ"òÿ† øõ›öçUCš½“_HÎÍHŸÁrÕ¢YÛK¬]ªp`Æ/0¡%kPç‰Õœ˜¦úÑþòmO°^凭p/àù¯±äшyxmm×DíhÏn°#…éѸå=窛:µX1ŸXË£'UàZ°z²‹zøŒÖ4¥_ÇAË®ì€s>ÊüÞ%pGZÓ ¸Ô*µÒ„¹-8¥âœä1Ï}¼<3ù°º’Ðah|œÎ?]aãDËqMͱ"Î>æžn^dz©Ø^©Fö6õ~¿iÛç _êùgTR3ª^ïmè'>°mãEƒ\ËZdõƳˆš¢ò7¹·ùýÎÚqÜf†e ”@ŽL~¯¼™üéRN Ðc“U„ïw–xÅÈÞûH`ǘ$}ÇA c¶'Óg¸ŒÅ¼Ð§¡÷‘˜Ç„÷—p]Ó.KgÃ(';TÃoèá‹.ô6„&•Òˆ¢%è0ê÷Oü¶ÖžOÅë†Ë-ÇЩIjº|+ïs¥0Þ7¸–5ŠíÒ¶¦!ù­6ÆeŽÚ$¡?^–CP”Öë„ceyV‚F?S½w:764îe}?ÝMÁwÈÎ[t®fƒ®‚“•ð–Ϥ²â›‰ÎD™™SO(R.Æ+M}Tn¦ÕÞ ‡ªï¥7ÎD¤XÅõï®Cd~]³^{t!¬üMª˜xÕöŽŽ®Ž‘Ìy¿ü|•ª¥ÓÒ@ç’I¿Rß;ö ;üôcð—žy äšÑÌš¥@`ŒŸgýN¾…žF/Û%Jí—²»O÷ôêαö]“ÉMšÍ#pIå»ú&ÒÐoøvŽ[^øgònÝV˜ I'],Ši7Hbø$;CW#V©ÔAʸ[‘°;»µá券=ù»÷Í7É`])â²C¸|ǽ º.J|í%QWТÉÚ)¯röÞ; {F¤`˜‚6¸Ñª ·b ø5=È¥ñc~Öiúl’è=sa{±È<|Þ奌îD}y]U@¥Ù ó‰Du¡çd—Öê ò¹PRSÍ`v'ø¾*ôjä¤Ée?I†¼áNmÛqÑ…Fqbÿæ!¨oß±ÝeLÐEƒ§øÓ†æÝŠ3š;]dðÊëxù–¨ïL›‹„hÐâ˜kx·ïK¼Ì´Vxur%KSöšD£2¯Eü±ÖÜ}[©=yæ”þ–æµløÁ˜Œ8»ÒYéD6¬`TLG$÷º9Ié׺õÌ“£À'"}nToe¶Û͈sYK[¾n éE³ÞY,', æÖ]¦|¦ä&§ ÌúcƒE–é™Éc›oï©Î‘!‰ JÉÊ0ìA„ÁY†Ö‹Û¢½;VYÈD‰"mž¡qêန¬ú˜jÖ4€„Q pòkf°² ­¦ Öùœ·ÊÖ¾‚TtúD´él¥ˆ]~³Â~¬Øîa¶«¹Š]CYæ>í¾Ðá ‘F§®rìtqÝÍïúwÒ/§÷å‰Ãi§ ’ä(gàÍÈe%(ë[f1­/s?µˆ£·èÇ1‚èW˜Ð‰A£îàvåýŒ=~…òÖ9 ÊFjU8²jCLœŽ¬4Z´ª™ mòÞ@%åvµ3nbâß$/¹UðÌTÃŒÁaÔŒè"õ¢ Ôê)¾a\=FG™BGi)°Ü <9ëuå¾ü8â´°tÞ ÖÇFø ·iÙ—½xº6òÍÅÉDumöQŒhÔÃ^msf'C@Ù×Oü+ ÖΧ{"±ÏþTŠ|…VÖïè¸ýÄÄPÞ5yPBLCŽí5°s3e Ò:R½îÅ®µÈšÆÕ¤²¶v—J÷•ŸS5;þÍ{fèIíx„Û‰/^ÊEVK¥N\±~QJüqh¡óW{R#ÌæJÊ©TaQ7<ýÆGOGš,Jú²Ì/°Èç“?WðÝ@3—1M=$JÙ’fþ%¬¨"®ÍÁ¾( BDÙØäE¿¬àúÈ*’—%ãËH0“»3½Õ„Ás©&+EªØ Ç×bô¢\ºBù݇–ÌÈ+£ûÑz8oéNs„uR^„9F|©ó8¹‰ oS|ÃCnÃÏÿeÃHºIõ¸9åvÀäàEÇ—Vè>s†B+70A­r¯l™íÕˆ©,#V¯s(X<I£yY_fá9ºCv‚´ä©1kÎ8Âb³nâæÁæ06V5óyTìÕÜ($w³øâ΢W *É|w®Àr>;!½wÎùÙ„l\q_Syþøò{C]³³´Ú“õuNÐcºg”zÝÒ¢ü&z‡ 7½ø˜eH%±•¯c®ýé=¡?H:kBSýuú²”éy/Íü÷WËéUÈÕ*½|ÝúHó¹øCTU†&]ÿÜ…ää}m÷Èo®*]ÖJrŸÊ÷fHº«ƒÈ(»¡’=„A‡òíš@ŠyÜ%žf/ªKmŒ=”½*ôÒW“æh(I)ý“ $â·ÑjôòUEg„üßÏtæhšK§¾µO~6%l¿HIšo¸¨ˆóÓx–¤çü%Àͱò{tëàZ2“ŒüÂ1q ¤ Õ^êkšÍ¹OˆÔhh–ûÊ~@ œø¬˜µõÄÇÂ<‘© Q%Húç<Û> ¬JÔ|ªàJÒÍübVñ¤pYäc“l¿LîâÉñŸe ¦½hŽAå‡-Ðr6>Yª›ƒÉ."¸!sá2˜V—Ó¨ ¸Ì×ÔxŸÃESÌé@†ÐΗñóåƒ,œ_™¾£Jk0oMÔX¿jOÌYƒÌí·MÛ’¶¹Yw¸[ *ch¸¤,°Ð",q«¨½~M¯DÜPTO æ(%dEn<'WV”ÖÝ|ä2q”œa†y¡\ä^Ç •àÈ0Y•×tMFfÉ“vûÞÝŽ"§óð'°Fr ­c¦&asôþF†­¸ž§vþc©ÿ¥ä¸™­p<ÀXS C‘(c4DÎeúË‘îzÌ×øã#œ ®ÎÆu¡ûafôŸü==¶jg´nÞàN™ÁÛ‚¬$[Ñ‚tËÉeÂo‡yª‡²—Iy»GÝÀo¬ÓöXØ®4pƒjƒ3¡\5û>“އGMŽ+H—>?„Ù´$3¯í› °sh4.ýç}ÿ«ˆ–¼ôÔòÙÑ5ž`²ÂYè Y#¹l£ˆ†¾Ó ‚;/Í(¶ endstream endobj 1003 0 obj << /Length1 1652 /Length2 8682 /Length3 0 /Length 9758 /Filter /FlateDecode >> stream xÚ¶T›é. E‹[q VÜ¡Xqw Z¤@$ÁÝÝJ‹‡âR(.Å¡¸{q+PŠ»Ë¥3sfæœÿ_ëÞ•µ’ïÙþìwï÷ =µ:MÂf–…AÙ¸Ø9…R*š\üNNvNNn4zz-ˆ³-ø/1½ØÑ ƒ ýË@Êlêü$“6u~²SAŠ.¶.×+!.~!NN7'§à aŽBiSWˆ9@… ƒ‚Ðè¥`öŽK+ç§4ÿy0‚˜\‚‚ü¬¸$ìÀŽ) bêl¶{Ê2µa ØÙã¿B0¾¶rv¶âàpssc7µsb‡9ZŠ2±Ü ÎVM°ØÑløM jjþ“;=@Ë âô§³pv3už¶êôäá5;ž’€ Ê5{0ôOcå? XõÀÅÎõw¸¿¼‚@ÿp6`vö¦PÔ`±Ôd•ÙÝY¦Pó߆¦¶N°'SWSˆ­©Ù“Á•›d%4¦Oÿ¢çr„Ø;;±;AlSäøæ©Ë2Ps)˜êì„ö»>iˆ#ôÔvŽ?OÖ sƒzý, Ps‹ß$Ì]ì9´¡°‚ô_&O"´d–`g'''¿ 컃¬8~‡×ò°ÿ¡äú-~bàãe³X<‘û@,ÀO?h^N¦®`€³£ ØÇëߊÿFh\\sÈ`¶„@Ñþ‰þ$[ü‰Ÿßâ0à|š=.çïÏßOFOãeƒÚzücþÇùrÈêÉËjȱüÉøo¤$ÌàÅÆÃ`ãæãòòøy>ÿåoþÿáþ‡TÝòWmœÿT€ZÀ‚RxêÝh¸þ5Œm à¿3¨ÂžF `ügò 9ù8AO_\ÿÏóÿ‡ËÿߨÿŽò›üÿ-HÖÅÖö5ãúÿÚÔbëñ—ÁÓ$»8?m… ìi7 ÿkª þs“UÀæ»ÿÕ*8›>m‡ÔÒöï6Bœd!î`suˆ3ÈêÏúÏ)<…·…@Áê0'Èï»ÀÆÅÉù?º§}Ù<Ý'NOgõ‡ ü´NÿR ‚™ÿÞ;n¾WSGGS4Χñâæãxq=-¨9ØýÉp°CaÎO.€'z> ˜#Úïåp¨ýý^8tþF‚³Г%èoÄËû„žvÒôo ×ÓÌr€ÿ†|< ˆ+ø_z>äÈÅ à€þ >yÃþ ÿ”ìé"ý?fÿ4-0óy<•àø/øÞé_ðÉÃùŸjž¢;[9‚ÿUßSzg·e|"ë vüSð_-¹8:>]=,ÁSÿÿƒÿ¸çÀ`w0mn¶® n¾ª scÛ™¤ßÔMfbóšslq¹ÁBId*O\q¼HìïÄYü!Ãx.>Ouïµûµ%¬1^£éÖûîm¬æøfÚìaÏhÞ®Du7Åsr6-ñ-ï{o„¯ðmŠôŸ\°Ôsð¯ÜºäÜ«»K†Bg65¶Ê_)¡ß•L°½ÓŽ6 (œ¢Ï6˘&¦Avf£@eÆ;rÇž:¿˜ÄË}¤RŒeAóÙ{Ç“ïõf•;æzÚs©T‹Û©„Žä 1Â9ÞÐøK/ÉíŠD߽Р¢pعsî3Œö"Ðf©7ý¿yY(u Hï]¬F¾t‡¶ n]úû £yÊ6KÕ Fmé†è˹wˆ4ÚiÃúqÙAÏpÞ\´y_M»ì+ަBÌü1‡8[—¿FƼpL"@cÒy“YòÁ‡ÕÅ8›×Ñzd™#ÓáøM VRWkgE}R,Qn>çÒ‚z +öRZÇV’¨IÔ[Ô“æ&¼wÂXv¯¯¢gdµTÖoGuò‹T䟭Ñn|÷x#×’:Ž¦ÖªÐ[Kºô±´qÌÇ#ÚÃ$Œ=÷*»çð ¿½ Õ Ù¿&øØùò‡îôÎ9oÀö³ûºÕDó oX-…‚ÛG{̸יÒ3Gú<:DÛ®©½ã_î(ÙïBî`cKáÚUF*²ßêXïVvzu[£ƒŽYµª§©ÌzQM–Ù´,É^Ýà2šß+h ‰¿f*™¹Ë}` &oFÇ_ú×°dYšŽÌkÐÄ¿>²“óÏ`ò#Ÿ\«Æ&-í|+‡‚ßí^.¡0d—±Ü;™¨9ø™6¡îôSÁβ²¼9½ç`Þ]ø>%á¬Ý'‡Îòƒ¸ÅWUè,VÚºi1à+«~g:7¬"Ž¾Ù¸c„Naݧ²ï“ö‚œgÍW[–?)[Ô÷^œF£|N"E<‹¨Ê–¦mOc {Ðïóãc½"åú."¯±E\çØDû1 ðzïð|ÅP¢@8)FÃFФ+ă1-5"ÏyÑ>ϺA޾SÊcž§rªv„™žË˜[†EEæ8gLK/£â㌲yy'j4$ü°#Ǧòwû ‡%ã·Š!Ô²æM*Ôn¼øâ\Öó­‚Û§Y ñÛ­U¿²;ú×IïuËe[ŒB*FϺɮ_áŽG8¹Q&Èã©1 ª LÐ<«Ìv•Ä>ÿÒ½&ÊdQøjäc>þ>Br¾šòÐÍâI˜Á—·Nˆvv!—P ú¼Øñ+Î!6΃oÂóH2¥-}«TñvŽGÕ)WZ8Ýè‡ñ»®p"Q›œíjo‘³¼lØÛ÷½K.žž‡Ô(³-$Xë™BY~-C{LÈ)p¹ „Õï¤ëyҎŽåCH'ÈÇœl:´Å33ù-xì U¤P±Fe¨ m±K*ÙÞŒØíJÉs‰“ɪ‰¢£Ÿj1UÖLp~œŸ¯ÔœÁÇXû½#*vZN¢åâ ;67¿¿)±È­PW_«s¹'è‡ÿ3õ‰÷ÔˆU 3ëøý¬ ¶ž•ßg?}>®Uê>Ù2¿5«šûdXýùb²–KxÃ|«Ò7 D†S=í|¸÷ö¾DE˜þq3‰Å÷=°¦ ûÅQ2•ׄ[hÉbÏôžnX˜y³a ÛTté<Ñ:¶‹GpoZ©ß`ü€?+eHt‘BÅAy§¬0Æ¥&ß̼|é¶¡÷‡}â5ÊåÍ·^ÿM朞 ÝtN¥AéP­”ÏèÕóÁrcƒ§‹ZÓA‡I6WÈüß¿M±e<´#<ÔªY¤I2U"hKYȰWc*èrz-¯÷ÊM„$l?¯Å—¬¼Œ‘Ä×$±§µjZBÆÅÚi[Wz»vÞ¦rv1ç­-¹œòy:ŠyxŸ¹{î¨cBÝÝ®5³Â‘rçÅZ”À(‡Þ€É þÍ`I ·+=î€K_ݨJ@cñ¥•4d礦£ œN¥%\d°ËÕJ9ýCB¡U)_ƒë¸âq9ЬIçap ¢¹vXÛóà›;8´-øHË@†lXX_œ‰5n?²S«ÈÇ÷¹ÙÒÿC€¥œ|Yø¨c@ÌÜäí|M;[¶üëUÔaì&iÅå¹7f³Õ~rSîDj/›Cú»õ{~ˆ¬âöÜ}—ØÁô@i /èËÚ-FˆäSÜÜ\!G¦Ú ±_ÞnJ0r/ñŠë‰øó€Nš—ªk6Qmh:¯,eg>5ðÝ<[Ø r™cWátˆá4ÛÖyn?¿aøå‚øNc·{'ôQ‰X¥:ÝÍl(¥¥C°¾Á%>ÂIKÿÎJ!wÕÒ.ÄÈ|©óõ ^<ü²±ó’ó÷Q"¹_/2]¾êˆhÂN§L Q~.g|ѹž&Í7¡Ãçõ¬3ãŸË¼g°þ©@‚ÌAÙ„móÞŽÿèleŸŸâÎc×-ËePÕþü#„^x òt>.„…SD†©„™I=iÎ ×R͆y¸wzÝëÖœ®Gg«¡;åÁ|f¤ÁqCn¹Ò”|MŽ•o [`¾RÖJVûK¾)éVíˆìd§ÕÏLT{>ÌUH –à²ìqùKäbÝcøJô¸Áqtª$5RˆŒ9 ˆ4ºT¹GÖ§…h°íùÙ×TÓ ½¼Úk=Š.Ž×W-îu›ØzR©Y *azÊ?hÚE‹“—²8d!C}u(*n|oõÇòZ¨®A0¢å¶k³FÍñ¦Q“OIŸiF|Œˆ?PáÆGºçµæ¸=² ޾¿Œê‚Îso:7[#ùŸhgö÷kŽéG+¥¦¾-(ø(·¿´–ÝX)¥®lÇñ2*wQ$ì”E%ág±–ÒñsfÙ&Y댆7NTnYÝ:Tùý¾-è$»ÿÂ^jHø2Ð縤Š]i ³A”¯k¬M¡šˆõ¾¾Öäô1XâO›Ì&÷+_3üZã.ìJIL¬Fãíg9šŒa)aºv¿ì"äg¤=ÆZ‰|<´¸ ¾ºÐe­Ï§í£× g© !é0A…&DIÔÉœK©ØKk<51:ê4~my;¢ƒëÃR¦m.ºG%¡ô˜kx£5]S{Ž÷DÔæ‹ù7fÂÔœp ½º‹Øš ï°{¦øp¢.ƒÞ^LÏ´®s'ŠÝÍ㽪ÎHÛ8/z†ë5ÈrÞ”aô²šäc‚N°oéÈD»¾ù"‰ª|B½ÿsWÌdWQÆÑ2múl<ò„ŽÍNƒî¶A(él›Pm.¹º,eôãÈѾbÙÅ{U±Þ~Å[„:ƒiWÌk›–ð°§õ°^xÄ’YŽê èEý64ª9ÒØ|”lS¦]#þ¦>€ ±’€ÓÈÝ·SnßT_o_»Xš2e’K9W¶+‚8®ôc­Aï4® Š,¨Ò5¹•zoþ|¦ë•ñžá&x[¯¢ÈCðš6~|Û.™¬ªTF ü¶ªð“T)à[[9#œƒäâr .,ãÍ».´3üNwÎJßrYú’®{˜d÷™„(o?fŠÏEâ¸W'Ò'÷w»Ù Sü¬Â~Q¼‚—P–BüRV‡|†€*Q#Ú5„¦ù"'(Õ·O°å}¨°I¥½²ñü§`ð<Ö6’¢Õlþ¤ËgÜ–ŸKºË4«ø*m>’6RuG‹MO}ŸZ{æ›X£\@úºhöòùlrȘËÎLjû·b™ W=ÖçþÖåOTù½¯ ÂgðY‰(޵½SÎD%Ë‚pö2An+" HtÖËÚ œþÒHß²mß![›dQbé¹kÕ¡ 5]ÚÞu Â?¾…\0ªŠ0û¥{ÁEsMž™è¹¨CJ}ùv•?Ðyw\óÜ®ôY9ëkyŸ=}çú&^F ¹1¢ßr ^ø¶Eô¯S½qîõ/‚u65«U{`2Fs·Jf1 PègéS†Óõ f8ç™jzÑ8²”Xí×UU_ŒFЍZsÙׯ{Tb׶Ͻ›Ñùµ\,Ìt‹"ÍA? »" ÷"÷0ÕØ¦.Ë—ä¤>uÚæ&ðk|eµåTÑ »C‹P¤$ÂÅaü^{Ÿ|Càt@½Ä±Þ¤¡|:„dþ]ú+ S¬ÔPi1Î}á6jR-¬&F# .c—pì­#AS‹ø|Wþ”•öl:RYs•£ 0 Í:–}©ö0øfÝþ[Ú{÷•u÷ÏÀwvnØ#ÖûE?^ú±NãXÕÖºD=êkŒÞ\A”qYWqêŠ1°‡m‚$T:ŸWÎt#ÞiØà†`ø *'õßmIÄdÕ‹^(ºž³î¤Û«'èÞN»zrôlйu'ɼ+‰$Ð_ò•ƒëÙ½ÊIIò]·zGõ3®ªMç‹RÁ´¶¶ðy‰ú+®ç?¾æF’¸þ\¨çM@¡jµ§qQbDZy€qÎSñÍrL³¥húDýs~\e‰f|Ä#û1 ¼8-ác("9JtÖPe¤ê¤ò,B“'m*†Q-Mά>ŒXmÑ+«i8@%ÑÔG¿H^€ÖÖ ’gä­º["«ój&¨ÐæÒû®ÓþêŽB}¶«v´˜+Yüí icLªqïY»ºÉ „Rr>övøƒ?2ˆR‹²¨'nå=CŸ FÏò-k&“™°é$Ã9 qt•@+tÐ.Š ª±ž¹ÿñ×Z4»eÊóE«X$³»”6à.{Ú†§Ü#‡ÈÇ&cSGϺ<¬”÷¯>}~K>•:ìZi'|Û™ÐÃB^-r©Y{bGÔœµŠSuÇù\Vjö%hÒ'+Ú$ú^Áé~Ktߥ´¯Œ` ÔQ—"\Ru]Éȳuö€—"V…/nc›-ì3ÄUò ?Éž=e v¿,¿„¢5zúdþxŸ£f°Qs";03ýU—©“·îµ˜ÿ{’í¥nù¿P’8íbVçF8KV·ô‹žˆ•3’ìTß«å)'¯ Ãý›îÒ&5nEö[dK®Kh߉3 øŒuŠHRR›Ü3íç¶Z<¨qÀì \#N±­#jª Bcà_™ù“vóeuÏÞòOFH¥•`ylF‰Qõi±ÆëŸûõ…¢s}!»yòÖ£:ïº)³«NnrleèX:ul„î†ÙøS:> ëgô>ã¼0® O«¿2±[+r!3µOÙ¸è-”A¯†T «‚I?4~’¤ÓÛúໃD‹¦b† –8¸Œ’%`¿ZŠ~É ¥M#¢Ž\”A®<{èYŸ3"ºÿ&4€$'½©‘vHXßE¾SÉÅ/™ÒØS4ÃIýb¬•6Y‹ñÍÚâd ¼¬Ow^ØÂÀu L 0‚Ë©O³M(©b»˜ŒÎ̘øIèž}K$ßJÊŠTÖIÉ”WǸ“e ¡ PÔ&aWÃQmzË=%goòc>lwý´Àd¢î|Ì' }´,yJZ©Ï%ø ;kúÆÕÛÛÛîórÕõͨ•ù™ørÉ…àåÅ@ຖîËðOIÅBÑ¡…‚Á±»u^)?¢$š‘vºÕ[IþF|4Q÷Ž2®s›á´7ŒäóVÇÙé]Zí¶Z8Šzu‚)-оI7¼’áÇ}Å,É6¹$}óÌû¾™åÔ/Õ›Ú]ŽÑÏ—<†wÊãú¬){ìÅwÓo%“‘"»S˜,ÓÙP ø/êHÃ7ÇØtöHèV=.¹ñ´ í)þÔ¸ [•©å0£9ùt_m{¤+~$ ÷dJ¡€ÓÖš_¿Î}'M|-MUo¯”G”ô…Q£ÝÓ¨x&[„2¤†²8fÀÿìÆÊ~=ùî¨ ˆé`Ô”°6Œg"ØW'qF¥,Nö™–}$xÕt§1'D]߆˜}ÄYò>É] –0#™Òþô.N…fÿ¨ˆï@|b— [‘œ.N;>ûð&ÄS@¢14k³Ç¨® Ø)Ú:ˆ9a!ìÐ̸3å!ç… 5±}<¸ÇÔ-n"m^Ô%€À›4‡n.¡?þV&R#Všl™ƒ±ó ÐdÊZó·»*Jå_îÈJÏF¢¯~4©T¥Z‡cÿ(ÕžülñâMèsÑDc¥çg«]ÀL¥¼×(`”ÒùË â‚uÕï*]¢ºQv®8Í…“º7´A9rÐá4¼AkM»Ã)r«—ý[*²†pC‰SŒÝ@ì´êCzQô£öÞN‡‘ üЩTP{„];ÂÕ±õäÏèÈÆöœ·2-Ì„÷òd²Ioù.L±Ø«å;]*S[k©÷rÐyW/ñŠ¿wR$ÍJË"Σ<2Ù¯äxV2§*±»ìòâçeÂ*š¿“]ÈEbŽh3d‚ƒwýEùªÛb8ôM9ÙúŸ}) aʸ5t¿  Ûºò°ñ;¼ê=y™¥T2uàÄŠæíŠ¢Ž6œ÷-‰Wªó ;”È’ οÇS¹º¶¡ðn1즲ÚãX©™M6b9/ŸñŠ’Øx®’ˆÍ:HD¢›0ÙNC §6ˆzÁHõAÒ¦WŒ+,Š˜hul*s%@q¦ÉÊTrâi¤â[™m"ï.>e›93ЀË}ÖþøîX'i+¥íu9Um¶í[ŠÝµtòBqÐ2\^ür¢XA…·:t"Þ¹«{¢qyç†I– 8±õÜÜFŸhyƒsÕãÌ*ÂLÍÇ^!cäƒÃRlöCõC5PÝøVrÃìñ¾1ž|Õ•XðLò+´Ïhx@†Æ¥¾Aâ1ޱ~µ5Ò_n1¡]2bé‹çÆby¡¯ v6HbÜö ¨RMÍzÇT‰¦îâa¦ÀÑ¢c> ¶ržqRº/-·Æáº0¦à½Ýb©Ç+.ô–aŒ3)~Åq7tÇèKt÷ëí~!Ð&u ¢¬ýþ–­!¢1ooÎ*Íÿ +GŒ¿³øª×w®¹åÏðˆ½BÚ¾1§»³7#¤÷V¾’LÞ &ºøKb©C²¸ÉÞ°ˆD¯‚ƒ‚øG jƒî[T ·žŒ(£þ>ë:,ç€O˜DÇApïŸs†À\ã]=;hÌ”éƒ$B%?«‡‘–Úop¨}?ŒË8‰'9?Ì•~Ñð‚ê!eÊ1Z¬{}r°“©â¨;Ô¨ÜQ³þK»9«ÀI2ÄŸ%Sód‹—%‡YÕÿHôøNè°c6çe[Ê£êMM¡³êý«Ï‘Û`lQFúËhÖSEÆå%ôD2sªBÞþhßkÃA¯„Ïó«Ál¶âì/´ÑwœZß»n"ú^­¼ˆÅ.eáðPK#¾v¡Cç)O—E^»’‡VWq›‹×ó¬º÷–>‹Tñu×"Úå§´[ÝÉGn8Ñj·&‰½:­ØLŽ”È8XÆJ\Ü“0œÙnQùzÏ|"+<¼ opµÛë 5ý¬Y[éW6Nð"ßfĹk0MgñE“Gî âýÍ‹‹€”î…ÜȘ/ª~Aó‰0®žŒp=[ÓØ£xâÜGŒ£6°M¨ÚصVê ‰Xƒwù$Cöè ™Û®ÛöUÌ!œâº}$÷›¯¤«€ƧÈN`ÀÜ+‰)§lÏ£]ž4ìn‡óÑ QG‚Gè2á8¦g'qhûn‰7LK: Äï´( ü–¹ê‚h»¨¡UÐA`þlùñY~ý†X˜[]âÄÏ‚-¾ N×zˆÔ%+ð»¢]ˆPZª<*™újÀµZˆ§0󖤩²*,§¡fótØÙM(€b†×óÆÐ"Ö–û–i&G‰c*BŸ£œ†@Äò]?î*ý/g=æØµ0k…¥U> stream xÚ·P^6N§t#±t³K7Hw—”ä+° ËÒÝÒ‚„„tˆ”H©4RR’¢t+HH|«þâ}ßÿæûfgvï}NÜûœóœ;³lLz†|ò0;° ŠààIµ D ?$ˆÇÆfA¸‚ÿ xl&`¸'•ü»"l‹@bJ¶¤›6 ÐðrD%Ä$A € $ñ·# . P²õ†8´ù0(ØMæî‡89#§ü½pÚs$$Äx‡äÝÀpˆ½- m‹p»!O´·uÂì!`„ߥà”vF Ü%@~[7O~ÜI–‹àA8 Àž`¸7Øð‹.@ÇÖ ü›?ÀÈâù6„9"|lá`p…؃¡žÈ/¨@ž 0T×躃¡œµþ8ðþ* @€_àŸtEÿJþ¶µ·‡¹¹ÛBý P'€#Ä ÐUÑâGø"x¶P‡_޶®ž0d¼­·-ÄÕÖéðûâ¶y}€-’ß_ì<íáw„'¿'ÄõCà¯4È"+Cann`(Âï×ý” p°=²ê~ÀßmuÂ| Öލƒã/ ^î@c(Äà ¬®ô—Âûs#" HL\ö€}í¿’ù¹ƒ~ÁÈû¸ÃÜŽH à ˆ#ùƒàië  à^à €ÿ4ü÷O@à±GìÀN(Þ¿Ù‘0ØñÏÙy8Ä`B Oúõùge…Ô– êê÷¯ûïæäõä•x~þǤ óð ‚|‚" €€€„@ ¹úï,ÿðÿ›ûoTÏò×Ý@ÿfT‡:Â( k÷7 ï¿4Áù׸pþûRÇ`翲·‰€ì‘_ÿÏâÿòÿ§ù_Yþ/²ÿßû¨x¹ºþ¶rþ2ÿ¬¶nW¿¿ìH{!¡ CÎô]MÁ†Xìñrû_«:Â9òP'׊ñTø‚ô {ç?ú»Èô®(Xæ ùõÌø@ ÿ±!gÍÞù”x";õÛFŽÒ© µ‡9üš9AQ€-n뇇l£›7&a.èí¨ÝlE^â„z%d>ïT}_¾¯ZžÝÐ߬ÕÄ¿®šâK2N´ «øÈVlW0CÍŒ…à£Çá&=ö%úxöcš´püŽQ#/h?I¨,À|M0ùrƹÆH㇆•ÆœšýŒtt’=@a;Kƒj.àEÙ*|4{†òÍØg· ×mNÿ ƒ øÎ·Gìlã’œ4Ô@trõ„ÄÕµt· ¦t,á‚ã%U_õobívž¼ºé;]W±&Œšér¦M;rºCÊG{«›“Íøv•e …*RªØ‰ÒR®'’oq/Êt 3‰K>rëʽ•è,_]ø¼–}Ú@Zx‘È8IÇwƒù³ëÂàçD-Ž¢åi†˜mSÎÀ÷Pkp•ÊŽÄlàmóz¬í.Æ·gy¤6D“ãÖ¸‘˜+Y‰ w´ëºð©Z/[®Ž5ø©æŸi=;½ÉÈ‹NÕ¡¿rzº/¨$¹ó¶”x3ðJxWTTØ»4ä˜UcHYóÈïzk%BøîûGÙJw?ޝ B9w!Ëü‹×Ó´å1F$‚ã¿|³á{mØI©T‰s꩘¡Α+²¥ûÉÜF;A™ôÃ̳b&rž5TéB^ÄFÿج}‘ªÆ½e+fs–•´im.}BæTpbÞ}³76FÚ\•ÆZ-, ™) ÷ÈŒc=æ°PXƽ?äãÄ;¨YšqJs›•Õo–j€Wâ’£Ó·0¤Æ˜¸P;Íó#kNw L1.ºžØ¡(†;ÇýÃ4‹¬1ªêÐ ¼³ãú'¹bžu(·_LWí‡$ÐK°¢÷˜#›qð³rE0$É‹Hd ©óò†eÉÈ5CÙF§l‰ÞXr"ˆ¾Pò+3ø§˜rƲ„k댦µˆ~ æžS–ší¾›Pì§)©·}$pî'R±ÜÍáÜîçˆ×èIBü‰_;’Ç›/ ¤¢µyóÔùOx¬œÒvÉÌ?’EÝÜÀ<}ªžlë‡qå·Š'Ô ÚÆ¯Ë?²ð–õíOz7¢Þi ^F ËM¢9b¼[ I0Dä «Ä‹ÕÜ›Ò줋ìr,¨U|6©R¸ xÉ…GPÍDZgYím}Ê©w»S ]rwÛ%Ãn3&­'rn+šn*ì¥aõ)³¬×pÀçé1,R–©èywm1Ic›^”›ªŸ-T¶ŽH|«4εx0•‚•´!ôŠkŸÍý.U‰Íî2 ûù“+­k Å#ž"UúÑÇÝ)uôÒâVÅÜ-Í+>4dzÇg‡ÙKþ°_·ON0,ò÷ö¯¿$zò¬q?¡1æË¯g\%²|wÃI×+£dáÀõàz… z–ÅÅòb!=N{![^æRD‡õµ€~¶K-‘sõæ;Ò@ºú7\æƒöGKs 2A©™ã¢=ÐF}J9À^1Õê Ü™|ùO{°™=™.g _¸Ï7yë à fû‰gÿ`Ë{5AIn}àöQI| -¾Ó0ôÒ9ÁÇÔ˺÷ËŒhŸeKºL ^²É€Yu› ['^mÇû]®x ¦AF{H Xæpq ³ ½8ÎÕ:ò®d¸9œ%Ò%$0ßí6ä»)›uo&§Y·àŠ„¢¡‡á!“Å—ð…ù"Œd›Ë!o ÇoAŸ ®Rq…™(±‚¹H°¼(¼ï­*³WçvY&¼2•ÚK|F;¥ ª½'úšu¶¬b3!µVÏEîý˜ßk¿»Xá¨2iÌË+Ç#é2Šª¬€cª¬¶ ½˜­Á߇äôÅÃåùWãìlük£šS³˯Í-‰KøàG•÷Š‚¿xvç2¿²Û¥²2ðËÍÍe‡*ˆµò g¸vküEµ7eÖ³Én™9Úuu·³nû‘õÇ äÉd%ž> jž[{þmØÔæGÓåÇ·¸CM2Ç©ù¼³ËΕo¿E¸ô§,ì):*燉\©XÅO$øeAéFp¨°±&€œÝÁì·[=z e ¯ï|C%ð.WvqSب?ŸóJb£’ŒëâhîOhQç,axÓ‘«ñ&’ËN%G&ÒñŠ6g 1ó(õ·}‡;kI[aËóˆnjôi¼’ØÚXìN=¤<,Ít¬~žÝ÷u·[„¶?³±ÇéÎ5}—jƒ—|%_\ý™æ¸½åiþ¾.ãuAEôtjPQÖî9ÅòO2‰:¥)Î{´i‰£âOðMTÏAŒ¸Ø2SÓ‡Xšgz;µ"ã^°B‰N©ãEï±ÚC§Á1l…—l(ÒÄ/£K3!ë…íû§×Ne‹ªi¢b·ÄÙÒ̳IŽÐZ>Á|#0WëÀæsyÓþÀ0!és3Þg™-—Jv7>uq!ã¡‚Q ;“Ã¥9¶Fóº<|zÚš[õÁ¨b—+Åëƒ#ñ†ð²úA vQ*Å»dß+ý¿s¸±¾Aá6nfex9ŸÅð%9ÜÖÆ`R]fæ™Ãw†5ã¼%âiAå¹ÂZÇY£5Ù‘–Š÷P‹Ü“UöoÆ»7-!µÇëi:¯ëí½>týIÕ³­LÔ_¬ÖE[2«'×amz†zâb¥{˜¹çcëY݉Þ¡Âu?Å¡†¢ÚÛï(€(¾'išÎíE Ÿ¯€m»¯—ïy‰Ë÷o¿.ÈÞ"ü2¶ûê®Ø M˜ozO«ycëÞ˱úwÇhü£åC“ƶ~_ôûʘÖ÷jó¹m&´tßïÇÈÐì®U¢÷ ©rÓxÞÇ&B³\Ÿ>~Tî ïM&Móx­®+¼ “ÏãÙä*¯ …‚ÙnÍ­[qÕZÎ>˜.‚ ¬%ª+ :¸z_Ñ„A·/Ë»æ³à«n 8¿ôŒk%ù<ºà›e€@)i.ÓÇub:KÝø,hóUé3¦"Q9mй/O€_:Õ›|Ž…!9º¶Ì?ïÞ%Y’®µ³ð]ð_ÙT‹/~ õÖÁ¼8ä„víþÊ}ßÂï¦ÔkÇNò¨ik¬èÞ=lhdOd(TãôüÈ­}*&v*ºBâkÚÝ{EóW'÷o µÐJ´³nÜRµYnð ð¢vÌž†4wæWO²Ní׆EŸbÜï,mÏ dÜÈMLQM!WÏnµyçèâqß6è¢ Óœ½€#­Oæ+ŽPYäG; õ ':ãg"8àÐÚÁþ›Jù7õ¨_‹‚Hy¯+¾qmQJBhpúíÍ%]»wê§ÂïI«ä‰}Äòˆ¯ï¶,Þë5ᙟ³tyXŠ Fí,z[‡ÁCú¼ŒVÔ§L¡¢Øë®û¿‘”He¸7[ÇWÉj¬Pšª×Ì4ïû!—~p#ÆÂ8³<+°hÄ:Å[:KŠCdN­QÈl'kŸ@-¬)³¬Ñ“@½rä´¦x)”LÉGo?ú¶¡ÐÈxe²¸µdŠÒOûÊÐû>ÂÔ7ÿÉÃFŽ›²Ç@5?Ó ¨áZp›ùew€6 µ [;Ì›ûzb•C~³]qîÞ .FŸFçŒ xØÞ‹¡^ã06-1Å5~¢v¼hV!8©®¬¡èõ$ʲ‘¶Ø±5|¹½É.Ù×aGôKÊR+ë›ihi`Þ•¦›'?©Ú¹SPãcB ö뜢qŸŸªAýR»6[ïp@@âÜ-½Z*]{L‘VÊÝÃI¯ª÷ô=+G}i­üW£‹–Öû#U¾Ì-ïOír„ƒ…­Îtl¦wÓçHÔII¿ùX8üTsýyÔ`¡¥…z@ŽÞ•lm„¡—=;çaåiÐR•wIÓIQ¡ÔqÀŽÐ/FÐkk6þ. »B°iÑ!IU‰ ØÐw_ 5\œáyõ}Ø~îöç€Å×=;­ÛùA8XÝ>P^S½ã"ò:ÿ§hY‰ùR³<±ˆ(“±‡'_dÆð-§¼Ê;2±ß|7æTôîG÷‘S›Ã}Œ¸ FQ*,¥öE\MGt\Å+ë¥[ ú¡TO“š"‹[ùê&yÖš[s‰ '‡‡|£F…S[Ï+ SEÕÕœ`ʳ1%óÐ&»Íûï,]kGµÒíÑö®í€„UšA.»&y·+J¸^E„¢,<‹;Ô0l̚þ1ÈKJRN'?WÄ“˜¶Ÿ]Øøæo>0êÇ$¶‚ ^9œ¹'˜:ñi¥Ú•ºŸÿ¤ñ³\ôÇât2¨ÅY |è©ÑLzu«JU.#a,¸\±ù9‚òe»bÃM9Ã÷Ô5üõ^˜{2œãò†ŠáÞñ›¡‘%Ö‹–d4øíÎR ¸ê¨ÅÁØa²JÃ%`JƒÆoj©•«/UÚü`R O·¡ôÇr+‹S‹nz²´Ì#,™ýW äÉF"LÜ´!T—†T*´7ÅXÄÙg÷ùÊ+.‹ü Wï$ž®œ^>™imPl4Z™ù8i‚}JŠw^}ÀcŠÒhhA«»ë&D‘¦çæ·ÃKRÍ“a:AÝ{Sqb´_íráwFl ÍŠO1öu9÷³à-ûÔ6ʰy™2ÅE?Ž>ë|  ka©jZî×N8;Ë_2jì‘kVð§ø6g09Ö^T¢OÞä_]9gEJæ™Pe´w|:­÷@/2—7J•o`` ¡Ýºá_»ñ=tƒKˆ(5ïP»óv™Zí3lßû}w&ØéeüœÓž WRk#«ÖXºF…3ϰîMIØ0¨bFÞ»fÕ3](›Eœ,NÊ8*³},Õ¥¥IvwP*[v;õĬœ}gõ¹"ºéÕl¦OŒf†¯:…‰ žv£äé©vv‘ÛäœðÈu•™IKñåzG[^»öuɱUù÷@ÉÜs‰/$±ˆKj¸Û§uå90!ŒõC^IEæò¿8(#}<ù’úÙ$g-öÜ»N^ʼrÝ0AüiÑb¨}‘Ó†|»ÿ}“ ƒûWïÔs_ïÎ7ñ¹ôÀ¨$êr%‰V‡L-/c½Sù‰ÑüBåE(26ûûœ¾¡8ZÉ=åºë÷}Zå·È¤“"R’àÄ;-)X{¨’ÔI¶å5£lsXw€2­°íâsŽÃ¹\?ÇÞLø(ïûXxA8y‚Nù™Éøvãâ³ÒqùAv´¾Cã“9Ñž}ÑÑÖRع5­äñgœÖ•7m’ü ’\‡á” “¸´rv·ˆ÷ü:ÇåX=õÜúƒúz€±^õk,bòÌÆÕo¹Z",çÌ}÷Ôà° ˜àâÃÂÉw#¶ÀKï“7aJB.Æ™§=Ss<´¼{ÕM³o¨©yGÐqtñ„ÙVcX1ÉÔ8®ß7*b‘I›o[Ò0î%^—ôÎò–xË´íDç3*ÆVåçûÙˆšêq·mž¦ ?¯ôˆc³‘À„í36;t OZ˜ä±qD÷j­LÙœzì7ŒŠ¾å¯¶T:`ÜÉjÇ ö¶?ÒyrHØk¡3ó ³ˆÛüÕúM)gç%M±-A©zÅå–’ðŸ‚>Ф)õÉiÌÓŒýÍ~JÕƒ¼,cv!}q摱&Üb_’ÕͯRÏ’'2üF¼C3%DÕ¹Ô™qY™ÒÞÍ_\¾ï:ƒ¥sê•øìö6“D>·!$’f¼$g  ‰/P-Ÿèwò„Glr*†¿ô’oèóÀ ™pÝ6²÷²È¿È|<+“¢œ‡u2SH#x¡(Ì6ò½9¤¦BÇ®Ø1EYB”êM+Jý”v¤øûOèƒÀ;vûÈ÷ÝGI?ÕÑètƒ:PE>²„3Iõ­Ÿ4œ¸*N.<Ý" ¥¤˜Ó!b)HM~)L˜!ëÍË£½r"°»Õãîgý¥>y¿t Ñ ½ËÌDN+íóàVÜ¡®8S¬ÐÆ5 1 ‡“IÞ€ðïû¨ÑJ6L`íÄTâ k½)—©®=¬žfЄÕ¸° ’VtsKÅéLŒ=°˜ªà³c‘ÓVž³Lý|¹MB.œDTâ7—¢bùÎbrVDz2þ”q°i»±™žè~œà–wêŸöj_“³‰Z|Êí¸`¸áãp阭ÑUv¯ó„ìZ¦ØztÍ ÒG¤BPXƒfÙ™Þé>U¯Ã6ÆHç6)ëUq3έ²oú;o>'jÍSêÔˆ]¦àOý1aOC«4`~²ŽÙ~g!þ°Ûx¾úä½sÞÏ" i£~pS òS’׿0LùÝ7óŸL¹U×ø&– V…Ï3 P»Êä^hÓ­ÙÆŸa1\xmŒêzEÕIÄÑ|*úº³s]ýív[|rW+˜#éñâÅ’ÃÛ~Œ§²¥î†7!Ä&,Oz½$eß8ÚŒ2[+À L>:]Ùøã~@E‘çãp;¹O()b??9V–}DUaàÆ“ö¯Ÿ ûj’i6)s£¢?³Ê Tf7rl‹¿dœ|9»¾‹©êî½J?È–Þ7ÝM7Ù©x³UUfø£ãÚÜôV ëðº0vêÊǘŒ«Y*dÖÒ:dúr†Ò^P¿½{UÎS †ÛiÓ2ìÀü5¯pžºó%š°<ú©ÂÕ¤ç­Guª+¥·M(‘Ê“{,P—ãi[à¤)?ð˜`®ô U÷UÛ»¢K¶P5Ä»ârŽK”í±½Ù=íq6xו¨Åë·ÄSä à7auó2P4˲ô&«á'â™Æ#Ç£Y,ž¯†="_G¢æx7p(k´iõ5ª8Éߡ牾Ý9©ÓoãÌcuN“¨¤ÕÉî7·)âœÚÿ‚ˆÄþñÍ:¨:Ü8¸Œ˜qAÂØÞxº&ÕºæF`zg•®q`?(qxñègsÆOÁÉ=‡ù3Yƒ³Cà”¨çF8»ß²' åuEå÷s»'Ü,®9ǜւËàƒÂð“ò§Ã •ƒ¡TÏ+1üìðs’ûÆi¹]šFÀ®÷Wc0ôá® •sa<œ T1ʦøõîäBö  ’º ´‡ï ò,*³ÊXøž·ûªB€„—T"÷ï­³&“ÐÉ^¹¯Íyцž÷K©0µ‡&¿¤N¢ š =·=Íj|–êûŽª¾9B*âé†guñø@QG’•^ÖæÔwÜ…ŒÎlýRÂÑïϤ/†)ð±Òp‚†¡1ÒNÕ6rnÞôe™™¾fà5¥­°¦¿ë0ÞÇÕ“:©Ÿ×Z§{:r¿MYµ]¿RµJ¥ü0‹!–*ÖÃô=»*›ô·9ØáŠá먅sà=ƒO+~]IèœUË îÆŠÅ?´Þ{˜4ÚÙ·!'9©Éb­8¬²=±Lqæ¤ãÔ4lƒ1 !ÆÈ\|ð\Vpã à¦nþ1øSFG¨ÕjN}|¦4¦Ì(EÉ#‹¢æèÿCªæ¹ìP˲ðí¨¨úÉÛ_qÓÏ[®™ªž2+]×ðF žúËbæUJ'ÈèÚ4]]zèèÝIúOû’«é”îÒc¾rÈÂC±} ?×±”÷¶ØjK[±†V»&›Ywd{y¹#³š*¿~ºÙHSû.± ‚ õé:k"ÿGVÁšùoùÍ%ßDñ‘ ­Ë¬Zv óL O<Áªœœ¬Ï \Ð\ŸwmŸ%ˆšîrV&›fLIÓ±ôm–ûðVÍÖ›ÊèÆ‹;¿žDÅW~NV$æÎBýp âô¶> '—À,yòÐptŒ©n$Fc}™fòNõ¡õ}B#%’"•r¸¼>h‚@Ëî$Ö|c³ò¨â œç``‰Í©p¢œÏsüà„Lläââ ýøsiÿ‡Ísší ³  ÃOV~²Ë…}ú/|7ß2×B¥J”–êÙ3®AkÏÞ´(kžípô¾–-°Â:é_™â JÈw$<:°ô<%Ý}Ò_˜…m#'šï_ źµ­×çJžyàT«D6†8·V³õn±|{lè ”,jMÍu¬`”Ù™¸ÈÍ™8”Äj:‘³ZxU»ý,‹sv¨suÈíFáÁ§Eð²ÎµŸÊí0Íf“AL·ðVÔŽœgªp«zÐC™j­ô(׉ŽÙ¥¥G14»y×Å£æñÙ3~œoU¥˜FW´‡ùì7×Ý^ê¢ Åxz[ï_³†¥ŒBR¿]¥Q ×[™²`>X»\yun)ÇŽ®°bT$#^ùC®nÌØ)X,û¬tú'¤:Qj<…Ýc2ÿæâëë•sGÿÎ"ܺšºV†Þ½š‘59­P7¼o‹©¢N5ðÌû1ã§YáƒWº6(Ú5åÜš"¶êŸ“Ç’ôî3·Œ%½Y’–KVä…Ez—, K? €æ‹ÌaüèºÜV~ä,ñ¶‡ápöìL<ÚQ¹Ïnö™›1õ´im^ ~_ls{l †·^Ç„°Ç佬+Pû‘ðþYàÅq@›=ýQ ºumú¬îGWFùôb)æp YÞE×jÜÛÎýSêNg}t¦ŒI¢%à4Own/NÇ7õ…7§ÿÞ®& endstream endobj 1007 0 obj << /Length1 1395 /Length2 6090 /Length3 0 /Length 7032 /Filter /FlateDecode >> stream xÚVTì»§$F‡42 ¥·‘‚t·¤„Ôlƒ1r4J ’ ’ÒŠ(ÒÒ RJJ()ÒÜéW÷ûß{νgçlïÓÏï}~Ï{ÆÕÈTTÅ í×D£°¢1°PÍÀDKˆÁâ~~3Öþ‡ÀŽñF QrÿÍ®†C±x:‹w3@£€º>@ˆ"-‘‘ƒâ`°ì_ŽhŒPê‹pˆuÑ(¸7€_ í€A¸¸bñUþ:`‚@ˆ¬¬ŒÈïp  ŽAÀ ( ë Gâ+ @S4 Çü+…€¼+ë)ùùù‰A‘ÞbhŒ‹¢ ÐušÀ½á_¸ð\ ! ÿ L À4sExÿ¡6E;cý 8¯ð@Àà(o|€Ê ŽâkMuô·<á¨?œõÿpþy5@ˆäïtFÿJ„@ý†Â`h¤'€@¹pà-M}1¬?VE9ýr„zx£ññP_(ÂêˆwøÝ8¨©b „âñý‰Î†Axb½Å¼¿‚~¥Á_²ÊI DÂQXoÀ¯þÔ8 ë ßcuG¡ýP¸?ÎΔ“ó/N>ž sÂË®£þ§^øGçÇ¥À`°Œ,÷Âýa® _ÉÍ<á¿_j|ÿÁ8O´'ÐŒp†ã8o¨/ˆÅøÀƒqÿÝðo 0,Ðî‚@þÉŽWÃÿñ“Ç üwÀxâA€à_Ÿ¿O¶xn9¡Qÿ¸ÿ.HÓJKÃÈ\ø7à¿Mªªh NT\(*.B ââ@ü!øßYþÆÿößZ#(âÏÞÀÿdÔA9£²@ÀßÝ_0|ÿä„ÀŸë"üwC4žÇp À?´·Kaø/Èÿ›ü¿Cþ7ÎÿÊòÐþ?ûÑôñðømøeþV(áð§Ïb,~# Ðø½@ý§«ü%6€;!|ÿiÕÁBñ›¡‚rñøûÞš¸“ sýƒ@ÍŸÞ‚¡½¿ž ( þ~×`îø§Ä?©ß&8~•þ]RC;ýÚ9q)i ƒðƒÇKR@¿œNpÿß¼‚ÄPh,>ˆ‡ tFc¿æ)) á«_Êß2¾ë‡þ-ÿ«ÌƒÁ/ßo"à»øKþ½ép¸?˜š@ÃnÞu{u÷Ía• ‡Ÿèò Â(ÿ²E¦ (n ÓìsLC–&ø";bs ’Ö×A÷iIC`_yšû ·Þðš,º1Ÿé$èÔ>Ùdd¹ 09ÌüvèéºJu7§¨™òJЙWÐípwâÂV]þ‘|ã¥R/ñÕ—…Ÿ­”õý(­˜Êéô§+g"¡•žDR+«§àýÜÞPº-ÜW9Cí+žÖÓ§2j‡¯]^”Ž Óå½Ê® °=•{sÚ—[qš[k-½òjˆšÛ˜Z“ÆàuH·3y…C(q_ ‡ç*¢¬= &ŨHÕ]xJá”"¢kWQsƒDdgÈ6®¸ÊÂÂþAˆƒb·F8ÆÝµl”Èí–ßZó'¯ "Š÷k")+öJaÞŸ÷ÅÀ®ð¤ ”ŠÇ-bRsRÒÇïs3¶±rS$¸w¦¯Ä¥9l&X?¯Kíí=0e ¦LPJ«! …‘}I]¶èvA·$o%Ÿ³¿«|åØŽ¸á ÷>l©2¦Eßík”ÔÌO>bô­wð8̈êöÖr)ódR›'Â=¹ÞÁm{|ç‹C[VM»F…¹ š|ë[Å¥›ª¡óýö™¶úH£>³øIÒÆâP{¾í¯tÏ©û|Ô˜¢&%É2TÙ¬M|$©ÖrJý;æ‹æF äÏsã!“ó-ÜÓdXFu²ù9NׂGC“×g–Í]–…\æÓá¼ðšh¤Ã[-jÀ2´vÛß}¦Ã¿{CyöÍØL6£õœ®´kØöóÅiW•骹Á÷¤rt­¼IhÇ ßÆY&0¼ÅæŒ{6“°#¿› œÒ·vifôB5×Í^àL 0wXë‰ûöYëñu\'äc›²Ó zH€%¦%M½ò–uR©FŸØPÒ'…õ~»Òføí¶zÁúö'ß>t÷|˜ÛÙDn7²97²‘]bà4I³:ÌÆÖ™é#÷@„_Œõ¾ãŒ Ô›4àB¾ä(zY”½s:I!l÷µ~ÂW¥ú ­Ñ®åÏ]î˹±iY§ã¯BÔ÷ÃâuîS²ÞãqEÿiµŽòÖu©’ÈÔ½í«~ù£v_S¨Ž˜&»Š&}Sˆ÷F$ED #àßߌ6’+Lb—62”Õ«½à^íéôO*8É«EóóJÉý56·€|ûŸ2˜“ „$Ðo*3#¬Æ„Á8aC±ã³š°nÅ¡˜˜ë yáu=:º'œgÛ÷Ñj<Þž¨ˆª<ñNâXAãtÚ­rHrÌÚð8€àž^ˆ_x£Ò9áóÓµ-Þô×yQ$²åì7÷¯IT. >6  ¡”‰ þdWƒôáÐÜÊžì?ŽËO}Vå‚”î •¿m§çAÌ=xûAÀÏʧ<E7hµèóWº¿tÕuµ¨Æ¸5Ó¬¾‰ë4ÍtH²±£e¿x|"\d›Ãí¶¼n¤æ–:­E¦ÈZñ±9ž”×~NËܦ¡Íý¸Î©½âòÑù”¶SX¡œ>`û"»Üÿ>Û6Eâë9å#óàaôI¾r<Å;4ZŸmý {¥d_=® Fx–@÷ÈNòCxÞµ§º)èímsFài¸³4û˜çANvûÁäbékm–¢ìÛ˜¥Ø—ƒi‡Š_*h¹%¯‘ku+aŠl‚¤³Jiõê Âý:ŠY“?ufª cÆT“`«39y÷Ú}YóW_?“ã|ØôW: †U®Í¸ã¼$,ìT Ê®?ù,pÆÈjUDÐëŠOXt™¬=0]P"ða8"˜î¢:#ÚÈ°îæ®ªM‹y€HF½^§0Õ\?ד)¸ž‚«ñ~¡°†´‰Hkõ¡÷°Ór5ìåž$U>YŸàÌHò¦ö'i:–¾œ2Åù’ÄñØ :ü:ƒÐ7òÚëÄåÅÝÒËJ_–×Q­*y ¸ìœªGÜ"M 1¸,ƒ˜ ± ¤¡$[£ûÜŠcVƒ‡Øàˆ®œ¸5wfeÁFƒ Ž­¸X#z=Gþhßóls»ð™‚}½I«x Ä•œCí3^Ô™´µ—î¨?ªKßÂŽèÐg²jŒ6oöSÆÚ†'8w¯ÞþV9žR1ë&sjíkû±Ï#ŠãÝÝdY)á ?¾ 8[åt¼•1sç» ý–öó7dc*–DÓëM©]%?Í]råÝk¼JôÙ:«U+V&Þ ¹=m¤w¥™Ð‰¿NÅw©EyZ)&òÊà/÷ôª†8¨mœ¿.ûè®d4Óèå.ïqó•(z¯Ínî’^WY)—5ö–J—­ÑÕátš'‰ß\Zx…V{ýy#’[E\¡MõHi«ðM;I } ÝžO$¤öä§—˜F…~?”a&}¡dçø^2òó^0ö'<§íœ˜•hlú¢N²~-EßÉz xO<ÊâG½ØºdIb¤ØV“ÿ€PÑ0W5s¿úTжµRõæ]™»‰ÂçTBÔêòFK~7Û£ØyÊ@ÝÆÃ´¼Ï¤ß*r}gRgÏU2²¿ØÆ£ó~èÅ¥%éÇ]‡•Çí×qìÏR|✋λde2%Udj}?É”œHu3tpñŽ „xyºà~šÃ FY];ˆ:tåÜy#6Ö}{⳦p¿ŸãçÜŒ/‚&–´¼\õÅG²EÞ’ß-cy^ñ:.Òúëãr`Qša†Ï Üȯg½Ï3ŽKÆ6p‰s|4›F…l‰mVDï¶ös¤•Ûw_aÜaKª?wx®y –nåœrZHñˆ¹„|•0U|vu cwÀ{öÆ áÁ¥ÏQÔéiˆÌú©¯ê2 }Ìê§MG•?x—_ìÏ´¡5N ŒÀ£`Ï2Tùûû6á]S•'“\2éïì)›Œ’FštÅR±"ÔѪ³‚òòP|Ä⎗owfµXpïm×0™ìøì<¶Ûh°}-#Îõ¼5zçÀ_†i¹ÎTƒ¹Iªª0íVÎäð¶ù;9%ôs/ªj: Úów—¿/sçzų°Í¼ÃÊï_v%\ªéèX0ñ}!sŸVÑ ¢{¥ÑZŠI}_±3ë(ƒìÑN÷D6Óa!ïå&WS•ê Eñ®YÒHò[ãJ´<^³´#êßnEEïû¸ïKÚsÏôäð–Q9¶Æƒ +È"èšìÕ–ŸM©Ê/*T¸¬ëÝ¢€Ž¡ÍW7¯F¥8èö?ÿÈ&+ÝcRØ_!s#+þîÊЯþépì|4ÄVÁú|"d Ü§)N÷¥›Ÿú+Dv§WÏÎBFÿ‚P æC«»öÚ Lw(ˆ(ž¹‡Ôžü^Åב¥«ŒTÍw£ ..ÀºŽß/Õú¤SÔž,ÞvB›5ØWhðE•DGô­ÕÖÿÑÌÓ >Hb,áõ9‡®}ž'[’/ C’vs^\ ޽/jýºBólï0ÍV¦6c µvï,m¥•FN:ö`r…×á9 ÚÀ¡^gþËC-µ86X÷¼N‚I‡€3=ák*­ÒbÚWEa2+=25k¦{üå©ÞL‚ž†~Îúï\hßbQ7ùèzWÿ„(6>z†~±¬L  )òí@y¦.éqO§‡è"¿? cżÏê[}¢6³Œ¼ôhÞ€`y„­÷<ÖQa}8’È\_ KÈŽ…žV0FV^µu\ŒÎ—s'%ÌáÅ9ÆÒnÉ|è¶b¯ÖP'cC—­ôEx5¾ûFöOœÕßP £U–ÿJT*Ûî¼ûx±£þl´Õj+ƒ¥MfÜÎÝóÝÀ¡eÊRdªïMXü˜‚jÆÐ6ªôüÓ )šéN§ãDÿhkï…Mï.樛U\2WhvM×d[ÍçÅH=· Þ2˜Ô|E÷äî×ÅQQôÖ¬À[ƒVféj¶+ˆ±ÐñÛo'@=6»šâhcRh¯ÚD>.žô&áÂÓ2²»%Ñ›7ÊÕjŸûºÇŠ[iÏÓ¥&iñ­ëNuí¥dܪQÔ§æÖœù!Fɯ÷i³àâ£Å4-Íô×Y ëKTi>0Ncº‚“q“D¦â¤U³§œš§ÀÏŠÛ˜µÈƒ¬ô͸ø›šÃW´&J¾_?ká’{Õ]VètyƒÙ2z¤ófßv ´Ðß ´Ê !>môFò9z¦‡}ð¬“7wÜóö%—ik®ïU_ïùDhÅòàEï°HI~a󻈳âë7šú<Óžú½ÓJ@á²] ¤*g$²äc×'Ô­Ad²Å籨k|îÝÆYï‘„Õ”¨ÁÉ+ôžLµÐñ«6›mÜî-„ {¦&âÏ—ÑÔ>Ö3-$¾j¯ì ÎAfQèafQ ÜÝ‹ô…²Z…îö ¿±áxïî“Ñt®˜HÛpÕìggù~AIß§Rî¤ÙÖvMÒø©Œ;›;-S€y‰qß¶Ãø›‘¸ô ÖžG눱ŸS°ÙõVmw—…Ìï3  þuj´#Ž€ïš·}âÑZ5è¾ëŒÍgæm>ä5kWÃp²›dÕµ¼¯U´¤U•j¹»{@ p»«L׊‰O÷„cíË6†2h¦Tš Ûµ‹Û·ÌBiwt]šÕ»i•žÀiOFš+ ²uXhl¦$€lòaúø³‚i7¿%Àé1ú“©©Ê÷Ø…äÀô†Gÿªy) Ë×) êîW•ò¦ä”I|©›\ã@¿éÄ2³EI©Œp>d®^€j\¦êMôÏl+©©ì8Ö\¦ð·¼¿—^, •5Ö_Í¿ä5ÒtPO´! ι¼hý3ù•à³7<#ŠïDÓø}­¨àiºs­Â§@®Oˆø æ±Ï–èEœBfi FMåí2Îqpw'{Àeôpõª¬\#pZÞñÕ`”òG@àTô"‡0Ã+üœ‹À¡'c3 MÉ”¤µ­(…égè—¥ÏXvžŽÓTr9 ا$Y­·ƒ-µËø%«„ f´‰±~›¬ÀáøöûãäÁGa?º¦ß@CT ÏìüaÉ(œp).ÓqèG¸³ôq%4ê#ä‹[ñ’ 3±k…ùˆE‘6aWÙƒTýã‰Ó„|WÁµPÃÁÁÒæ¥r=EJp ¶Ø~‰ZÈáV ¹œÔÊXƒœÇKÁÉA‡ËÖ†Mæ=?ׯòÎQh¦U«JÏÑi4„¬ 9~RƒrHâùô Œ¨ž ÙìÆ˜ÍqÙ§ d»8¨QRã%=3=r„”Uü@éÔYÖ³y#IT:Î|°—Õ…è]¦Øª–SÁÍý0nvÝÕËü’ò3Ã!¥£Œöâý›©5nåMN·:[¹¿Ä-›Î áe<Ís”C HÂrÙ”8Øç>Ç {ÑJsTËiµ+.cRå¶H"Û¬ý×lFâ®E ë‚–ß}gZS¬}§Ä»SÂm)7QzÙs²õúáíŒñ•BL¢ ª0á—Äí»YÛ¬•nÝÃïg´wX`mân½ÞÕjÓtö`ÛXnYWy´ë¼ç¬•RW£ã+“nXôpIj9K«’Üå 1fr.ñÌsTŸ#øÈªSJùÀñ$ð• (ôÓie µÇ–ŸDŒÍ×G6–9K*½­Y¡’Yïm_l¦¥øF-EN‹CZPæœÝËuj–&“ÑltW[Í@&u¥œ²VXáÙZ/cÙ#½"*Ó¸|#Ì8æÚær {†Ö‚”mšù‰ß’EÁÕì7;ù,÷oÀTwë¯;㨊rQ¹ÆW^Y¾ÅP˜T?@å›4'AfÉT©W¾>b±ÎŽÿøxµcU”v”\£pßÝmehýåÎóã£T‰ÛH<>äÙ’ãýû•÷dÄð¶k¦#­fÊVC‚ Õ=Ÿg˜qšI[ó?Ö¦€ÑvcÝÊw%r³§m.…RéªAàFÎ"Y®;Yo $:ÇAó°¯’Så›Éz³§/ìªC)$·ùUÙ•ùÊ œj7øn¬{§Ü7zg+¶ºØ‘O1¼¶ëEO2ðI2s?‰/PzÛÊ·ºã­v-i‹)0‚M C)¬ô ¢Lºï‹â¢7nçZ]e™2µe =Õ—“W¼_ü´µ…Õùã}­C,n%(Ý&—è– 6¤Ô¼7ž-;LH–¸ÃCÅÓTƒA>ƒgÇd¬göã&ÇÎ%ô¹Ùe¬ºd?é©Îx³nBâ`¬wã%·ÍáÎÖtZ˜3Øu?ï%0L¾òâSþ=ê€ÈÉ·Ù˜~›7FsGêQ vÏ{ ú³÷wmîñÐU©µh:nÿð00& Lãnì_ÌßÑ™yAPu£ÞÙ—ªBtjpžˆ:§èVø¨ªÙí‡$,Úe3V,ÂmžºÁ¦€¹¾WHÏ]6‰¨Ò>«{gÐoªÏ¹$5B¦ÆVúªFöw"´-HTºŒ]œW€;-œ!ô¥‰wüßÏ?‘x.’}ó”õŠYlþï&{–}†û=íºZ”ñúø ËK.9Ò‰\B —{>ï¸g˜ŒkrÞËÓ‹Qv6Ì›w¡Éãrpâ鮉d`-}†¡\\¦Ÿd÷Æ4JJ±Å›Švš3õѱØû?&š¿px¯ÉK3·Üš„$x o>[j^ä âF¿Ôë™)pw¨ ;~Y‡ !®’;\Šw_ò˜Ã%¦. HH‹F3zTŒ)±„ïLEÚ&Qv¿þq-.ò£a@GÌÔà‘Í­døËm$%:µšýËæï¼ÔÐã2O±;_¶Ì_òº…ðÒ*¬äˆm'Æç¤øŽ?ÅòöoµCù¤a¬m…Þ¢™#gyß„ßß1‘áLÇŹ— e.¡õîSªP \¿<\s-3ž´4›¥ZÁÁÚuÐ:°>÷ÇøÞôcr¾¾a‰‡¬6ÚS²¡ ‹ó+»¤å/l5zîXˆ8@ ˆ˜™¯_ŒÃ¥|6ÝÓY$"ÕAL´*yØóo™¦RZîv}æ n-Q`»Û~¸—¼mÔ“øÖÒ—ÄÂTÈ*!4¼Ä_iã”A.É^¨Êœ ŸûÚ°À[oÂÞ j}I\T½éÄ®½éËÞʾ éÐUð¢dŠþB£­¨˜Ç‘­”Çv½/å{ò‘"’³GöÚ ÆÖ'ϧ}ƒynÌxF˜­eb| ^‚Äòk)W¦Þhu([å/&\©Þ›"–âùòƒhvà¼î£ËýØÝçþÌõpÁ6–¢&³œ®U×pûEíܹ!¥º¡„¡ò‡šòŸ~|lÿ“áÖ”m3ÃBw¢X¾¼‚„0RT®Ñ·'v¹Y1xõ»ä·‹®F@ˆÜí·LRb‘íÞºPø·,Ò±¿h CDF&||×Cg;ÿ_ #‡a endstream endobj 1009 0 obj << /Length1 1543 /Length2 7283 /Length3 0 /Length 8311 /Filter /FlateDecode >> stream xÚtT”]×6"!‚Ô€tÝÝÝÒ=ÀÀ0CÌÐ)Ý!ÝÒ)H§„ ¢€HˆH)ÝßèSïóþÿZß·f­{ξöÞ×9×Ù{F:m=N;˜ H…s¹xDrºÂ>.^lFF}0úÅf4¹{€aPÑÿð˹ƒ¬áHLÞŽ Ó€AªÈ Š…Dyx¼<<"ÂÜEòÖž`;€@y`3ÊÁ\}ÜÁŽpä.-,¶¬ ˆˆÇït€Œ Èlk hXÃA.Èm­!=˜-÷ù‹¸#î*ÊÍíååÅeíâÁswdåxáŽ]ÈÝdø% iíú-Œ › ïöøÖƒÙý¬ÝA$Û‚ ÈÔä@î ÐSQh¹‚ «ÿÀøój@.àßtfÿ"C'[ÛÚÂ\\­¡>`¨À ´Õ¹àÞp€5ÔîW 5Ć̷ö´C¬m¿n P”ÑX#õý©ÎÃÖì ÷àòC~)äþEƒ¼d¨ÌÅ…{`ÿ:Ÿ<Ød‹¼uîßeu†Â¼ ~¬íÁP;û_ì®ÜP°¤"ÿgÂþsÁ<<Xþi{3[äønþß)ÿ¿žÿÅò¿´ýŸGüö²ürÿ?^k0ÄçO?²‹päDhÀsýïЧ ?†XdF¸ü·Wnœ ¨äïK{(‚½AvÚ`¸­ã ôW ô0¤ óÿzfœ@žÿò!gÍÖù”x +õÛBŽÒ¿·T€ÚÂì~ͯ€ ÀÚÝÝÚYx¤%ð"‡Óäý»¯Ü\P™@Ê ØÃܱÕSà¹!·Ž„#|n{0²µÿx‘ áþ7À/àF>pÿØ<nWä³…€ìáÿ À?Ñ?êÿ7Œ¤w… <þ¡çp{ Ûÿo™wtýÇüp/Øoû_âmîH~øïæDÞÌ_öï×òÙb/ÌÃlÅœÂ:Ïëe(½87'$f7Ÿf²rú-¸w!.ñ¤±Öå>[q?•IyCðé‹ˉô"íß÷¶¦‘íÏu:®ü¯-“u§7;°?N‘ M–|—i¤Æ¢âÔ—Þò¿qó7 qFkCíQe,tCãiŸ{ (y7V-EÌoêlÕ ªá\WÍpÆÄ™…”Ï1¾°É{ONç¤Æd#:ôÆŸ;9%*˜¼£UMfÇØç+õ3YåM¸xï»\£ÏëÑKÁ@aBNvB46Íä'»®úèƒ_EéŠûXÆ{²®ñ5—T d›ÅwSS÷ÜýÛO &ÆIQ rn4•ظ•vå—rº þ¼ÃOª+Þ*?…Úl<8´RÀwZ¡<Ë#‡éÆÌ.A±­´7ÚÁyM­µp"ï&Ž^OÕ¾c”üÝwÕæ?±¯$>íV5Óf‘~ÍS^w‡ˆ)c‰Ž±x'ksk\¥Þ©gQþ|;¯w®Âìaó™²£øC`P%†¿všk™¦­iëËZ™ñò““W²õ†C_úéYõ“Ë&-äñ½ï¥“³è~ñIãèõ`eW^‰ûâ‚ò†í‘ÔWIåÜ.úÈ1FÍø1af›£EL% âx“þ´Þç6oíVq-À» µ­‡íÇIàÇÖ ÓT–Ïk¡Š¬Ñš»:¾ #ìäû¸ÔžçhŒJš‡ÝqÌ”uqZMEŸÑç좩Þ'HÒâå^Lcâ8ÍU”žÙntÙ mÌ—ýäý0þ8y±8@€wûu·²_ú‹É›”„šl¥‘HØ;ŒtÁÏÁºI€jE=øí{/æ@t ­¶cur[‡síõW;žÉ"¯Gs|/I žU†üo¢´2¸gmöCë("»?^íìbU‡¨á®§X´µDÏEvˆ³jÔö†ÇE|Ǽ粂_!6ö5=™*¿6@Ëhn¢7Aò•ÆE;Ô~œ¿~®•:3@#:G»ldÛwªtˆ[W<™ø–wð¹È7Ã¥%àgœ_s¹¸)!)•XU˸Jrü½‘Q ‘I7U0Ãîég @Êêj`ùƒm“|”{T•‹i“{eø%œáò}Ó.R÷ø&šv+Ø1w/(¢º‹ÛÖ+ˆ &Ùu(ƒ”n\ó}äQ)Ozzû¹Ùª“¡½:·ßt/Ï= ÆjUü¦¡éÀ¢‡³ˆ”šcEßm—ë”Ö +Þ“Õ\©Qê6:I”ãïÀpÑ qµ_.èu¾Ñ3Z’¿oêüý4.Ñá­é><·¯ÿˆø•…Tòối{Þ˜ÖüÑBg§ÑO‚½÷ P¶û»\ÚºN¬œJmGœ›¢­ºU$ á1`…¯íï_Lˆïv®7¿ç²0fz•¹A•ûL)â!Y‚{1ÚßÑܾ‰]'ìÔíK¡2»ôM.ƒÖ1{]­¦ü©ëð$]L¾3}”2Š€7™E•=tôÈaºS)÷yùöû½Üï$«Î"‹ ó¡$G Ÿ¢Ç„7ÜÃ"ìœ6|^m"O“Î…îä}ØYàî}÷}¿VÜFÕZz;>[ùØÀçFßõ²þáª5!ú‡åu/ÅWkÁŠ”È¯dtsZ9€'càq ŸÍVeŽ\Ý’¼R+ÌðG]!Q…QÆP ¢ÄÕÎttâÜwŸ¢»»áù38–?ÎÒ;œ¨sÛ’†á1†¡éÁÆse“›ü3µº+w3¯“)AÆ}ˆlE\ œv4‰â ”äm’´¹¼á¹û®LFÎK-=º’ë1:h÷&ðáÒÇ£oÄÛ"åÜ›®ÉW÷}‹·6žËO‡g²Ÿ‚êvDÉ1&Q¤‚ûOÈJõ-nSÛœòЇOÕ»ék¡š«c˜wc“ÈŒåœO×`Ì hŒ??ÑHH ‡UÓx«·wÇFÏ"FhÌC;,§§¿â¢’ˆLqTI϶ÐdSƾ冣å«0Pš}2æPŽˆ!*íTY”äÍ^xÈú½ðº½ò壞ҦÁ@ßXï8Áž² —çádŒN cROå´¼U#.±]ÊÂY)ŒFºÐ^P½ŸŠŒn}K»ø-Ýï âA?nl¸m1Û¦XÅ(HjÑfså- İæÖÿl‚Pºd`š“°ˆÊ黌ýºÈënÃk›ãXDÂ÷ô¯–ìœÈùé¾v¶gn€NÜcL<çL8@†e3èR<Ø&÷–÷ž*•`\xÞ-Ašˆ¿í-DÕ› ¸«G¸aêzº8ÉÍoVÛh ‰:ä¯íõõGžb j}'Ol}}¾X…OSûÄÚÇ匓œ“côG.Ž}¸â©÷ÓK¼ø®ê®×ñ®­Ftñ‚nœ‰aøÌûÄ7/Wèo‡8ŽÚ=¼G^«èg ç äžÞÑ[ì9 mòå*¼ó4ÄÈÊbA/Ò·ØW;å,r–Šû1r=›Âµ&fçÇú~ÍSÖñ&;Ív" ‡­¡zûÞšè¥ËóR1qjFg¯è8±K×G„rÆÙ]™øO²H7(šOµ,:¯Jõ]=ãåÃ-2’HÐÆe/á{3d¾Þc·‡ox§$S¼Øê«“X§ê JRº“^jPFúøWWxÌïp3ŠÇ²ÂåÊ>~¢%ÞéÃ⥺?Ônéq'€¯±¸d–ú²‚uãr#;ß~ÐwyR~ÿa}' ñ#Ì®‹Ùç : {Fï7Û,.ô˜¨¨²8,6înÆnTó‰jej‡· (ä%®B…Ï‹jE_i.èÈÚ¡vîE¼oœö#ä@ǙştêåY^1÷ðè™°õsËaFfØ¢'½o]Ín¹3µ£€ŽTâÑ‹*Ö­˜4&Õ û´å$„Ás£«o—œôÌI™ÞwÝ¦ÆØ†wØ–FŒ²ÙÁUÈŸzöš©Ä~n&TXuÌhÒoWíÐÏ¡êV¿zµùã"Ô»Ál¬y~ø’¾q"þ#‘ì;£~GÎCHŸ¥t*¡ •Á@e7w©Œm;Û1J¥LŸ?µ˜æ¬_-ÿÝÞ‹kt“š^õº¾ :C.œî¼wTµµ+j²R·gzYhl̺—ùxÁ¢Ý#pETË€-CNò}Šà‚›lÅd‰ë Ôbl&ñaŸû c”`q 3l…„ò2 »€É£Ì¹‹=|diú)Öñßôgã…bª‹|¥-¬SœŒnyÌÍhÅáBVÝÎß%ØÒ[]÷¢dhHBŽÆ—·’Š/MÖßaìZÂUóªIÝÞfõ=P=ΑꌖõixÂ^U_ TÞU·þnóN=º•ý#ôdsç© m½9«N<á'{èƒÄQWÇ‚Mxm–Ø„YÒ§¸SaÑ¿¨†‰4U|…P^Ó§/åÛýä…>uP‹ôR2«Î?›Ú¼z<ž:eˆNCÙOî+q|œäH#Ý$‚xÜòu.?ST¹ÓW^MT¦ ·JA9ÍöÌíNû^¹)Á8Ëe½åƒª‘]ë£!{¥ëÒC8ûxÒ ¼Z’÷Åž/ÿDÉÌÿxäle%LÇ—i¾¢}¸w¶¥]—Ü–Ï™i¶sAµ°ð!¿Ëî‘éÇ^ÓçÃŽþæÔ¹Ä+cØ"ªÍÃñm4Ã'ïçg±yjñÞ)pø¹AÑg‰Må]ëñûÖ©#ÓrŠV^Ù¦äð\E9=ÎüîE=ÞQ2,hÐ0ï®e3¸“_”%sÔì‹~‰1íñžÆÂÖÕô~Í6©Ul‚á‡{¸ß˜ëßY6sfë3¡»È™yº®QŸW 4×eYÎS¨àÞq!d4G½Iä9 —¾Þ.EdmY¯Ì‘ w¼“¹[ >‚¸­Õô&¾T;(šä¨qi¸÷E¡|§UPD2möºBH9â±LÆ{ò.Ðôq­ß—©—…ñR†³£šÅ®Ú§úÏ?C& pìòÅTn»VúÒ¤Šè³–dgçgå}¦ªïjHb+,s òÛ–Í÷ùÃ~Œ…wSâòk=Ió¸7©Ú>ïõþ½Î˜+‹Í}‹§gè2†B/½uA¤OöTÇì¹PuyË:å|~‹×4•¾§ˆ?—­ÂDjçߞƎ|Ðl,"FÚ5+Xòô‹Î„'Ù[IÄ?PÄ„…âÖ·gjܦ¹ï´¥|æ“ú8”Øóàþ<1q ¥GR}Þ@¢^P€a®{ÊÞåQˆç$¦ðFä²óÚ§ÊtÃ=äïö¼B&?B‰Þæ6}Ë7·M/ûN7ïX/ÀDB`cT’Ùêö¬Ë÷Ø;Ùåf"ñâÊDð}™Â±PQ£Ü&»¨ZòÜNôóWkËŠvèšU@L¥‰ö-ÆS´”ñ!©¯w—&?o .…}Ö}ÞĨ&‰ ñê’ƒÜßÛªªy•?æTìÓ±/¢¯vĦ‰˜¥ìH¿éÌùJ{oq“e0ŠªÙ".›J}ªñ†±õËC{Ußè±/489MÌi ˜÷[puM¼ã‰ÖadoC‹ö‰ðæ#LZ_ߘP…ÎN;„ÛõcˆÌrñqžâ/<ù`üöAtÅš)ÉIn™ÖØÖ%âOžz_²Ð‚{Éc¼pZI/4ÇZëiqOiô÷O0“$*PÛ-†Y™·% q‡¦T)öI{ó»é—Ò¦óÎ(AgüΪ‡ÒÜ/õ´ª&¡Æªfô.Ã7÷}ý€/ïSƧ¾¾½Ÿ»É†v?JõZm!Å¥»Úí%G<ß æaºçdÙÝ¥TCø™«Î8¡öÚÆô°MuK¸<üPˆž‰%xb"¯†è<ž‰á‡ŸÒÅ~Y¢”¤‹  ¿Š54NŒÉß3B¼ýÁyo¾Ùi>žž¦B1ž:ìÐy›ë&j`Z3Ÿ2žIÚ •`F/;NäTbxz2–,£9Í67'hÜ•óúð8µµ»kŸžšíä¶Í—„E“%¢ÿª -Ëj?›…££jÆ)]R.&È&7’]±¢B”—„Ib¿rtºg›ñÔ­û ,eª¦w³[›-6öÚ?%ÈnjúD  e—®Úµ (›²;´aíΪåàN±_{´{°³\¡*Ô¦ Ù#4žïÖ3n2êǸü†tSpÙfåk)8&» v6ˆ´‡ú")Ëœ0REÇ—“ì£c™:øY…>½þо‰K)hÍ4ûˆì›=üÖ“^‘L[øÀŸ$…Í7P3¤{‰]B6(ZƒŒðÌËþøÁ™¤ÀÕÚmdœ õJuÌb¶Šj,s¢§ ¤ÁQìÀåI­N+­Ïc{í¼œmHÕ‰É,Þtìœ?°GvÀ\l ¿y­W?Ц¾}: ;v9¤sçÈí8© ™î–ňÀ7\±²^Á•¡¹•Ñä¸,Î!oé£{³Kï=fL{xQ:£±â4©ålÒ3Ù‹Á[A9Eì#qçÕ‹PBDÀj^AÜËø}'H'Ijªük‰K´|̀腶OlÀ>©u‘Êw™Ãºçâz>¯Íl FLÑvÁÚÝC&½Ú‚¾ -z…3Ê_C¶Á±+]%<ÇÞ/ý“ôO(fŸL /Å-è¼£ª“² T˾Èý,kt9´ú)Ÿ%^›%RÒ5÷ÔŸuÞwbé„Þ‘RhAj¢¢6lJT´†ëˆ§–Y?:ƒœœyd„C„ü¸çÃp¦¨Òž?€æ~ÒŸïïƒÕÇÒëmŸZðÆ«yEzÎ]Ȉ©|žYhë|¤Tða` +ta×zF=}’‰H*9t”þPcã&— £6³Ð±÷ÇÝ[ÏZ“eÈCa5¿ŸK„¾ÝSkÚXÛµ-! ¹aö®ôUÄ0ªlÑUô /ÿýâ“’Ïj¹µêw l²ß\*©>yá-ÛrŒÔ;rˆ?±ïðf¼e§YQà/Ló¹úÖ£‹‚ÿ$!ãHÏ£5!œ}êÁ±Sc×ÐðÚüÕ‡í~w·ÍÕú¼ž¤†gõø}!xïÎ(6œ)ïf¼ ±ú„A¨çŸvÂlMJ'dz:oÂÌ%ë©&Êï8^Ǭú²qZ¶²|!+òPÐáM TŸ)`oLQ=GÀ`´×!%6©ü¶n…Z[‹MŸÑrv=DÇ'š˜ ÂìB =|ð9äDl|ÂL/¢¦ ]óŽñÆ`‰ý܃ÏG{Œ†òG•Ñ5± í9¤3[m>{tQb¦}á=¢d´ø}VýðG¡oýAÛ;–ÄiD¨2?ß¾æõ”ÞsÿèœÀÄÝœ›ˆ¤„Ö.ôX]‘ÄNvÚ©ÉkÚ‡ÒÖm ò ó?é`|~ÒÈ/²òrlööd|•è‹‘ÒK-ƒ;½:ÃP‘Ê|æl&Ÿ'‡“kÒ†qÇ]}îè MÖÏðòìwFUãcÇù=(~Ô6kñ'[ÐFê¼Ù¡ÕÔ±–%ZŠ59f-›‹IÕ#bW†ª–›uÑ(ÞX˜Y1©û·ˆÐ Î&YéßNHT{ÓA\ zc–çnãIYvy¨Àd]ÛZµpGbéƒö3x¦×LÊ>àUsÝÓ® )úÃ1¼l$Žãäz+´JN Ì ¶¹=\Õóþ9´H¼m±óµJü4(Û%a$0zÏlÖל„<¦Ìgý£r@VËÔÞmn€rHóõÜèZ#ûD¨lµè¢w¨¿8·½÷.¨£yšœ¯F¢Л¶ÂçRRËcå}•krìp†—ïˆ9Þr޵ œb[†ï,„\0q ¿3ZKÂ+[¢O~¹0«4PUPùäÙjOÅ&ÂrQ¨ìlâŸÇÆä,Œmk¦=a”—¹þL©ó>ƒ4»‚RêOèÚî0uio2ñߎT-—œ lN]-…’&²Êƒ(ÂEš–ÔÕ½ÍÎðbùá‰ÂÝ¡SJìíÅ£1â€Hó.ªó›“ÏfŒ"2Å–-y¡¢\@ iý¶ª˜†¯„_ú­HáZdT|L¨,vfOWˆQEן:oW³2÷®_ïµÄŽ—Q»×´³úó£zØÑkõmv²w`_!ƒ,ç ;Ûv‰\•u@c|ì|˜6GŽÒ#ëüê.{‡ÝRÒýi é1ƒH—›®f‘#¢å5¼ɼ»ΦñýMf’!×=(•á‹=…¼ï6©¹þUBOÈÎÑîJ²‚å‰?{yäAn—µW×}u&¯"ÃèsΠäët¯­yÑ})ÊmVYËwN2¿´Mõè¸àf­¡àö±Ô©òÕuX)k Pû¯d¾Ç²L â0­&RaexÖSWäKã%"Gî·F~i{Fw¢¥±%Úˆ8=[ÿQ? Ä•áÁ¸%ãÃOŠ•Aë“°[¶5³å(*)9\Ui² Ëè}Ív ·i~mÑ4n–Ò:¸lÚ™WD>™ý†¡ sËŒ '_¤P£‰gVXĶíõ‰~M€¾Ê«pÃÎÙbY–;Îí<ÔH©KŒWEÜ)Ñ›¦kã9¤MºV¤ˆ"Ä´åBßûëø—Ê>zÐu£ø£=Q_*Pî‹jÖUçÉÆA¹á›âÞr²§µÄ¤âó+\ •Ž ºs¢ó"d(´£ùLP b›nG˜ a• Ô5Š1Á&$kžG½BîÓKgOºÛ‡•#6”¤}I„_ܦ½U|2mG1Xog wccø*ÔW8ň+ C/Hqà eZ{»S8³ŠM–ü¨`!Í8|žCìz}D=$ùTì;9»]/}¶ñ,‘og“¬«Žâz´‡c½zgèÓôÀw|•=oÈú£4Eèz×ð'Ng’ƒ÷º…æ ¬’×Ò*†«;-eü´tâm«çܨuAÏ›_ ņJöÎàˆv°=Ml¡¯ôà߉øroOEŽ»JŠŠiNÒìOsÉ?+ãê}±£Ó4ø‘º+}È7HMÅ©Æ<çšÃ…6Ôå‹ÌSQKs~Ðvƒ ¥L¯†+ÿ$‘ãìxòPh§L¦ó×Þ«ÆñêHÃèИt¦¯ÅðC–ƒp«åä§ù|Šû1ÙkJ^žoº~}YØB¿ÌØ“¥ÿ t÷z.Úç@ïÂCEQù²ÙÇ Ó7¶åæ»Qg/ºÕšidhp° ã¿&)Sp³Q™íÆ༯ÏÃÚØžŒ¾RO„ÅIsl‹“{™Š§÷²öŽiÖX7ÃHW}úï‹þ`BüÀ[@ endstream endobj 1011 0 obj << /Length1 1668 /Length2 8458 /Length3 0 /Length 9555 /Filter /FlateDecode >> stream xÚ¸4Ûÿ7®65kïP{Ũ½7µ÷ž„HŒØÔVÔV[)µUQ{+EíU³-µJí½J=i¿û÷ÿŸó<'ç$Ÿûºë}ï}Ýwr¨£Ï#g·+Ãa~^>q€‚¦¾)?€O—O—…Å‚€‚ÿÂqYŒÀž8Lü_ `[S´E 5á0Àc/(€_À/,Î/"ÎÇàãûËî!P´õ†Ø4yá0°'.‹ÜÍÏâè„@æùëÀâð‹‰‰pÿvȹ‚= [@ÓávEfÙBúpŒðûOvI'ÂMôññáµuõä…{8Jsp| '€Øìá ¶ü* eë þ³4^\€Äó…>Üácë (†y"]¼`ö`2;@_M í†ýa¬ñ‡7àÏæøyùÿ÷§÷¯@Øog[îêf óƒÀ( ­¬Á‹ðEplaö¿ m¡žp¤¿­·-jk‡4ø}t[€²œ.ÀYáŸõy‚< nO^OôWÀ_amV‚Ù+À]]Á0„'î¯ó)B<À dßý€×÷ü%9@`ö¿Ê°÷r î^`5Å?mî?˜#ââ€Ý`_ðW?7ðoåoYCP€Ü à€,q#?p$ýø|¿^?Y"f‡Aýþ1ÿ=b ¼Ž’œ²ן%ÿ­”—‡ûxÄá_°Ç¿d;[ v@ü üþƒbãBH9nð¿ ¤%â‚‚A¿ùyWÌËóo™ÉÕ Š€¸!ûú ûO“A^È{è÷6 'ð—üûÒƒ}Á Ü…Y8H"ÂùmDûeÏÆ(æòJgL’i_´‚uîe€“V¶Ê”»¼}åp†Î|yÔäl çþ嘯ŻÜÐ¥tÕ|ŠRßšü!OÁàÕÉ;G0½=œÚq\$#fø Y—ŽÐÆÝœ-Õxö&R¤GpóÍ·¢ÛNÏM3±€+ äœˆ1/—×¹ƒúÌ”‘y1djA”ðÀÃ<ÓË@Ípüõ$áB¾=ŽêÊoÍï²æHÌKœÖËÏC×iëT‘0“›Ÿ`J4$,0 ž3ÐØDÉÔÂ1” ™&" qÙ/§{³øZxä¥TX³Tšhß“O‡÷uw‰j×îëö\aX%Ùy°­Ôó;ÍœlJµØ#%Aw’n¶äM§BEf—òå[“”=±Èwˆÿ‘p¶yÚpo"WmyÞ5¼fýj„®Ã¬?6³{b··ƒ-mÓWµáúýÄnHE|€)¢ZÙ˜(Ôªð¥Ÿ,ÆÐ¼ßV£ý´Û£gÄ¡ñô ßüBâÑz¨›ÕVƒÖÛ wyEÀB¶ùH1Áµ*ÍV±t¼h£`Eü3Ñø¶ a³0^'‡FÜu¨Œú"yáŽ9ó³æXâºk·Ãó^Ú/$­µ´ÀÇþ  ´â0eÑÞ:‚Ÿ¿M´…?øÉÁ»j÷ŸìlZ»Ó(†i¶`F›>Z.=‰j&.4Mœ)4ÑQ:Ô¸X³h¹_ÕRWM Àå§ð¢"Üfëj÷¢ lƒã_ž_k1Ðée+=?.ÙËjIœF=ýÁú|-Ê |Gn¬AŒªçÄÿ†^9Ïj<ˆë)_áÒPRü©‡;‚ÖÛaÎå0N™«¹³ÇPt•¡q.E3íWYë½þfYáµNôR¡^¡=8•À¨v?îíôÛ›”gzÄ?­ÓÆY]#G™^²ì+œ#¥$Ó÷ _æ®éÙ n(—AÑÒ:OD}Ñ_Ó`M!RTåÊzªV%ê–&~â+´‘†Áë2>y·æí¦ÈôÔ=gxž[+5üYš;¢­´²Ó‚©òª1-›bRoÃ[O!m¾=WWÑ —Š`ZÖš;o€|8—°Ãåy¼tSNíRÇ µ¢.Ëg!›¤Ä^mPÕß…t!îû#‰>v0tWÈPG­Î!@}¬|Ô“:oÔ´º½`¸ëý.qܼ åÇ<}³‹vìN–jxTêÉ%¶„ǯ†?{'Ïp÷3×39–jÊœÖíȬ¤ºqÎFˆxÌQH}Òá÷ ZS!L•-ÒJ²:L‹1بuhPûé–< oÑæˆ¨ÇÍ'2ýmŠ… 'B¯è:EÏÿÉɉÃ÷€§VÄŠNŸO%× ²²VåÓ†·gƒ®»ûò<ØNü–Vk¬ÞL¿‘µÑ‹¦Ö¨EÜÙ©¾ÝS¾yä¢-E±÷³RvÖRöÊýE®ôl‰â› êÇ,Nlw4óEFÌ݋릱ù­i x[˜Õskܯɱ%±(4-q½É³…5"â0iuÕŠ#›Ñ`ã}ˆ-þ êÊëý…‰ºòÐ}¦‰Ä­´/+ý\9¡ã,ay)âO…Þ°OYkØUY‰µãíL‘“å$–@ÌQžà €èÉþAÙüét®g´Ù‚{·å Û17Øà§µúé¯3øZåa(N,žWßó(-s+ZEäaë¯×Ç»l˳-O·df¸ñP÷ŽíÐÔL'"áä;íhïëRL½ï#ubIú+4=F]· œwI4-Âíï$ŠëÌÒ·ºú×½çéÅ\ðüˆÈTSüÜ$¨çÖ©ÎT{ü¹â‡z–¯¿äØù«(È0±„‚¿û0nÕ¦ Çëél1kj¿ëøÈ1Ø‘ ôp~«ØžíuïF OK#Þ M€å(!èéBMÜüg <×áÈj³ê÷…¢ãݧ ñ á“†q8éêëØ Õâ­êŸOOó82ϰÜó¸æ>LýÒúFÛŠósîá’XkŽÄÝÚðÈÖañ=0¼¥a;ͯ8/Gè— ÚË|©5!C'a7 |á¢eÜ`Ú½§¥=·ÆXj3ýëæ¹•§¯±£ë>¬PÍ7Ë­?oy×€vÖŽ©Þ˜£„úzŽiÒEêÄpÖ¿ƒËKJ:Q|\ŸRÒ_ªòsˆ`—%B˜â'z˜ùèæ†ÖWöÉ@º<ˆñ?Ùíï ì*–¶¿sö3ÈŽím0rø–±Bå^:â¨0D•|’|0ßÝš}OÌ£mà Za)øñ¤5¹/3 £Nǹ—!×ï1>£ö¬î\m¸§~Nâë\ÐÊ‹Ã9zÉeÇ_3ûö¯W-ª¨q k†&zѨß¶w°IN˜v,c‚yvù—qù"¡qœJB3ìŸÁÒ,*¤™¢)ãø;2NDs¾‚·¢Lc8Ç~äÑúº7Z~Û2oRD]Ø#ˆPóã{ßùŠ}úaLŸyêÃ"ºpŇJÃRÜܪ•9+ËÎj—2½<´§íÇ`"°ûEÄShbáœÕ4»&âg›ÒíÙ✣Kt¨£ñd½b)¬¶)Î\tdm|Oq8&åR{kÔ9·CMÔ{P?5²ù/˜ŒÈÑ-ràÀöÏÇï×Í´?'îÍJú¤1¶Lðxçàø»•"¤ìÖ¼äPÜSòÅçfÆ#Ò%ç×9(é1¯„Œ"v& c·ÝuBƒ.n¦¥îⲑ¿gz„´uz1·<³ÅŽJé‚Ö7R9qé¸ÝäB¸k¸ßI:W + †‰äœÍ।W7dÌÓó~*—ÑÐ ¶ ó¦#ôrWZcQy™h}ÀxNÔT]:!/Áë³®nÇûŸÂëekjWÓC﬷如KWuɾwÉÓ>a>S*l%Or–Â}f)¨ÜzàƒQmM($xQ¬¼ï8ÝU÷è…|ÖÖzή\Y僕÷·ã‡Ã„ ËÝK“°béŸ%Mìó¿Ñq üˆóú„{V¿/_øt­ƒö¥GQ©yò—wÞ6_ñÚjÄSœvû^¨0ßåÓDoó´ŒÝyÞTFñy¼Sy4ë9¨¦6;9Lвê#Å=ÎᎠ^Là¦æû=ÑVvÙ……gÙþø æÙ^-V5׌¼/¯¤M?¸¦†dÇ äÆwLSF ª[—/D?ºPÌ$cHú]æjyáÛ>ÇÚ..ëèã-é?@EhÕ¿† ¼%jv‘S³|ÊA¡yIܨ_øíÎ4}Ö@‰™•8ÃZÆi•@7Ìv’E!\¥¼am ”\ë+ʸ褟¤Þ«yp·½PÁõDPÒ(YðÄÍu×S2Ëð{¨˜£u'j©nûâÙ:[‰VŽJýÁ F¦4j_Ùh·³eý؉ ‰ô㙎)­ËÈ{v0|ºøw ;Svi¦Qέgƒ£.e~‚—ðÕØK”Ï€“ÕµüDEŸÕ–KË¢¼š$²û—J)dCŽÏ|B¨V²ˆy™ÉŒV6¨¹çþ.Ì..Ì–vªÉÐAÍ×ÕDm èÆé²ÇÃ'?_œg¸1@u«_¦ê~ËŠA·[)#ºÜk8yIkêÞ©<)ŠnýsFŽ8¥ ¶C¢ûë®ÐU=!€Õ_Br¦+3ÔõxÍ"22N^¿“ûꈓüÖÝ$Äàì!I3çr Ä–)p¥âÈw8m©ÞK[Y-¼ô{ȾVmòPACTÊØ®KŸ äcõ\öm9uØ”¯äz=ãñì@iùÀ1¹è¨­N¯ûŠùšù­)õ×°¹\™m{YA‘¥`u:Áö í §f*m/uÖ÷â< ûW+™ƒnT5ü¤Î·ùÊÄÔD]Ñ HO:DÚž ÛŪ‚Ez«zÇ9æÏ\k†lâBŽÚö–ëœâ†ûšš­¸ uøîýÞ¬ÕC Ë‚Z(fžu>:^Éäží­ã5—:yϸx^T•>˨U>3¼ÔajS‹ŠâªlŸ2í‹ÈðU²§cCìih²5ê%]°ÄÞ=`7UãIŠƒÚ¼9Û—°™!Ûü&7­*^ÿæåŠ©*jÃj›ê@@³Oø€ž•éd67îKfå²éªŠ ÇFÔ2nÇX~“-¤:K,ÊRma=ýòO1ÏÎ TÔçuœêžhÕ›7£« YoG‡(`û/M9àlâHN§?» ½góù­¬Ä?û˜­ývå ³M&aÖb°EYñª–€‹C¡í Ü뱈à‹`¢íúcï•í®Ó`õOƹšÓK‚2s‰ñåšÇ–WâÆT¤ÄÞ I‘D™&«ò )81¥&$‰¼:+j2ùŒEÑÞûMžä»h熖ëoÂS¤&MbÞ¿MªïŽ ñÑDHûIUGq®…Ú) u>±Âï@ôÑÈyÔ@Ù/ûJÒnNîYœ^ÌçÒj„¢î„è¤²Š „¨ç^*þêŽO&ãé%š¼8˜¾×I\ÖOKïñî>¼9SxR'Óõ8¼ ˜¢Ì$lÈ[Ã'½‰‰zÊõY]w:‚ŠihºrRj'ôÈóûÒ^¸/ü±åÊ\ãˆÏ°öÞ gy!ˆá`!âÃB£Õáò:®×ÄÅM¯«ºoèDbë =òßÌ–÷ûmn ½OÅ2ÈSºQñp\5Ä|O$4œø4#Ž5°&±¡+ûIÚ•ŠõyѼŒmü‚jLMïevg DiøÚ2ÿh¼v´—c9fÙ§‹:bL©=ŸLíJÀ÷*¡êGϼ“b"®%éüðöO¶°Í÷íüU$óÝA „‡‘šÁ/@³ìâóàÄZ™óȨ5³¬GôêÑŽOÑËû¶ŠzÊ7 Idãr ^?̰ٞ3±ô«Úèª}-ü°v쥕›CtÂrû^TŒ÷v¶´mÓŽÚ[ĬÔÅ%ƒ7(TÍ ;5iÑ‘ž€9žâ¨)oŠËô žÏ'aêjú œ\Í‹¿Vj‹H‡º_»–w ›T³…¿Ý§+!Ï%$ë‘4,};§õITnïüÉsŽ@è©4^ÖCê£ôI›Iš=™—’Hí¡Ö:&v–}œh@ŸåqœkË àSªûýGDyms dÅöÔÞTÏLQ£0MÓÏ2øÀÝHN¿g1f)½×y!¢,§ï¬C(¶z\Å”óÎ1U>öEÜXß‚Î~©„¼•n¢vyªàU§ü}Áºp/XsÓ²Z?Áö]¾µ6&ø§ÍG\†Læîe›° 12]àûâ Í:pHžÌü»Áí©š†{ôD»Nëh–±%v‡]8·ßÛ¶+­·$'/GÓû¹Ð‰v´=5æã¹µÑT ~–k˱h&«…-}ÇG”4Ì{c†GÍXP·íÖ&{5”Ɇø„îÆ¸\Ô6ŒÅ¤҃ʛD—ïOO+ïZ œ+¢Jz™Jë¿î'Íâæ š“MkÄ:å£&˜> «ã˜‡ ‰¸-ÿL}ÈŒ¥šbÂýÚw,ðÔ³ÚÓw¯X5ORYxmýé<ÆèžSéý3á ÊHWî¥I'}c³‰hc)Ùšj.†¤ÊÖ?ûhm¼¨³…VˆÇ0_j -ë¬GøôZOÄ(ñÅ2ª/ ÆL 3YmL^9ºÿã«uPêg—pc’ú9äšãÍqQñÜ›QÞ ]‹ÅѾ:Ú±y0„]ê–’м\¦&L¡®~«€ô©yáJŠUùyHÿ#óÝô“ §…'ÉÍä¾™>8_;Kè"•›—r0XñŸ0E¬+¥JF6JØ öáyÿ`¹dX¬60ßÍbZ„Qc™T2 ©ã—+1#übÞ¾3â^öºÉä^f~Ö¤o ì™R+^Ùqm¾Ó޲œ‡Vû~eö9^6y«@Ô¥¨N¯Eõî©C»£¬¥C‰QÖpùvð“8~å«ïôV„r‚Þ¯qVµs¼§ªiîyãáú_o4/]ó-|!µ{xžsÏ<Çßo=¬Ñ‡>Èwî;$QQûcyS¡-…¬>aá%Q÷·Ð"-ˆØ¼Y» WÚÆâ^ LKiRÀI8HyBƒŒ¾‰OQ.L6KòGÏ}He"ìÒ5n}®}{6™üˆSÛÿG+/¨ùÄô¼Ò”õfùóüü8Iâî¶ÔŽÈƒç¦”Yõç—·¹å„`CjËʱiÀ\™›‘ج|K[OÞz-àqnZ È|2TëúµãNàš²Ž(}ú‚Ê>ìvÖ{'tE,>º æ÷s']j¦Ñ¯v¿•÷¤réÁu%®æßê²ùÏ“+Œ°<ŠÁºo­r3–+íùùÛ 3 oéžVÊéî·Ÿ3ÎÐÔ JÕ*ßúi6Èô×ÒS¯™ç-ÝNu(Sf’e×To¿Ö³ï`¼‡-‹kFŠ©ªìN}!TæVŸ^¨g4éš,ä½üÔû0SfÍ)×gB!)à~]!pëu&WÞìÏ›ËDÔfîn`ÌM²·þe–Õ7göW£¯ÎÖQ•—ˆ–¹N?]yE&o}cTîpÑ^¹Ñ€>aó¿)dP6\ߘÕÅD2ÕÎåúck{Ò©‚=®‰Ôr iå$'䃼ž‰^nÖ¶Uu¦lK}<ùq‡‡Â%ôž>«Êå}8#žSÅB®RDr*ÆOt!9pгµÊ7«h ‘8Œ @{ÕÓóØ%…ÝüËxê;ö5Òú]e  ˆvÈñNæøм/ýRí§þ=oZ篟»J$bžfØDæ'l`¶^kyŽës<\Å!µóT*&4ÔÏp]àCà³kr‡Z—&aFRõºQ×^F‘$æ°õН ?|ã'Û9ºëØæâù;jØd—ðcºÚ Ë-»ïSom-¥} ÅÂëЉ×l¾½ºæ ­ÜüɽU¹Ò ­«1¨îŠí)§@ßIÔmÆP>üB†<ý)!±Ô.ÍdsúíÁó½Ó@w=j71ÝíÀ,F؃—Õ" ±“x™wáºLïñ8ß#Œšb~(Ò¯¿8x ζZ¤=GÛçèÃu˜J—wâ ~ëa§ùµ˜gk“³{³É‚ˆtÇH•È‹a›ˆ–ú úýƒãx,öTREä¶üèÚà}LÁÐGîÍÇSLW­õº¤1üžæ®ÆÇnÕ °F2Æù×ÅåZ[hä8­ÛäêèŽ(=aV¥8æÕ°3{g†ŽQAVñùÊó£-òÈÅŒ\l&÷Ñ¥yŽZîX7 ª€Z»ýs³‰ ZfU©‘—ßX¦h’’†WgD÷³k%ã<Ÿk˜5¯ªàÓ„G­6-Yzp.‹s©©P‘KàFZ÷øÞa=ö£;û88l7ŠE¦DpŸþÃ×ýy¶«¨$0ZNKžÖÁv·1*£½¼ñ&Îè´Ôäâ3Ú=«™w$J•meª9€µ›öµ'Ä’i;`³ü—!!×ý¡;UùýÁ¨—’µTOŽ{GÀ”óè‡À}ui¨T°ŽR®?ý^˜ËuÄá£ñG5©¤ õ%‡Šî šój±2Š›¯îÐ ²÷{²åº^¾ŠåÌýÌÎô\ãЭнÚÍ"‰ b9ÖtŽØÝïÿð÷ëšðS=ÜŽ¾3sÛ¹ÈN“r·$²-Çe€½/Ô~ƒHJâ·ºîóÙ§ŽÉOwg‰¢_øLˆK%-{oæ}¥¦R¯4.a_¸Øø¬e¥”™Jž¤«•,bwßË8ˆƒÿÈx¥PEc+>룅ÉQŒv”Æô̤ͦæàD¼4ˆì;LL[)+5£œÁ<ÃÐ…‡ÂaÁ%Äè.ß À—ÜÃzÐSa"ð¡êÒËa»RM•á3Ûïµßà™JÅ$õV_KЮc·X·,bs˜µp?˜ÀÕœ¡xiï¥sa÷%3ÈžÀrx¨‰èãLÝvÁúßÊ×ó±B!>‹5¨_[‚µjp »ðÀj¯°%³Ä2MSíø[!'½ƒ‰Ñ¿#ÍÛ…‚sÆóÂ^ô¸J°ö«d’žúhOŽØöÐìíÀ)Í>Wr섃†ø‘~ ¾7¡Šo¯$Ãb¨X‘Ȉ´Òé“Oaã:ÎåkÇhñü•*øÁèº[=CgIĵKžJБyÉtï”ðõ±7"¿GüÆ›ŸBWñ”!Këí³G ÏÔŸe?2ÿ ÇÚ7ÖÈ®Úrf*ƒX·|ˆQ]=ËjÛ¢­¸éRe»0WÁdÆXjcϼ—ÈÊ‹& ˜sÖÒ+.ݺ Xüäµ:; ¬ÃÛlã9ܘ€7§˜¤x§{Ös‡ÊBFç‹§¤n_å‚ïý( –ñ”äq/ñP?{wW´¬{t¡ÐÒ9{Y¡oüuÃߛߣÌK«¦u92-NlOþa‘´2²83›ßkLÒ£øu ÑIìe¤jãÆëñ9ügþâøT¬!6’îBR·;0öÕ0e§˜6áý?@z‰‚}¯UÌ éö3ÖM‡B KCS›ÝÃ&¯óñ…­¾™Ž&¨}¤µ»w5ölgðXYa7#Àd¿2¥ºŠþÑÑtôBÑ=ýÀ0½QÓoâ'ÙÍ"_mZ‡©RAª@dµ¨"–CÆ&!ãc°šÕ7·brGЧAêþ í[žÞ„x!Éd& z¨ÿÛ'æ²¼õ$jEæ¼kÎ?O+oÒÊ´}G®ðœÛ–·§(š}N=†{Ç4Ûž|°0{Q@F.ù­‚÷ÙÐ ŸoÞ`hQ€ðyCÕÇ›Zó 0ôX_ìÙ¦Ý|æú.ÄÂ+©Œ‘]8„£Ô[÷ˆÒlϙ·¯ÜÔ‘HÒ–-U% ÕÛWÿ£ïþ;•ƒ·êïs¸»8*³ÅGY‰_žD:|œ$ÿt*}Fó²ÖÝnþj÷íäˆc¾vUãþ‡"VÛÍ>L³¯ÒSÍßÕˆ°Š”€½?¨Ypdž蹮f¿ÖÒÒ¢=3?8ºå¿aõQT˜ˆ<²Hj˜iŸô'ÖG7žon®Ôô- Ösþ¬¸4ú…샿æM«H÷ö=W8;E„¯¼å!ã:Ë­ZbSlØÞ¦0hÕÇý@Ờ¢ý{¶\Ž 8|quò¦ ÑÚ+£:ôb™'@ÕÃñªUëÓÚÔþÉ2nÅ3œŸ#/ZQöƒ”×ß Êv °s¼ÿ‚)z¿U¥M"ƨõû^–þöÙîh«·£ÛZ–àŒuä×e×µàú‹yÖ«Žzήˆ:nˆhÄšb xHL„/àÛ´¿ü¦aÙ9ŒáÅ`û ©æT$Ó¨Æëù®ç[¶·,ô†Eâ b` F°ë¢ly ýø½Ø9ïL2M+)7yËÏlÿè’•· endstream endobj 1013 0 obj << /Length1 1477 /Length2 7066 /Length3 0 /Length 8067 /Filter /FlateDecode >> stream xÚuT”k×6R"Š4H(CHIww‡t—ÃÌ#030CwwJƒ(Ý% "Ý "Š€„Hw£žsÞï¼ÿ¿Öÿ¯YkæÙ׎û¾ö¾ö3éµõ8eÁpkˆ†âäåâÈkꙈxxø¹xxøð?Ö‡¢ Áø !ÎH(&ö¿ä!@S¢Ðqšp@ÍÅÀËàããáðñðˆþw(]¡`€&@ ƒ ñËÃÎP[;ú˜¿¬ 6¯¨¨0Çït€¬#Ä š@”Ä}"èЃƒ ”Ç¿J°JØ¡P1nn777. #’ îl+ÅÆpƒ¢ìº$ÄÙü" x t„üaÆ…ÿ oEþÁõà6(7 3€   ‰Îp!Îôá=U €û¬ñ'€ðWo¼\¼ÿ”û+ûW!(ìw2‚;"€0(Ì`u€´”4¸Pî(þt@ÂÑù@W Ôhø}s @IVDü‹ä E \H¨Ã/ŠÜ¿Ê »¬ËÃ!0ÿ×ý ÎºíÜ&kƒ»Á¼þ2l 0°Í/`· êäQUø+ áÿ³… ‚<¢BB¢ˆâ²ãþU^ßùíäý£øx!à€ šÄjAÿà{!®ÊÙâãõ¿ÿ¶ðyy`(°†ØBaøÿ©Ž†!6lôð¡î3´öx<¿>ÿ€„·y+<”x¾°£¶ÁZû]¿U(Ö{@@3?¶ù`QÀÆ6AªOž ‡ZüÓP£{SÇsÝY[p¸ '£_©XÙ@ÅçØÌZOÙ®W÷š#\ÂjÒÐ(i]cˆ~hU.13MÓGàLjù\Ûóš!*ÜûâG¦\OÝëˈS Ã4$NŽ´G ·èõ.ˆ¶ÃRD×ùÿæ<Æj,¶– ŒQÏß¼“—"v·ÄAáù 5oÐqQyGbïz óëïýEæ’Ñ® Ï3 böÀö3ƒÛƒwS${¹¿M2˜Ö±å& ^§R<úÔŒåÓEi9¼˜Ìé'ýÃs¬könð‹}gϪͧ[VÜÜ y ‚Æ™Ó'_ ¢ ‡­\×2&Q‹Ÿø86 ÞùãtÕxøÙvÊ’µ†±Êáf=EyÆ`¾I(:Îïåx.çªtÚ ?¤cÞÞë (÷‹Ä ´‹çë‘’ÙæÆ¬à;šøð^åõü`Í×+ºÚ“ šÚÐïEÛ\ ž`ÀŠ&C3QısgËäq˜Š›$%f.»°‚ؾᘦ¨@ÏU(f:"‘9Q™õ§cäªpÖŽY #½¥dR´Ô&¨.Ÿ!P’á^ÿÊÙ5•G—WÒÎÒKßø¨d+³*ª–6âô ÏÌWü̽-:‹º@±! ™!p ‡'hÏ.1¿‡ßB¼É®Öíè:޼Þsæ˜!áYn¯=BD/ ö-‰’øXx4Tèˆ /pGN¨…\g*œjär;@âÂémQ$Kì é7G¿7þÂ<¶Lµ?ÄU ú¹ÎˆÙ§ðL<Éä5c‘s3Á±å¿gaùlêÞH*±ÿj<„Š4“GP푎¶7?í%Ø9;øg¼ö#1¡ Í›Œ¶Û¢!å» éü俚úÅòpÙ9?x®*H wó•ÒOŽã <|Ñí8•±âKY.¼ÑïôòC&Ç,íN4O`ÊHP£~Ñ[®T…ÞfT)Ú AkM†Ê˽·HsÕ>×H¸­ìÁD³ØŸkú#±Í$î?xÐmaÚ@æaå踜y½Tó)}ç›CR>÷’¾x Q¶¬YŠ+h0ìÂ!íºef` c7$á2o\ÄOP?ÃÐ)Òr¾kú9’ñ²opÓ³÷\¿ë^"ŒÝƒÂBn6ç­ûÅ O±ñ£f,'&ÓÖáSºlÐ!Þ|Qq]~Ü·×;*þ¼ìq˜ñÎ߯¾³~òlš5iK&Ù"07qÜ3Ñ•.ðhÊ W‚ç$ÿTŸ?²ž¾):ªc†¥‚)6¢L]ç °¸ìÆôoóèРʸ{X Ê~:Y½F`ï9v×ìD\`%a¹^ÿtqQê$§ !d™8'g‰ û2œéGlœxÖc_翪Œ­“Ü«]ç¿ñ骺[‘F ¼Í2ްe½q<-jQòÆûñ‚é$Û³H)PWD¾wšÚz ›•ƒ[“Ý÷Ã}âªS¡‡á6¤øïz$?¿z‰}‰µ¼Ì·ôýQ¡¡èŒß­+¸â”äŠjÛIºë¬wÿ$Cÿ€1¨i†¤ü¬…g%yˆúÊ6¿NÓâûc¯‡¶¤­Åi&¯¨>†–ù—°2I²Þ ö}ÝWx]2ÃÁüÆŽ¾w.¨$"zvŒzËéÆPƒƒOS¯~A »\€ã+l885Õ“"—ì~‚81€­©À'4N{±’OíQ O'–2BMÌ ° 'udÜ?ÈèdÁhJ7’ǧ4÷@2?³ò1-õ“U>XŽ¢l|þù,`åçÊbhªîq]Uåî;Ç]æ¸7oz-6à aFAú@y+‚ÌÍ÷…®nf6Žf*/x OfÇkLö^‘0õÎÌWfï+PH¹Íé^ôù›†ßg“}é^îÐFÏ‹±F3¼Vb|çÖYlÛì{šÍä3/t©Š¤)&pìÑoWîfÂeK\œè b½¾k²‹ã&³ÔÕÊogÖmÔÛØr‡1´í0øø^¼5(½Ÿ­•žkñaõúÇq£†gß" A#¸©²_:™°ÜФlWGPÈÒâç1—”ÇWhuâÖˬ¤&âùîÏO«fZ¼Õ]ék{Òߥ‘f#v'—y‡F«UjÐXÀº"³‘0%L:ÏPJ†d©„R±ë=x.jÞéæ4óêÕñ«±ã•c'ˆ[bí*0}'ZŽkŽäÑ2Ã=6Ý.&Þöìeo¯*C *SÅ:]®&VʪWÛßyÖ+1ÐÎ71P°Œòsþ@@õNÚ89ÒÇ®9öj-‚iR‡Y—±¥x]µ1ó9äÓFî#(øT)ª_åȱ̻)õR‡=kpNRM^=$‹3»Ø.=Ðxþ‘u}ÛךR™¢Ý9îØËºó¦)UÒüÒ%’µJoÀ¶Þ„ËSx_9ã„J?l±säÑr«—9ºÖX¥îS~áí}[ TLCf=s·Éñæ$œê1«MM:{Ÿ4^lÕIÑzÅú(jðš0Çý8ʾà L£#|rÝÃ/N <ijhöz—X!±:JàýÐvjSÝxì¼²5™Wí7òÌœó"é2½g&V¨[DŸ¬–{ÈÓ‹‰ñæ‚^ÊuªcÒgâéWt®:u‡˜¼-$RÅ$¾ˆ wxûÃ=‚ïÎäÛqµ€ÏPpó¦üØÖÄJÓ“óo¢“V2ÄT&NR¯ý¨Ü»±rg'¯ç¦j}ɪ*}„Ë •±t~è_^ªgÃùFËŸ…ô³&¥I¦îå°Ñeeí=MöÏ1™cîmúpLß^'_ÆbãÎVå—1¨¯¯v {ØPf ¸qèÞ Òœ÷X'?ùtaë‡@wÈ$™G¥~é•Ù¿ø3*±íÙš >vܱxÕè³›¬ŠòPEPýE*Qù×!mâ͹ãarMÆÊêtßQ£纶vÒS[ yEp×hå¶>똔bÚ9—ÐʦÝíXŠ/ü åpF3–F²åë˜8Éõ[zR¥ˆÙ@ÅåüÈGĉŸ¦š­ÙÍÄ_.­íª -\ÚV\êŸç?òYß óJtX¤…G$ÆK,E5´`¨.æÍK¦ëÀGFÂJ¼ÁÅŠç?Y¢—ÙË-lŸ úÈ¼ÖæÁ‰ó/Õº}/¹¢XÄ6þ S p;¶R?ý†SaA8÷lb³fNå>ýégûþmgš©aæk y"ðàjîŽëfå#»™åÖðøšlÿœX’8lòëÏžùR—ƒoG‚UÚ3òÍ`¸/š°Œjû°ç+ò|‘ò\é2ÕçÍ5šö¤CŸ¼¶=øvü¼vÕVC£33ÿZìYm Çm—0h]¢¯—xD k™k€þû„T¨+ŸÕ'}ðJ gØ0S<ÊL²´ÃäØºT…äE3“ÐÃ(™® ¥,Üv[o[2T,3wå*xæFÎ:”N_1…€ALÝ,Þ¯~þå@eYI§ðc¼lauýpéol–seÞZ'¬+|t30c{QÄžâI-è"w½‡à‘µ,!u#Ëp!×Ò]YäÒ*õôX wYWcQZ®û@ˆ¶½Ì¶‚˜ïGuZ+€P¶F0d.b*ŽP‡ GÎs€I#¼ÄÉGÙ 2ÕvÖ‰ÿ­ábýè«¢þ–ÄΠ녤Ü+Øì¡s‘>f誶Þû/éßN²\¤ƒØ´É-× ­3ßU¶À¾…§|X;qt‹æëLOOé!…¾bò'>_é¡+,H¥@<~¤®%r^ùxKÓܺ÷Ëzó§žVŽŒ†SÈú]z×2dŠW))ò„.%ªrÎĸ·£ä‰òª?Fž-±BêÈãúZY%ŒÄ| Ÿð<¬'˺Ûz,•ž?sЧ»¶"Aè6ÑüÊ›ÁµC÷Jkÿú&•Ôñºé6¥ÒíÔWÃU*4—Ó'™µ1$ Ÿk{¤ß¥Õ½ve¢kZÆê¦<2+š]ùª2a2Fmî©}ÊmJdmH¾|9?lÎ&«1îù¹ô•ÿæ‚¿&'F–Dx¿ÊÒ#UÌîaðÄíƒø8aÜjáÝÐçPý@³ó¦tòRZ+JFèù•«‰ÜCcñéŸOŸg»öØß Ñ_žÌǼC)¦cÞï=O°þÉ ˆ¿j(WzË› tQ-…8æ‰8æ½¹æ»n{MÖ”ûºî˜¨äT/†Ô%~IɉçglÒ†“Ù0ÅŽ‚H“È[e´˜0_á~®yYÕ6ÀɈØéúY™ªVJ YS¤Ç«½x2{#`’öi”…SÀÜRúÖ‚MJôÁÉs<Æ„¤&7¯äíQR#x½gVNÖKó‘L/GCçñUÄ="’Qç-|jð{gUgõ¦ïTI½{üÜ# ÅfÌË-ü"\iXÌŠ½)Õ;¦×þzþ\Ö?k¶dð儦ÜE$ë.sgý‡¼EE ßwík”ÅDäÇ;Ò…¸œ]4Yñé^_>ƒ6Í‹/xd:mOYyػǩ 7Úr Î#ƒ¯ŽÍ‘F–AÄfîÇq’¥Ëú"C»ªS6¿eËRûªc'>ÅуŒhm€È^š±Ë¤m•³-úÔ¹Zze<ÀÆÏëélË~Ùð 8î¾F(˜„lf…xu<Ö2T-±¤nˆsÞTLõ%ŸqB)$,;׬‰´Túª—©ãóÞ™õê­›.…oRËÀìKÁyJûÒÝ—4­É3Ùb¶{x§ñRÄÛ’Õ×?séò†·+Bü8…Ê„©À_j.˜ÔYÝf=Z×CíFBÛ¦‡t·ž¨‰qÌ[œÄE±ƒKÃûëù‰¹³äm½¨ã¤íQ§å ‰Q;¸ßQ‡/š?1 ½ûtbº%×"jš9ཫ1rÉ<=ÙÞpÕº"æ1õ!Ú‚–ªÝ„.”åŽðQ?'I»+Bë¶Î ¾9УìÓÈVŸÅú ¹Š¡Tq¥ˆ+*¹åãêÖ÷VF#s,™6¿<(a¨Ùʬk–Ó¥ŸP¦Q׿”sN\ó‚(o[LùÖv¿PaÅOi³èÕè™ÎåLýühªDwä¹ÙÇöö¾äåôIÜ 8S‰§·xÃ4÷¢£¯#^î>¾µO\†6Ój¥Å»r4㮀·TtøKˆÐ“ùœ}lžžµ§"Ú¿™Q¥ùÂ56ðÀÓ'¶ ‡d2¯Zåe²áðáµÿƪçá‡q.ú'³YºãýŸ\pn}ÿÔ0› ˆ”§½ù‹giË"öúò…‰þ?-} ¸º›ksŽž9sUƒÂ˜Ö“#–Us÷_¾œ.~~%Ûa°›ÜÄ”G/Ãá£Ë@XéÕ¶@îÅaߢÑÅ×T·£vl¨ićCpKmE6ÎÆû¡X¡j7‰ùûƒYå.$N•ÂĹ/×~€èŒÂë*³nRªÐ[¦vZœ'ìgÌÓ_·!v<+. Óöª[ª“9 }¥äY?›Ãƒ%¾àÍdÖwâdA'Œ sÆVê:¹-νgt[ l~ð$Ÿô•­'ŸÝ,ˆ(IçîºT•¿.®ãÎÅ— À4-ï_Ø’•ÝQ®B¢èò×dG|ð(ú´&‰æ‹~!¸)­:G/Mç•áþÌŽŒ¨‹kâ­¡º;±ñˆAMý1|¦·î9ò¯>ïd[àwÔÓ>صSžrœ7NièoÞºm9,ÿ~àu Ò—n͈JÆú°»Q"Íâ˜ÀA9à(ò»õ´i¤E ó5ÚÔíY\â¦1—È]÷…ðŠÏ5,nÕa%Ù‹úJ3ø4?¦©Æ¿Uu,* À ?ÅÊ› ôñ¼0’,_t¡ºù~Žû(w†ølˆÑv-kž’¹Íå%²ØD×é#è̪·ÍÈ Ò„+¿\1ÿ–nt@òH¤ãVµ–Uxª‰{Ф+¥`SѽÃ4|ÙpîË ©¡âžJ 3”h©ñÅ4÷é¡*Q½T‘eo¹ÿFÚ“p¢k¼Ðš{G8ÞùeRlx«#Ö†ïë~¨jt»(ÿëLôàÊz‚?}MÚóÑ'3 ó~»YcWò/rÛ-éž¿öÂÎÆmkÙæƒú"\Œô»2AÆ- p¯šº7í½üzÚF‹³G¢†Ï;ˆÌiÓj +ý€"í&ç]/bÆï>!ÃnðS“Øóê<ÐËŸóhQÿŠAðg0ˆhvWö©Í}£úîÛHmÜÄ¢ëâ±¼I9[6BÚDõ®@1Õµq èJq– ïÈ †<ÆêJû]÷2‰·¯ëçg´¬>}d_p} ®ÛZý°=Ü—¿°Ô·AÅÎÄË#ŒõÔGñÙ™† “дÑñä»à·K«{ÎJâ¦ßÅt‰+¹‚yËr}Tßi‡â¹{÷çÚž¡ßtn4öôé|6h¯owåÒÀ+¬:!ŸÊ4•{ñÀóhŸ e lþ£ž€‰Q}|G[X[Ÿ€"m]¸Œ¼¾Ÿít:"€ܦú’–+ç(N!8n 2>mô¦ŽHw/,§ÛŸ‚ ]ˆÈun=z%ð©ÛÇù™Lb]þjŸwaÑïæ*6ÝÝ!dƒôŸ?ÌI&Å8¬ÞègQ¾ ^׿yuüJÙ¶`´t$¹ìp–y­šCò—v’Ój?Ex²Ñ”Ýà°CÜ“Ê?‹éí+%Í:~@í“´%¡{^ÿy^å®+☗·NáKѯ!±•nѽõÐ¥i$ÃVáÜ<ýþ¡RÞz‚=½{àô»;¨³^q¨„EûI‰‹5¢}ìùD'_eIŠ?µë¶ cßЧ?ýI¨Ê=öÎ0•>¿<;a}#%"TÜj|z¸\/çÊ©st]0k¡ïó¯~=œÓµJEuH‘q£lµ{ïóÞg7eÉÁ4Ñ»†Â»Õymø„uÍÛJ:-!B w”^§ÕŒÞ¯­;úñ»ÖÎgÅ(ä­)w“%t“DÆL_­x«©Ü¿ kUvd0;˜á¹ŽG6˜ÁhüXÞ5§\cÔ'i˜@ ñ€Ì,tÖ.p 0K˜£:“ßÞ)·2;IkÀN´ñôÖí§z&AâT}õ)ãò§t§žî6ã»ÆØo»¤dÊõÎå7žgÛUaÕ v™`Å›4M-?íêÂŽ2¢˜Ú¥*5ùﻋ2)ämR¤¨[þfÆ4!‡AÃt'yÞ¦q4˜‡½9tP{õæN,Ýi¬;˰ 7&pàZ¤rŠÎZëJOçÝ¿º4¹O€9ƒ{ßšm]ÓŽ)ÊÈ|ò›u¹G$ÕBO¥:Yð¾›Xÿòiöm7G\ïõª8Üì‚i;ÿ¨‡„µu÷—碞Y„*ôvL$/޻Ѭfž¥‰/#Ä•Êïî6 -Ü)¹«·)iJ.ו@X¾N/•ÍAÃÀº©!d_Â_Ï#?L*76Ä6áp·)bBÕöûzæ ±¾ò½÷325I÷WºxâDõužë#]áÐZ×>BœÜñWH'Ï×ÒjŸ¬]gª¦ FSŒÝ.F÷ øv¾·¤v‰MJhóìÏTë ݰ½©æE2Qtw™μ•§¸öIÅ­Ûi¿J“QèPÀ¥x#Ð’pöêõ<ÏÁ¬&FD5“ÜR˜Š”Æ©o‹uÉÛbŠ’•AŸÃ¹ÛI1ï¦ö£Øû¹G&] \+« Ž•¨jtÓ“›yi×gG²‘™;R4Ñù)¦“Ò¢À‰Ay‘]SPÞýÀgÁ„ˆØ+ÝúÚdb'mq¾©•*Ër¶ý+l"Þ'O*?G0—‚­ÂD# ¶¼®ñNø”#g’ºG‹ø:Ô™Š Èr7ÍMÄèNÕn¿¥r™¥ûñ¬óœsQƒÃf$Äv+vw‰o©—œlØ½ë¸øui"Ñ‹kWnä>̉#LfM¦WBãŠt7ÜÚ®ÒG™¼êe?ÆhIú~NӪР‘©ng|Œx^æGS¡*ÉLy»{¦Éµ&oDú­,c̉1U„Øãñ&Ø㈠¥M°!Ï6ß>«0"Œ£¹ƒ%ò?Êù©' endstream endobj 1015 0 obj << /Length1 2242 /Length2 17075 /Length3 0 /Length 18413 /Filter /FlateDecode >> stream xÚŒ÷p¤[Û ǶŽ1±mÛ¶mÛÆÄ“‰mÛš${b[['{¿˜ý~ÿ_uNuU÷sÝ\×õT“)(Ó šØ™ŠÙÛ¹Ð2Ò1p„eU$™ Ìt L0dd*–.6¦ÿ‘é™:9[ÚÛqýÃBØÉÔÐåS&bèòi(korµ02ٸٹL œÿ1´w∺YšdéRöv¦Î0dÂöžN–æ.Ÿyþó 4¦0rr²Óüí´5u²46´ÈºX˜Ú~f46´(Û[šºxþOJ .zzwww:C[g:{'s>*€»¥‹@ÉÔÙÔÉÍÔðe€œ¡­é¿©ÑÁT,,ÿ¥P¶7sq7t2| l,Míœ?]\íLLŸÙÊ’2yS»ËüË€ðïâéÿîßÞ²´ûÛÙÐØØÞÖÁÐÎÓÒÎ`fic “¡sñp¡Ú™üehhãlÿéoèfhichôið÷Ñ b‚ŠÃO†ÿæçlìdéàâLçlióGú¿Â|–YÔÎDØÞÖÖÔÎÅæ¯ó‰X:™ÖÝ“þß͵¶³w·óþ2³´31û‹†‰«½ª¥£«©¤È¿m>E0dæ¦.V&N€©#ÀÔÃØ‚þ¯*ž¦+ÿrðõv°w˜}Ò0õµ43ýüñv6t3¸8¹šúzÿSñ¿†‘`biì025·´ƒùýSljö/üÙ'K€6Ãçø1þúü÷I÷sÂLìíl<ÿ˜ÿÝbz%!A))‘/ÿ¦ü_¥½À›–™ @ËÄÊ`dd`°³2|ÿ7Î+ðöK -ÿ}:†?%íÌìœÿ"ñY½ÿqû÷dPþ{m¨ÿ›AÎþsžM”Æ_‡•Áøó‹ñÿóüíòÿoöÿŠòÿ:þÿ÷Db®66ë)ÿeðÿ£7´µ´ñü·Åç<»º|ýç†Øý_SuÓ-´¬©‰¥«íÿÕJº~ùçœÓ2²Ð1°üKné,féaj¢`éblñ¯YúO3>sØXÚ™*Ø;[þuï|z10üÝçê[Þ-Ο-û[eú¹Yÿ›WÔÎØÞä¯dbe:9zÂ0|Î++À›ñsWML=þq=½Ë§ à“£/ÀÌÞ æ¯Æ²±èÿý ±è…þ v½ðÄ ùƒ8ô¢ÿEìŒzñ?ˆ @/ñ1è%ÿ ½Ôô™OæúÌ'û}æ“ûƒ>óÉÿq0èþ Ï ÊÐg•?蓟êô™AýúŒ©ù_Äù©3ü/bþÌnhëð9ï]fÿµù”ýAŸþÆÿE¬Ÿ:c{›ÏFþGÂÂò—ÄÖöOÔ¿:LoòøY7ÓÀÏ™ý~ò2ÿü gñ'ø'1 O S»X|Ê,ÿ?Yÿ~Ðæðóô¶ ãçÉþêó£·ÿü<™ÃŸÜŸ¶Ÿ¯;S3—?RÆKÿµùÿöø³Ž–öÿàýùV¥wü3K!WSç¿·à¿ àüKhÿ¹Žÿ‘ñ³ Nÿ€Ÿ”ÿôàSéüy«þQ&ÿãüy Ñ»X8™þ)ùçZÑ»¸ÿ“ègÍ\ÿ?kæöøy(÷?éÓûɘ>Ã{þ ÿgE]>‹âò÷]ú¹¿ÿÁ¿2MM=La–Ùs‡XÕ‡t>Ö âºÓîO2±À]GÝB©ï‰b»* ó<Ý0D/ öÎD?m¡œ2•~´Xk`0Xëmú¤Gsa,7v‚›íÒøL£ð>Ÿ:˸2H÷ôh0Û™˜c\´*ýt¿˜£Â¤q¼Ú_È<ç!o­~¨²¸€¤h>£ƒ™Œ†Äâà`† éÌ쪪œ›ï–$u¾˜þb‚@3¾|€7*‰“x«Ö2èj‘ð±Kh29¯ã•ŸÿÊ$±]’ƒEâØé¤xmò*cÍC,’Ö8ÖS™ÿÝÜtGâåa×èdšBŽ"CÏ> ç~3!'Xe=Ī€øAl §Öµ–C¹T»4{¿†¹ZO<Æ»+« J=«3¶8âÉÙ‚X.ã ,xdPýwÝ“u#!‰¤â]gö² nÙïì-‡RìM8©Ž¤©vL`y”—Âjðæ±{ÊÃS(UYôCi‘E‡æÔXH^³å„^™=5ž7l)ûk*$­“;º^ RÕò J¤RBÞpœ6qZžy=g]ÑÚôÿ.‰’¥§ÎFÿw%TŽõ;êv‡‚I4Øëƒ6¥Ba\×b «-þé5É´³º&ÃéDF²–Dr‚1ÒÎßvJô™ „(ƒ˜Ë‚5~Ø–ýä´e•æk—׈àú%:—óüú5- ÝP¹]6N·ž‹#¢ºÀxŒÜŒº‰Øi¨3a-²Sz¹£…½89ké«Êñí‡/ $ü8ø°_pñwBÌb@ö±â{e{M´)ˆÈL_Ñ[Æ5ÞB¥T!^øë‘‚ÞÌ8ÑÄLÙñÈH£¡×:‘A¦Ï'ƒ~FÚÁr¥î^Vˆœ>rTçËŠŠì³ë1¼²²@æã²´8•NìJ ‡èVÅ6rçhiG÷}k.\?´…«÷F^ž×Æìòµq¼ä¡–zúElVƒ.eìúaŸQÉ s8˜ù1‡4¢gã0Tˆ¾µÛ)„¿?¡ ‚m„dÇÛœ†‘P÷qéÅê=ÿ¥N ‚5ˆf_ûÍØß0¯Á£ëŽOÊú°vŸL_¢TüZ–žl—%l³q æV$FѪDsuŽq€·°úû‰tDðh‰„VQü Äxž»üÏà°ôÝå6dätá$"ŽhÝ“fsc,Áå~¼Lû-þøß³ÙÝV}OüÜ’•˜¹‚â¥_w4z¤¥ÑGJ–?ÚŽ„®õ÷fÔ9{ÃkD˜$E7ÏÞÔï¥årꨙ-É\‚‚Ê`Á`+Úèì=à¶H~’+·[ˆßT°z‡Úá Eß—F’q{ÓñrE.×øê &Ň?·T©ZÂ=ò†ß¿Òqîürw¿ø`ƒá ŒD·{ÚEóãW››þp2“V¹Â‘p[«»ëRhëìd™Ï2Ä ‘dþUj| ǯøåã[L2'òe¥D}$U¹ø8³Šà³1·5á6@ç•8cè²Ý¦ž˜3,w¬L]ˆ½Ü[SË5„¯Iwˆ7Åbµ9¨) »†¤gm±)qìB®ôv˜w’ÛܺíZYïHk2hÂ9·Þ£ì0*Në†àé¶/JhŽÞÎü{£D)#…[W€íˆ}ý”‹¬ÞïÉæP|.Éåý"Ýe£côF?èꬽ€þZeÂv{œx‚G7󤀂Wß>˜Î_k=ëÅ~œã£'¹‹Ö“!gÐï§‘ý9ÉÜ(iª=µï VŒdñSÍâYCö+Ä¥˜†ÞÄÝ<‰brKnÌÞ`Áx œ­b‡)5· îVýÚë"ÉI.WGùÃ|±}†ìÍÒ‰™T‹e©Œ‡mÑÞ3¹lAêÌr¤í~S2rÌWä¨SúÑøâ|—ŽkK£9y7)ý†¡± „3}½¨kn¯téî—,9béPÚ©Á¢s/xÊFõ#@¿.ex]ˆÜ¶^Mõ®~•Wªä;Zg›—µ { Øâ-B$½ÜWtŠm£`'R•öºÕyTØjI) ¾ ªïŠÁóµÚ ºÄu ?_à–¾"À¯@È–ãNí¦®N„%ß5\¨ž½8¾NÞN"¸Á¶[÷.x—ƒÙM FÉR˜cXX8J|åpR“Í_©ßQ\:suJèípYNš#)zk1&˜ºïr^Ñ é‹´¼çÖ¼Y­‹jwg×sžoB Ë*?ü±ÂÞÖ³Èàø…§ÇïÑ¿áAs®û÷ ªÝ:xåÜlˆ£ HiiWKÁœV9á{ ¡þ~1×”Ë{u2k4vÇÙóK«ê *ç‡Ê+… 'w™)Z²Ók­È‰v˜}>mD-B|#—œ¿ö˜À7}þNvfŒ>a‰¾{³ZÁ:œ|ÉóÞ›/Ì ŒZsGñ=õ %¬7µHgD¬âWD÷ûžWÇöŠRÅ6ü* ¸n(oupäÕ‘¨A~ÊäØDöal©¦$‘ÔC‘™–zîÂ`šõ¤$I´ñq”P˜[ ÛòÊÀt§«Øƒ¸7- Ҽ͸ôd@Š%¥óœo¾„x³=ãÞ¨Œ×þp–ÏÞ¥ò#ð ]gjSæ\>®ñEP´Ü$19„®¡HÕ¢üæ0H[˜†»4a ì34Ý×µò¹ƒô¨põ ØaµDØë›1LëJ[ò­¨ƒ€¡Ý܀ɩŒ ò_êS 8ô,°šzò/ÑH=—pv Ý…|»vJ©¢ú±6l øHbgšv v-Ndìs×)k¾]d>½ª"±{…/ÉNZ ôÇ4!$àrÅŒ »ký«ñtáÂq‹²ávT…÷›¿AƒÙAêÙ‰ÌÂoÊF¾Y/š\šÊ}ýýëtà¡YçÁ~Œ6•m¯Gr´ô–DÉ]‡Dx8ãdÇñâ™Ðdûòå!ŒÚªB÷B+¾ˆ3©A%q°|i…;/G$w뻿i`P0o‰ÒP%‹ú›žI¾™0Ý×à•ÁÛ›¢)˜i¨¦ÄcóÇÃR¦ô\Ò¥Û#Ì^Ø ˜xÇfÌ‹êVÐõAG“à×ÁÃô1Öj¡«óAäÞÈ̉á )Ã*ŒÙžMhÞ=mŠP3ø2%߬ÝÇ0¹®\ ¯øéÀ…E*’sÇ–±ËŽHqf¦èŸVa€sró•·.Ó»_«ý÷À‚1Ï5v†Ey|`’/i:J åM£ÃO1·Y›UIˆ®ßC¶X(\z¢{»õ¤Ž–Äi/æwó¢ÕÜ8’Ó[ãÍ9”E}™ÛCU‘¾põS£ ]TzÄN'¥³ç£Ï3.Êú¨jÌÒàœ)Ä™g¤ÅQy_ “)l³Jºè.|GB9 žw5ë WS§@ü¾ÑZ ½>G%ßQ95éÞÔÀT Ó„ׂºŠ)e+‘;zw¦b¤~:SR+©‡±²%Ñ¿oÄ÷âd&çžt“ÃQ‰D™µt X‚s\ÄpþÂÍD¼dÜóS³™/“¢FŽÉ9kØyb¡d¦PMzh8%ÉJ¿/hp@ôq%)té[nŠ i+ýÜÜ Úðo™•Äy#FHÄ€æŽìû|Uqr2ðß šî©u5Ù>­ Ì•p2ÚËrÛb]2Sº¦¢¡Ÿâš·vSA/ÐlÙü…f•´¹ -®üšrº<ÒCå+—KÞRe+±%}ìiQ ¯© § ßj¡ûá¹V„a0xO=ƒë%jæ]ÙäSËâtðÜs¡)da¸¯¶ð°h] «AÜ܉{ ®ÇûU ´hÝØxŠŽÌÂüÄÃc5Î ƒBn¡¨W«›¦9ñFzÏw!~¿*¨ÒSs´LWŸRiÆý»µãa<©kÀù§ÖEg³›èõG´ä›M’ŠE‰£3½ËÚ·A\™¤ì.f.òSnYc€û­ \ïÎqd ¹µýÒMÀ)‰dqp§¤K‹¥S¬#¿e|u½4’b+¬ºis»Àr¡Ýx‰¤6«iv½#?&kÝKÐ@RÂa”>Û˜/#ü€ÄðëÂï vÊËŠY¬j,ìáå "†‘o½{›:K8 {QÓH7þµj›_Jž0¤/Q…ãòš-o®ôn—@{e”è|BEóeÄûHÕv%â›]±0U¤¿ÍÍr¬J™¨œ,XU( üKWðô8(Õ> )6.‹vÝÞÎ(A>PC¥6í™ LޱžÎ59ï‹DÅÀÜT¨~ò% IûùU/Ù,ß’7¤1î{F" $È«Wk(ògßX[Þx—°(gàV –ðØv„!ÑâˆõßD@]K½ÞÜ´I%ý‚5H()¤L2¼ Ì5Xàýåhø9Ƙ“}¾F á+·{y‘ZÍíbß@mHsá…èdÅd(‹þ.¿SG!$CÒ × ç ±j%¤‡Ï\Ï©—yZåÒnÑÄœ\ä'®dÔJÀaÀN—*°·Q$†jÁùB#Í1Uòãkæ]ù46ªRö§…¬FËÏ# 9–Úé7ð ÷Ïw,ꬌ& ò^n£ÉDƒ¦Ñ—E ˜\µŒ®l˜݆<[¡KvõW¥¢·í"Åk¸ñ#XP ö6™«3Ž&*ÛT;Ií zN~Ђª Ý1­@t‡z(þÕD½¨‰c».°Zqš…R™Éz]œ½¹³¶ÍjÌkôÃsKÜ™#†ó`óÖ‰¡ç1pÊs¹åù T­»ŒHP¹&ðø<‹À>cÜÀ…;õ üûÚlÏ $ oû—N¤µn×Ñ@UÔ­å'Ý‚(& ·hd?³B ùLRIÝî5åoórdÎzÃnšMC•?‰A&-‡;¿‘€ðl ²Û& £õ+½†Î EàXQ¶YßÌtxÍ3ýäi-.c=ŠõáZíÄ£¹cg>Î6ªºÕàj!„ï‹»ÂׇøÖGƒ/äS”Ñ¡sO9=+i_·`³G^à–cKæ,xCÄpì­b²»ëâÈðMÅãUµÛ•;ò«! ƒÍÎ丷8ÚrgúPÜ O-Ét›öJVåJÄæ¸žô°·¸öÅÝw=j“ñfxžÒõF}©j[‡»žœ1I//]žIÊr•¹1o5¤eeD Tw‹Š° qé òÓvd¨k äôñ Åcú%ÍÔozì*J,’T¤A1ñGšÃܾQtâš|2)Œ´˜q0™(-Gоf;§æ¢Ö*¨Öd‡1õÌõÔ‰™‘[ñ R躒:s-ì3 ñņb¿ú:Þâ#­òð*“ºÈm<½¾Ž¡»Šã,èFTït;l:³Ø¹µ•ê“2é}/J:€Þ¯ëŠ-¹Œ³R쬡"'9"ÈÚ„rü¹ êÉè7ªÛÅÿyh&ôû}Âù†s|Öüý ¶Z6ØÏ€£]J­ îg34_toüDÈ(Ï's¼¬Mµ1ÑpvBß8£°|Ê@“ñ«šmQõøíÕä>؉hmiVÀhÞâa‹M™ÐߟÃ×¹¦ÁÖC¼Ê㡨ƒ™(1±ÇÙl}öÆâcwq÷ÁRþjáˆ(ûÕº ªÚŽvÊiAãþ\Œ× ý7Ü»Â]$.éB³V ¼ï%°VêK¸°›„-ò¡~qè v$_ëø&†Ó1>ÓÝá%Žƒr˜oêæhe_ÅR‡PƒØGIÅÛ0ŠíJÄn²»×UÚ™]w´Ì†ìL*^ȼrùAI±Ÿ7%×Ó¯?=öæ aò«;Øš}A3¥/8•òôWF¹W}Ñ!턈!¶önƒ›ÇëªÎ}£ qÙcµ¬ê+@ýžbP5Ê …­¢x;³[è™âZÃGâÖæ DPÔG/á]äŒGÁêo„« Ȫ®jžU•,˜XO ·KÇ(Ç Ïÿ3q•ïà'4WqÅÃÌ|öü’„£ŽknÉ·þj)÷œm\àÌöf]dieo"³ËûñÑw/Ñ)6Š2þ6õë©‚™Ý¢Ç€P7¬øK<Ò„Òì·SÙðB,Ìó]_q•õÅAg†Ò'ïl,“EcÛˆiˆÕwìöPzÚÈ 5t¶âê5‚+ðp;ïÄ´l æat&mLÄ[îYRvx åÀîñÄÅB,Œ¿÷Éžðy‰r-oóû[¹UÛPxsW…GÍpÆ9¥xœnÚµ¢½[EIÓ²êSb•‘äA'iàÜ5ÁzÚU(õÀ¿ïiôÞÔ[И¼Ð)fèÏ6I̳íÆÝÙøvåO˜ó™ v¸%GMŽ ¬üRòâpzá+Ÿý¥Ðšñã Y¸Âß-’}ä;¦#ë"¼õ¹¶„u²3«!®¥4™z@œ—¼ï@|—èé„ÀþôVœYvT­w)¥’ˆ øv¡A½2B€‘ÉK4’ìA¬³jØ~›{r¦ëÞ:ñQ¹H/†­¥M,„ê`ôÀ=OTÆYÖH®îÇ¢da?»!oþ±$ÅjòTæšš^Y\9Ñôjp[ ä/k{ª}sÊ-J|duA}ßÁè6×hSΟ„WW6Ãá’(—Æã–ZÍÆœ|Ò&A~éFX+•dÿ(“$_6ßží3XjÄ< QkÜ™z: äï4‹Îf2Üv'¼‘žÀM(‹†i«äù5ªlfŸëÜ<È:.£ùë<™P¯û ­ã!…9¶âÔ6$µÛÉ/-Z æì‘Dý1Œ¸©þ- ã~ uT„ª3BŸrþŽæô{&E¤+›Ã׸jêöIŠcV5Ýò²IÓZØÚ*èZ>ìF€iŸ „ar?5H°Z Óòcδ%X}ÀùuÖƒ&H'ö¨¢·>¾% _JHŸ·Ó¦7³ $™jÏ`‹÷1k¬!î×ZZ)wX¦9€€(žƒü$ôz'ÈÀ•éÏóžäAZ™«ºZ?R€•ž…GMKÆ¿aÿPÊdŒƒïN =p5%å ^[û²R´Åx·åس‘8«ê?åß&,øB ;s$K&,7~oƲ¡.½YU×z¤¥«–jvVÈxœo´ùcì>žµ§Ã£ÝÇ­iø‹ù÷Ì&>âÆ¶Ÿ³¿V—ÖZáÌ!CîÍ7ç8ÓŒ½ÜÙ†™œÆ ÖÇ8Í™ï·ClȘ¦ÕýÈ$ ]^Â>&Ù\_¬^!™Í=i2Áà"E¥WŠq —{ãNúςօü°þS¢½yùíTf¶h'“¶éýóþõ¬ä"Á5Œou³A™vpvµLË}ÞjùÓÉ8Ó¸_’ÆÛ­J~“ðéöÛnFfa#œ¬4ÛKÿz¸‡g=ášG{kî$‰3ã¾»¬$È©6´g Ð8öq•‘ŹßXÉtÐ2ƒŠt˜¤mT<‡à8å6yÃ옣ùò•Ë â’̘¬·ÆWusïB¢q»/ *QXoAËÚš=Éáâ5›)Æ[Ue÷çý-:À‰CãÕBß,eýíg8½M©q“¸—‡çU©Á±b-‡ æP![}^y6yW0,[õѺ'B ¼ª‚í'% b¨r’Å~|øÝ¡† ½(OYOŽõÂÃ1òrÊf)§ÞQí_–0ÜJkõ{Êá‚ EBÌÂAfÁŒ ‘HÑ!oáØb£"ÿ¶Dõ0Öƒ%[´}œ¨ áº>ÏŒüÚ2 ºMÁËÇe|§Xv^ qªÓÐãnsƒÔJ©\è.Aɘ ËW_Ô÷ëœÁ3…f»ÌÅôà™B0»,tç> ¬-=+ºL¸ãpn+ Ã$h»žÅ%;Ã/NV¼_áöˆúôFp˜_5E5cúˆ¨è ´Ø“icÖ4—cÓèOºÄËE Ä»½Y±ðÍ u¿mØ!²÷Žv3w½Ÿ>ETÌSêEÉ(”yÏu2¿5/ȔֽìõT*xUØ=§Ì ¹ŒãÎ.©3ùÅ2’Ûdê„a;³XEDUf[¸Ü0è.õ~R÷Æ õè@7e, ¼û«…Ý{ç­á7yÇù)!b/‡Â|{uŽ0 4q¶úýåùÀa'ƒiê,à‘Øûd7ipxÓ1*ÈÉ´™DàÛüRkÀ ÈÛ *¼IéþÄ:ú.+ÇûÍ—/b*pœ÷&̓^€Ì¥¨ó6œ]ZóÈl2(2S•?`ØÅj9Tæ·†¦Î!¼É–hŸ»´'%h™“‡±af¢¥,)Èœj’Ÿhûõý¾@Œ1ç¿w%À7‡‰»µ{=Þãö[“¬iŸÒ¨ÎÓŽØkWÆ»FaÌQRBg¨]2Šª„¯SgÔ«÷í+ÒàÎd(ŒŸ! ò}lTû×óz$jàl'ióªÒŸúë^´Ve‹F %<®“±!Ð'Í­ƒou\?üz£²æž5»:°«*Å`â²NN˜iŠ`‹±å{e€}SŒ³4A{ë$'\pêÔ)V«9JQê¥ex;u°MnåeHÌ(!·µÝÆ"U¼`(Ãó“wkºšk¦¹ô ¡î61yõ³vš9E-²É8Åô›Õ^Éc‚äÂu— eܤðRÎÛhhm˜rÔ¶»sf><7ºCœcôW¶.¤fù@×sEkSV†+·z+½‹#jPQûR¢ý‹P¥¥¸7·…¶g,i³KÒØ÷ÝtxÞz;Ö´ÛÜM|~È7#¾2µþúH´e±z=§=‰Å!šI7øJbÞg<Á;ϵ[Óýº?0u#ŸR­ô•ÄN¿ûÈÀê5ïîȇ ü°ÛƾN¶ŸnÄÑwñvÌT,R¾ c0Jkº¦¿&-¯}Ì<&4sõ(L ’EéËûñá,v5’OúaÇ¢¼ò•Gé]eb'O>w?˜úÉ&™×[Lå'jp æOn…tNï‚]KÆÕů.4$’ç^ÈãæÒ›æ€U½Ñùº™«|œ»Cë}­Ÿ®JÂ\dC!ËóÅFEXÑÜcèú¤G{n´—-…fô€»fB£dïàþ]—ݦñe¤˜JÎ9àñøKm]kl^8¸%UþU: ,õ1~90Mš„´î—æ÷2ñ\­Äç‹e‹”ü›MHþà—@“#±yâ¹ þ媞•Áqd~öïã$d×c¤?ŽüY€rP›’pÃÒ›‡7 ¿ÇÉÃl'ðÔT˜Àà†¤–ò[‹Ÿ‚%ߨY-F®|«oä&R@Vw VÊc•Eèy”õe‘™—,Qdñ¾‰óóša%pÞChPÀßTÝÛ™½s¼…ôÝ5ãú˜ºd_§ýîñ¨L¼ço¹êçÞ(aÂc}T²Ül{ÎûûCü‡™ÏI#Г[«½°}ùg7´N¨ª KWœº"Kƶ¤Ú,O(„^8èôG °’xÓçE/q¤0)˜ÇPÝ‚ ø¥ßU/~ ‘àÊ\ê|µ\r–àS3b]#Ôä70£á{µÓ‹Ð«¢© o]‰«G}ª@×~ÕÚ8mHì›~§Ç8mG›+wBÖ¯k1âî·á EhK}ñ÷Gí¨ÏGTàM¡hx¶“ zn:ÊÕéêgÁS䨓РÞJ@²||Ô_£Ñk~Y÷x1I)CL¼9‰çÉ©¡½’‡&½wÛº#S߳ ± ²îpò¤×†å´¯g>†søâdÁlü[;ÿ¤xçáÀœa[w¹4ñD‹¶ÀHF,Sk!Ó݇^¶ó—òŠ©ðÝä¡;yBÜ‹39…‚±œÝ^=(¾µÄ½x£¬ùÛÔ½0Q:ѨIé2ŽL-§Ç.ŒxySz²Æ(”îæêœðŽå"í¼¶š‘ªF^ÆÈ×Gíl››Ë5¼x¡v-uvþ7“ÑJe31%éoúž¢rÀè÷“Oâgñבï#ïzÈùˆ§3é¿YûÙ½›j ~å>' ¿Ò+Mœ}}àb ,¼‘ü¶Ðê8:ºrúÀ{7°9¸óÚó*²Kù0àèα­¦E]¤ƒ2ܤ¸Ñ£zOòuœ“Á¸ ²ÕxDé¤à£VÙÄf‚¢ÆwY4H«lÒJÙ†/¸Ï½ƒ û˜¥QP±=Çj’š2spg«Æ´:uêWEü:×½»¨¬²g(¢Ù{œ _Ô—^†M’ržJÔ¿¯Ko™ÿ°Ð™ý‘FÓòu7âiÉ(~4Àý~;•š¥ð±Æúº‹7æûøA_'G¡_ –àò†æþ…ƒbZùÅÜKÙt>"Éc–.&œšº¦•a™ D*l¯^øP¶jîX}O,PÒ`ÐØ:['êTM1äÕò…·Æ.éŠ+{Îá¾)õf8O:£ˆ¢JÜIÈm nùì{ä”ã²>h5ÆCS_Ë€æ|"s2z à+=*ØÙÂ…ã”5Ä_N?Ùê`Žâ€ßG•Ÿ.õíÐ×y¢ ëFÅŽìÔŒÑveèî¡%crÀ"­9+ŠêŸ>X ïš!¨¨K]zA¸$J";}g+ÒûràSGYÆÆ>Ñ÷•4”YHÆPLüÝÎ&Nâ|U3¼íbL¼Ð5Úwì¹% ç–]’ŽQš'„ar"¬§°#ÞíûôŽŠ»¹qWÍF(¡WÅ B¿#útÃñYÚ^ï× U¿»‚¢vUµ†»´ã[t1YÂ"! õm—t…Ô³Ÿv?RõCw+ŸŒ£´«-qÞ/6àtá"®?øqD“ý!LÖa8˜üÐRù±ŠÅ@-5µzS²ÚŠsßâa}ƒ`J~]gY´­é‰+ãÆÏüŒƒý¡Á½¢òN;¶SûþNv 1ÇßÞñ  ñq øŽ~¬ž9ÜDAí(à­š·‡î&r9V¥FmWOµ(ªs•£Õ@••}uÈ*ð2IòmýÒÝ[M“gæšX7 *¢Xͽ=³\øtÊŒF×| âËZâ}8éŸGK |JL¤ôÁ5£6gƒÂh¶áwÍâæÒŒ9>‘ׯØ%@]%åþÅC㵨ù!ÞæÎJs0Çɵ'€)q!;óô뙘ãEŠ«N-€ÕG¬`÷Fnðµõ’#óO•\`8ŸI×µÞhVDûô³ÏKg wÞm`DŠîƒšv/¨"à× 8š@WíG‘Ü/xÁCȸŽ<*OeWcbz ív+Å_ºaRÅÒ%OUf†µâëL¾ò®ýBiåH³Uâ,NN°øÑ¸0 úzÀš´V?ÚJŒ6«qæÕëÁ`,´uó¦âÙzåLJ5-—¡ ïüµù ¥Øù™2ºSs„ aÉ2;~KòSD­£•Ì·ù¤¥™` WýF@Õt®7T½<ÀßÓIŽõH«ŽH£êš4OÂpÙ¥H§áå–¦òÿbzH@„Ýmô1ÀÅŸ‡Lbð.ÑWu©Ç¤™‚<²ºí†Át«KÄ)Xóê@¶P³\W:atñCº-ç)²xžqmš&sWµg´Îoý˜ee¼vLþço×Ûªe^¯rXú_ó›±õß/ßn}ú½H~°ÉVÅu>x’Žæ­pI D…Õ7†ö•è›¶‡{[Ð´Û ”.DVãÊ FlhqIwyÌ›«FoNGŠÅ‚ŠÀ4Ï ÷æ0üZÐ÷©5ñŒ¸‘5]ç¥5SÞÄ í#‘€“?Ÿˆïå,ýk½RŸfN¯ÌC°ûä‘u‚Cÿ}ŠP…·ÜÚ§­ ½ ŸR±Ã èM ïðâ.·+w²“=@+fÒ¬¸õq¥ó{Ô®°rüä­íBœ8m¥‡OÿÈD‰Acó\…ñU±á^>ƒƒÌåýʽi?Ïx–ÂA!ž%L0“©ýà¾;'W³ÀG•XÑ‚B#F0æµSU¯¦pæ÷` 2‡¸ª™Z6"°»…}›(Í}¤¡ÖÛ¹&’÷Z; °ëŸ„ñݯ+)±d¥›g§ß1¸\dÑã…ìW|A ã{“@Ÿëû„gD½•=ǯcW!2˜×>&ûA*œ¢ˆä· E/’òB1`ã³E¨¶px›G"Z»ýDè‚È«’‹Æn‘0=…Ût-1Ká}çï,ˆT¬m*éY?fã\’Ù­ab ÆQxÓÁôFzf s±¿Þ£“”ÊGÃnMÊ×/7ЀI†/}·¬–_]ÔŠãbqr…Nü ¯W¢{u<¾[«’ˆU*ÅÈÁr¼ë+Ò§3aÿÀ-:8²ú²Ó¤WªåÁí¬·¡EÛéÃȰ6Y#¼`Þ½ ¾"…(»ª«ÌG¤nŠ<ÎY|£µ7ýZŠK›ÌÛÖ Yq®¶Ê3nMòña;fK3'ö@BþÅsŸ$lC°ïüÅLæ@F5òŸ¸®±«*9?å›xg}—¥.ìoHƒ(„^Ÿ …Xö¼wÛ– n í¯¬ÈûÙÊè#J¾Ù.±!Ͻ„8àt$€éQSœžá"Þ'¡#‰:Æ&òí6—’†û]emkLGY¡¾ÞwITªÅÓÙ;2ˆº-e³–@Á£´Ã¶3NîXý€’¶±ŒÍ…ø‹÷mVDt”±ŸŒ,ž5mRÊíYÃŒZ+ËØ_ÙˆÝ1j« A7óT߯„*a-Ü`:tIÁÎk~Ø$<Ò­<`a‡'²Ë Âô|{Pw½AzbÝEéÔ>Çy:¢Ì²Ú *¯ÿµñp1É¢Û+×gŒ¸[¿½°H8Ž18×â¶¿g™»Ýe‚~_´Ñ,Hkг—²V?u8Yµ”þ£"tuªWËJ†ÁvÊТm޼KYØòÇ~ïVÚ×z×¶‡/ôÌ|eqðð>3“–Xé`nÁhCáω ÒÕRW,`ý®ß¸:Lh’jÁfìuÅoªÉ4ŸäuÁ¿á $J€Ht YÓV.Crʬ,ì0yÒ¯œ2Z4OÐeÿŽÎ@hpâ™ûºœšE‘s=¦[ÏâPÿý ‰žš4Ð\a[ú8^ ·èWä‘Ö®¶õ¼TÞTkëzá¼·¬F9 1 >ØŠµþŒ¨»¡æ$Š˜ä/&vèE˸¿˜Ä:Ú‘T{).¯á¶U%Þ üÙ|7Èç€ôufÆ~¡*-0'‰è‹áæÙØ{ÛЊ\¯Ò‰Ö…Sœ)bBÂSœHž6}ÝòC+Mÿéž÷€w‡¼ ÷Þ““s“ÜÆ8ýƒ{@¼NËu¢ßƹI&•÷í·•N-èt½}æ‚XàBÖD¤‘1\’„×ÁrÝ–5:ÔX0Îóv½ìÃV ˺†Õ´«š‚Îþ—zo£Ò qÏæöQD2ÄMÝïsi®B“nÞ=g5 ²V6ScÕäŽL®á®¤ ®|’LK~T嬣n±*=p\™¯Ñá…Ÿ°›¬•ìã Æ6,°"$‘’¤ŽºxW|@{ÊM²¬Z£½çÈw'…0Œ£E#0tä)¸)Äì3±³¡mä^ùZ FáÜ9]1{]/äÇì}¾ä<ðvÀ¥¬êùÝ|;vŽ^õP®ÖH€×rÍ£µ‹pûÚsø)¨—“m¥"-¤&Лշ¢T‘]œÊvÃ]ðEá^­'À]zdÒ E íÌ^ÆÍF2´Kgx—½¥”²ÙÔêÎRXœ¹Tõ·A¦ÍVðü:Ox6½áÆx+&…WFÔƒ¯ïó Po@Bº\† ¤SqoZA±ÓmÓcaôbϾü}BÐ}ßæoïGŸÜ~†º¶_+v!J62ÛÂ%np} uD¦f)ø¾ød ‘ÉgýëPªNFvÌÇ N”Ú±FÔÄ}ÍCP’I÷#®ÉŽäÇ]Àl®ùÕ0i]<’”¦ñØú]Ùû‰< 1Ê×ÞPPQÿy™7lÔ,`ëp‡À5_ômt<ü#÷TÝ5q¯tb¢ÙxF!"UÛ«Ÿ¶ƒ_/ ˆ£—0O¾ÉJúUØD_ÐxQ¢¬ÌynÔX™¯ñXá ñ˜s'Q›8`%ãòWk0h´€¦|S'†_Õ×&'tïl…^P =-]@MC~%’ù‰(÷\Êî²Öxííoˆwâ…´±t팸‘`KÙŒ%öÚ?–.–Ábà6Uù´¬'Ëüh}¶`ëÙC ÿq møH™ñ¢ÜÔJС|ùP œÄºd¥möífEˆ'¨ì‚ÒËé]Jóí´`·íì[ù®Æ‚.ýŽô¯ããíº@=Óà‹%ù,p\g5|2éâfßÚ(zìÒm`¾=t ^³|r;êúÀj·Ó¦@™;Á0mÿ$ \Ðy°„žŸ ªÖ#1@û¯™:ža‹œ>@yÛß 8ˆüØÃÆ%5…ëËš•g« JW/?~ÆybDÕºã›mÓ üÖÀ_nýÅCoš?&4ÓP_ȱDäœ!O¾/O¸b7T¥Ë—ªœŒ®£KcO^4nœòJˆ_HàR$æW¿åÖwß©2M+’sÂ6È+Ô¸¼Bb‰J âJïPÛ oU‰1™“ íî³RÕBÉãºÞEÔiàCé-æ_H7lV‰(2^AMÊ78¿``Ô»+WúUš¨ ¿Íf^ U7k¨´¥Ðpð˜^xzÞoª¨AG5á%ÒˆJ’¨V²Ïm›§ áaô-0ïRÀO‹"W¥šH¹+¿:¤Ù7Š/½îÕäñ`3õñ{Ò‡T½£Ì7ø4¥4 äÓ£šV;›3ú/í¯yêÖuj×Âï.ˆ¡­\ÿO\£ùçt0(‰Ä¾Fi*¢%ç´ æœ %—&-1øÝm,{ xºÿ¤±ª9äÄç.CŽU“kµ¡í%Æ¢ÇY¹‹ð&žn¶ƒ5vûä³z'›çÆ,ÐÉþÄL»ÝúBƒ£OéÿE% ÁÂy})ÿ-üP:ÈN“²ÃÁ7¬£é¢ac”(<übå™ åTø•—‘äŸT/´6Pî|ÕÌÌKq±cž ÷š^÷ëë ‹Vì‡U8’Ѩ* *\t’?[Mó³ïÎJ`ê ²@0˜¿Î¹I¤[éÑõw$’rf“O¸Í律ù{$ü­!/¢Ÿ‰‚PC¥¾ ¤f2ˆs»åÇ×­@­¡C7UYþÕ\ûƒ×°ë 4ÞQ÷å‰k‚œý_ä/pñ7Ñ[… ?{xÏàqóàùÀ.|=_¹§‘ÆÕS+«°¸¥ºÕVolTV;J;„_‰Á(, £ ;¦>{±$c!¤:d•¤I‹ ¾ÓÛ§_¨yÓjŠ ©Nó¬Ñ©æ/*­`û×çÝœ/¼ö9ðÞ,º†òúâÑmÃp¹dí 0›¡mQÿ;›|mO\Ú@D²Ÿ\s‘A¸&´U±¿)žÄ2†©.¹±/õž{…“Ê ‘|{ÄÇð¹¥KàäÞÈÖ)K—ÕÒÒĨV|rˆM0°&¯³e¨^;lkOïúçæ>3ÖPÈ¿K¥úS!XîÆ¾\„lèÏSr:’Ì´+ÃZ|…ÉÙ[c•“6a|còáHq( úÕ¤iœ)œóþcÌåÔi§3e¤”bNíý%Ê}¨i¬‚Rü½°ìÜôRòâŒÉ¿îï¤ïÌ£ 5#åq™–ˆ<½HšXïüÀÿ饮ܒE&ZëD…=R™wQò•¤m³î¯ŽÆÝ3ÍÏá·Qã0Ohw[¥Oe6±„Fd0.óâWgK5š›íS à®»i5WyöÌZÃE^Ä„ö}mÞ{#ŽfÇBwúÒ,t)D<ÊÂÎh>»qh`8Ö4Š:—S±% ÿK…6Ø3Îö"ºo@ígJ`TŸ·iå)ä/ùý<@åV·ÆbÝ{íM‚ƒë^G=mÜŸüY+² cÙºW#$ŒO§²É3<,lÌEe´¦jb\ž§™Ð Ú•·k0úßÔ=bï©TäA}sÍäó1¤ªÖc‰Ç®&¡I{Ùº¡Ñâ°Lëߢõš« ¿Õùà`SË d4füèˆ?"ܬÅý§mºV¸Øâ:&®Ò[bLçŒÌÖñæ'¶Æº {x·hPó £ÄaOü„1\.ÄÝ ç¢'Ń0×_Æœ@sÚíš¿“qºÈaÈá! ˆÛ{ÌÿÎ^½à ®S´‹'ÉY¬ü´ä4©í9c†w)SÄÒÑ_§ž‘•Ðøúzt'¯!¾ÇñˆÈ…ÆùŒrßÃußÒ;‚rS¶ûªâ÷vÇšº·¯Ã 쥰JS-Æ»k÷qMÿlÖ4…Ý÷ZÀN _Û¨¡éá‘ÞÀ;7ñ;6àŽ‡>Ø >]$J¨›è³©LE98±v7jj¼ÍOàÐ1Òeh‚•×Ì‘Bl{QzÙ"XÜä×ÔàŽ:ÇV¾ÿ8žY‘¤€<ìR˜“x\vm5úx•P¹0!doã³.M0Ù¦FlÆ®7j²¶Äá•â*Ä—+ þ=£Îg-g‡Õhî'M´ÌuîÚÞÛkv»•`!bô=×Ð:©¹a¥uµR´nl«ô ßãƒy¿ëöq6³1XôÌ mE®iD˜R¦W¶s‘•_Èö»ÿ÷qÿ½ °c0‹È0°30ˆ-1‚P@v:æÙ¬¼W&rHq|ÙUäd7ahXÀˆ˜hº®£0mdtÒWÁ<ËpA‘ìæÖ™ÚõùS»è{˜jÝÊ_©1½iØ×žåZ¦”*kЬA~ÎŽˆŠR¾¤ùâsAø—Ì$_)QØfW²J²e.ÑESóîëÒÙ '„4uÔS\¡­rôoȶKÏ=÷T±ÆÝuìÚ…¸¥4åŠïä·¢ç3Š&—ÚÖÒÓ' endstream endobj 1017 0 obj << /Length1 2726 /Length2 19054 /Length3 0 /Length 20607 /Filter /FlateDecode >> stream xÚŒ÷PÚÒ ã.ÁwwwîœÁÝ5¸»»w !¸»{pw$879÷Ü“s¿ÿ¯z¯¨‚Yݽ»WÛÞ%©²£¨™ƒ PÊÁÞ•‘•‰… ® ®ÎÊ`aagbaaC ¤T·rµþWŽ@© tv±r°çû—…¸3ÐØ$“0v*8ØäÜl¬ìV.>Vn> ï œùÆîVf&€œƒ=ÐRÜÁÑËÙÊÂÒç¿4¦´V^^n†¿ŽDí€ÎV¦ÆöcWK (¢©±-@ÍÁÔ èêõ?.h,]]ù˜™=<<˜Œí\˜œ-„hV®–U  ÐÙhø2@ÑØøwjL”uK+—ÿ(ÔÌ]=ŒÀÖÊhï:âfot€¢Ôdß”öÿ1~ÿÀßŰ2±þãîïÓ¿YÙÿuØØÔÔÁÎÑØÞËÊÞ`ne (I½grõteÛ›ý64¶uq7v7¶²56üEÝ %ª0eøw~.¦ÎVŽ®.L.V¶¿sdþíTfI{3q;; ½« Âo~VÎ@SPݽ˜ÿn®½ƒ‡½Ï‘¹•½™ùï4ÌÜ™5쭜܀²Û€Dd@W' ;èzšZ2ÿ îåüKÉú[ ÊÁÏÇÑÁ`JègeýAðq1v\Ý€~>ÿVü/B`e˜Y™ºL€Vö¼ƒÄ@óÿ`Pÿ­<z, ñc°üþùç“>hÂÌìm½þ˜ÿÕbf-QqU]ú¿SþG)&æà ðaä0²±³8Ù¹\¼\¿ÿõòOþÿÍý/©²±ÕßÜþåOÖÞÜÀûŸ@µûoîÏÍßKC øßŠ ihþ ÿNSÐ/ÖÿÏ+ðבÿ“ÿÛËÿëðÿ_FRn¶¶éiþcðÿ£7¶³²õúÛ4Ín® ÍPpí‡ýÿ5Õþg€fVnvÿW+ëj ÚQ{ Û iå"eå 4S¶r5µükbþÛw[+{ ²ƒ‹ÕïûÀÈÊÂòt •3µÝ). fý¥‚6ê#JÚ›:˜ý^=6N.€±³³± h¾Ø89>¬ 5zþ5Úf&{WÐ(;?€¹ƒ3Âï–rq˜E‹þƒ¸Ìb7€Yüâ0KüA¼fÉ7 €Yêb0KÿAlf™?ˆÀ,ûq˜åþ ù?Äåýâ¢ð¸(þA .Jÿ å?]õEWûƒ@ÑÕÿ Pt?OëÅÓþƒ@ñtþA¼ Kã?uù4vý£4ùƒ@dLŒMm\l],ÿ‘²²qü;ÿ1ÕÏÄd½UæÿrÆþü?kõDÈôÄ Šiê` š¨ÿJ88~KììþÐü=jÌfÿ‚ À?@¥þO®ßz'7Ð~þWº`˜Asekl÷// üÌÿxY˜[¹ÿËíoµƒ›ó¿€L,þé-~?ªÀ›€¸ÿ©¨I–^Ž–@ûY€dVÿ‚ òÖÿ‚ öØü ‚Šó' .Pl¯×=¨”ÿÊt»2ÿ Å òeZË?E…¶w³3ù}!Zü‹èÞgvøCäÓá_§XYA‰:þQƒb8‚gûÿi6ëßÒÿm5(;Gнéð§y ":Úºý+ Зf§?IþFn@—¿.™˜sü:¸ÍLþ”ôXüGø?LØyÿ–þ/VV‹5ŠT‹?8A‡\€vVÿ;ˆœ¿m€îÿê'ȉ èýû'P‰ÿÏz°‚Xý zC˜]-ÿ+Pý\=þuäÃíOR ˜}Õq1upþw@“àþ/"ìñ¯9õüEõúCtÔèüŸÿs›º9ƒZæú׋ º«ÿ‹ÿúZzMV—LùC¬C:êE <¦ç)´2h}V;ÝžP`Siër‚¶œïDSGûÞ­ïIÒÜŠ|#ùåsÖÖ þ5Y¥ýÙ÷Å0Quö ae{hºøL´ižQ]äÐ÷—“¯f  dx·e“Šrƃǀ´gÓ`åÚDØÒÊa—<âKåc¬ḞÀ²ÊB“ÜE\2WF"8:ô ·wóèùÓo$r‰ô~ç±ì%>ºÛlq‹ÞÕêl.=xxº¸D·è³T>bÇir8Ë>å¥1[‚Ëy,´L`[ƒ$¾ãݤ|zïeÑqXlWy¥'(üÚ›˜µû‘àsÔŒéÏP–qéÍ=<¤¤‹”¾”Ž„ÃßG8Ó›)¸ÇÃ*zùî¬BÝêœÝÊŸ]4Nëyé™ïÂ#ìb­·ŠmHü wòÃT€!üyÈÓã[l]AÑàÓo=}î8ïyè©Ö9T%y醂[œš‰ú£8ë37åhâmÇø:Þv0ø½´z£xߤ4Ö˜œ®_9. 't3x䟽=<[¼lS¦Ke9MÐ[I¬M/t±ª!P2£’¹ó‹—F+åøÈEäÖÌjEfÛ¥ÎÁ'Âî{ + ŸÍÐÈ-èŸÎ[…΢ tsÃý¿´¦kF)ÞbFÉpê0ÛÐm*>.. LÇ&œ,ÑŸ¢*ˆ•Eìã8^¼¿CŽÙ‡ICŵt´1oPÔ«É¡Ä{»©“ê¶PÍ”¯hÒœLP›WúÒó†_]"x[¹«7AØŸ¼ª_Oþ1cBw¾WwÅkÌs¤.¦1¼a8P‹JB/qþ,› ½åàë"?/a{¨²ß£_WâVwÿ¬ñí’5“ᯩ؂oã2$-ö‡±§Cñ£ó ­ótžv_±ujÓ1'„Îב™œ0ªÍ}X$z|¹DªŽòOrùõO™ëº,}§g˜ÊTE¡6Gëå írlï Ö©´Öp¢7†}ˆ[‹¾ÿ²“À߸ª"ÊmNï&ø¶˜9Êž %ÿQ;¬„[[[t]áYI%Љ?n#!FfŒÞ*L»!߯1é!óÐzPGûVrÙ­Š¤ãçp»ãZ‚˜lGéNa”û¥¢€ÛQ¥3–ƒÅ\&sa‘ã»›Þ9²‡NgZVÞA.[‡žëÌÜèXÚ·O1Í9–?3£¾˜äì¼Ò­AP ˜ •EQ”C‘B³#ùß‘\WÐÆUøjÌ^ UœÅ˜ãÀ¼[0Kï++¬ÎÎáœüÑáOOð¹øÒš»—òÌJä-{c|6b\lÆ)_c}Fê¤á>¡5ÅUr:h®u£Hy¶(‡¯ÿS£”ªpcnjîM_©v¬Aés «…Çý[O!siAþön‘ªÝõÜÞkÆÞ§³¬„'´‘­LÛ™ßFKzéP©¼?åŒ2õ´·îbÛí\„Y2ÅQjìÒlª("\ò·…¿/`kÇR¬ßúKa39YfôCßëäß<ÛW–{L¬*Öj8N–ÕÔüÜÍRàm€Ù7Ä”³˜3ñ ÝMGšèpSŸK«‘è4 åÓr"Õ÷·*ôhO6z;.®€‚¡>è3Ú¶4€éCRW—­²—‰Úî.BëœLº‰»ï/0B߸[Ú Ì¸[ÞP—;Fl¡ÐBUé°¶ÞUEhtÏV—3Ÿ+=A«#PQú„ÐàÊò1‰Ÿ[MÊóu{Ê 2b¸ïJ¾,pxrGĬ~}‰Ê`ø™Wf¶kËIm2n²áÄ&sÇPJ®?æÜWT´¿×¾†ur›$nnXRHèúÙkñ|²`Æ Áëpñ‘n 3 }çkêX7Óña¼õ²ÑÏ5@ìœ&íÊGÆEaÈH€†”×2î‡÷Îý& ½Ü`î[Íó7Ön÷|pí—QëRM¨Á6œ‚§CTÙ:…çVÄ«?ÂÆ}qÊqsÃÜÅ뢕Þ{RP ›±'FRÁ»r°J¤=U¯ÞC…ÃýŸ$™hy>‰æ¸ѧO9œ®ž¦ÀÕÖ {c’ú¾ú×ÓÕNši &@ÁÒ2¹ÊZ:%.¿FÓ±@8]|m¨: QÄÖ€d"‰ßæFàUrý¬ÇîûÓ™òG›ãÐÊëó ìVªV¡“ÄûÁÎŽ8Ÿõ £FÌä3ßådi¹7oæÖœcê.]ŠÈU°Ì…©bžØâí¸ø!ÝwqàÅpÜ[>uï7Ñúï5i)1ÐwŽmÆÖÙƒCÎ3ÕŠ_Äíý8„ZußœGê}Úqz5tßx%+ó—¤kwÜ9x¿ m9à9uM2ï|à4lŒ éZØ’–‡j‹YÌøyð]Z2)ÎW–ˆ–ï®ïZ£!µYÀ½;Y·(¸(°Zýžµ¶X­¬v¹¹Ž~Qtq4Áë››Gïܧ ÕÝTŽÚø6n¯ýˆZ$›ÇËiöÔÆÆ'Y˜’»ëâX7iÍž±£ƒÉŒÉÂLò·(ëã w޶\·a«‚w¿¦¾§~•…dH!ÎÎM¼Û3ËŸžyYæñ]_“žÎÛܸúÀÿU Á~hÆ”-b«Î“D{ ³€•T˜ok­-íà¶+9qÿ6¶0eÛì}ªEH”Z7PÏ;+8 êÛ²¤M’8G‚´f| … 8W ár¿õv+N1 †„·òl6Ú0r^C§rî9"DF‘=?…AÇ‹ÿÖf(„ˆÌªvªfý ÷@‡â2Ôˆ¶¸¯ævvw™: û²;MñA]FJ¶VÝÆó{¶µ…IžL² BïîUU!SÌ D:e±£SwåO!lÿj!ƒoO†o>I“¦úÎÙ»\µ­a-m·…#›Õ®2Éêë⿦—©Jü3N»ú<˜^_ZÅ"Þ;#øš÷|®¦ H= úÑÝS>ÒE£ ?U>¹š¹ag‹ƒ+z›~nÏ*{â”þ8é¿Ò÷%8e‹&Z0«"DÚÓ7qñ¦îá;˜6Öm®ÌâÀ¥GøQÊé¶%(G¬~óT“,ÎS®³ÓŠmÿcfÚç¥1µãá .ÏõmÎOùå<Åu«¨Lγ)•gyd^•pm‡ çƒÏ˜‘ÛÆ›VIKÙOÊ“6öÞˆø—PÎöAaŠr$-§¯ÑÓ7™¿ ¤jlª› oº”¬»Ó;ñk·¾Ò7Ãjñg\*5Ó£i+2Ò~ônÃVÊ]ëh^gó4Ÿ÷°öþ‚1#—{ÏŠ-Œ¡Ð<"ŒA6˜mR6¡Ò‹BxÕÕfnÚ:3ŸïÜÜY‡(`aû1ö*=‘S§N~Z0PíàZÿÌ A$¢8À–sQÆe;èùvkè”ùf÷kô„&á†Û¡Å¾ʯÂè¥Ëw~Ô¶©3)"u݆J²[mÜxÙÓÌ> PÞ^ŒfΓ¸žÈæ…$OèÜr[³K×!Ëó=÷Íj¹{ÔùøÞ>xmg&-%ó¦6Ê&p‡ÁVX úúJ'½ ödçkHCÕƒ¿D«VRÌ3”•Ÿ3‹ŸïRIfÀðô6e¿(À{hÜçœs¤¯|`ÈÙ¶* ×1Új£®èëÐÇ:ýTH,¦kÍýø• Ç{ý«À¦W Æ¡øŒHXºÎ§0‚| ý¯ã[vn¹aS\Ï~J'x’Lê&-ºh‹m³Ð Ù£4‹š/ñ `š 8TOÈ≰‹gZN¿ï   W8„É¥ÇiõRucµùjéÒ<†œÎȼ‡9 Ÿâ6Sêÿt8â¤fœxƒW·^ƒ“Çç‚C ëNLG¦ 0Cœáu²¼kÍ«(û:cˆ3Örq•ñCrÔãþ{b“¬^†: %{j¬Ñ—‘ÊšZR|É…0j~¢×PVl@ø^XΘ?5ÞcÝ!€íaù|õ÷#Yá”I€úœH™ AЇã”u6Vò¢¥6ë}?õmù t³A©ªÀ4ÍÕÿ§^NéÄ Ï;Ãã)DCx³tzÛ*u2b+®zCwgM¥5ì¢08ðs˜´£ü JËà- æLÏöÂzÅÙ‹¡y 6á ñKL•À*LrG?YXy½ ÇÁ†®ù{ÑŒ+Uå Xe+{-uðƒäâäí3£×)¥ˆ$å¡,Û‰ø;uº,ꈓĔ#bß  …¡YRÒñÞ.^ßoNÑnn@þ¶ù(‘b¬s dˆîÜÁ±œ¼(‚÷hÖU™Þ›rä^ljÙqú5‡ˆ5 a®Jßj*¨lñæRµ¦ÈCôšµ0cgµÆ/YS÷þt@?GÆ·F-¹¯¾!¼@~;Ò Û]öýaœ¨¹ìਾ§}µÒöå¶‘à1s0r_~¢Æ…‚ýuøX|ÙÛMÊ'¦£nñ. æLƒ¶z¡ºqÆTDPD~Õ4„9Vö‚E~iûÂëwíRCz×ÖB6ZÑ%Ÿ­ò‡«=Óàåú‚Īroe:•ñŠtµeÕ3:’#[Å œ•x ëÑð LN7ÃÁ2H\B–-\öÃn»~AHæã-•ëŸMnæ?w‹®©eᡊÚw…G1œ¬+¯3iÆâβæéó>Š¢ÏÍ8í¶WpQÉ̤ˆó.Ù9Cûös;7¢ÿ~¤ä ¿‘s~ý,°ISe!mÐ7ÐÜô±ÎSùÆ @~ws§w[çI'Tb<™ìáK ¦°y+7qú·¬-?´¶$íñ}‡ãˆ#ö—ê]zõP /÷íÇ|Ï^©®¤%˜±d@*¦ÂÄUFŠÕœ%¯¢+QR(oP»›•é¡Ëä¾\€‚©®ïç^Lh ñ½Yb«¨eà÷`Ä9²{°çÆí®!~|v_ÑDo©Ž;-Ø5B™± ¹²¼Úo˜”9e&zÝhJÂý׃üXùªá[mÃ’5œŸ„Éò´|øke¹.c!R´!¨?˜EË?þtñc‹ÁóQ¥õÀ—;u…Õގòbw‹QEg‡PÏvâL4ñ%þxö”$pÂöÜÃg"ꘟ‰_ò^{A‰ëè™ù5„ÉôÂu'Dswsb9ñWp¬k‹YpŠ[i†Ô· #/?éÓÒœ1aZÓ¤uèÍiYoÜ;òˆ¤eS M–Qè{1EöŒ5ÜŒ<]Ž÷’*S62”¼0=h·õÙ”®] œ¾¼k]JËÞ,LÁoZUÇ-ÓD²5¨Æ=ëÈTØÐBÁ†S×aÀasŸ°<¿)xμ ò#ÎÖ…tŸÐÂËJËÙdCþ»‚êŒ= ›Q}IŒVaÈŒü#ãEf#G˜2Ô£©Ý66+Èò'×qxf½‘=_~ñÒ-0}cg®½Eí[ä­/ âÑQ``JØw‘*ç‘:FåGFr†buÛÄ–e N×'m€ñN8Ãlⶒ嘹~ÎË ð:™©\*Ô<èk¥áö-Í-}ÚØcÌC»õ'Q.KjÕ¢#ÒÊŽRÊ;U €?ci: X4ŽÇù4µÔóæ@-¤s*õžÑ;2na{•±7›独xm¼ëH[˜hTÆ–î`Ó>l-ž³R"4"¾}:× fG|¯Õç– šÄ/ÅûFbj÷}ÈÈà èÖd©'`ZîM^ S&æîÙmÅ„T ‹a2°µaÁïf?wH뙇^ `Q%W(÷x~i¦’EÇÍÊ|;+Ž·¤AO/8öæ ÒódQœ> -AÍê7ÉÚº×z)ÿ\}1‹™×#† rEûê=ë±Ï?k fZ›Vw¢¤ÆsŽî“›ˆ²˜«S-ÇaƒåÒöšÂ™>Û5ëWø!7mí–Uô{­ •ä½÷ÜÉ´5Mw­aË?'?“1Eôt¼™"ÞIfÿ¢ÛE@­ÇQ» âã&¬»µÆ·Ë΀Dª$m¡.…êÆdoóÄ Ðs\îWA]FàÙ'ldº|åË7HWðéç•LlÅœ%„˜à™ÝÛsø¦E~Ö¤å²Ïžä×÷.ðð£þ´¢è¯YOÒR¤ ó”s™Ãõ}«„ÈçgýãM +Ý*K{1ÍZýÕÑ•àí%U ìÍ»º­,ÍóV¤“;ŒîЬHÖ|a6oˆ#§oû3\ÄM9X¾ëðaz´ìƒë<Æt§\;L¶æì ,¼!Ï»"Ó g՛ϧŽZªæ‚ư?°©q”Ù ¾Fç4ÑXvñÎof;˜Ä¡êè>˶ ¾dK¹#¸ Ó¤³WE/*º®_… A±¬¾KäÚQÈNL(Áxõ;¶Èi…&OÇ]™>Ì üÒJ\9X#eg·Énד¤³¢äÃé¯õ¹KDƒ'XÒàö¢èŠ/¸JŽ ÿ£rN0ÌhKi$°¡‘À‘,sŸ{†qh”_P¤M6R¿#b«úõÞóɬÍ\ÙÒe‰¿X—¢z¿lb/±§R61Pñ=-"‰†1:>Å›ŠX¼Ý‹ï~‰m ¤w¬âÎàšãO>ÊE79¹ˆÀ †iÓ–Õ»Çtz«™«Q¶q§©–Õ®ü½^\á1–6UÆïÊ{”¯Ôðµ„qذE‚Ð ¨„Š}ÊrC Û>'%A£jƒ$Øï&PŸ9äÙnx’4êeßi¾,aMU=5Eê=-´ æÙEGþ²)aȰMh#K-:¥‡M‡åѰšßJ²•Ðxõ·~Ϻ۾9¿Û4÷!õ³fâÝ<ÅOï .“´ª¡C1}Ì·,|Ó½›—d½ÑÒኖ;irÇõÏuæÚ ÏÎñ~ nÆ}ƒÑEÎϾÇVÅË9Àž·CÌ5æãбDgRÝäWx¶ ütq¶µac²˜æsgyºÎO°>[4­9ípû?£3;;DÞå!³;ûÕj60Â^@»â½ƒãƒQmY)y*nò$h° pnrÓ( ®v‰K`ÿU ?¬A1|ÆÜŠõ¥Âwãc-¢×Îøàû%€ëã6a@ÔŒÁ³Zš/ÃbëÙ´½úð8 ãŠr™4ëQ†Ú>Gjr[¨ÖAíb\zÄꨦ@ ²Iæ¨xõ¨ê¢Úšümù32cEnjû”1±3Í´;ŸeÅœnêOGº±ª QHûÇÐE9#åôIŸ _°è2% +ï­æðƒûFª]„ŽÁ9Ã;Xeû<]òx#N›×L˜#ŃºÌYʬ—ü?D‹k'•¬/Ç}ÅKŠ1›2Nþ{ yãEQýKMŠÙOq€EÜþµ¶˜Ý`‘*ʺ7e{Ú}ÇrçûH;ô«é—œK!ÃÖ5ò:­áÍlIýñ¤Š1Ø%–²w¿Êwrˆ‰ÃJ;ÅàËÅ¡2EØÆOv¾!·©°ðLeÀ6é10 õ†îSU%H‡*¢•-s^#;ÒÞò¶R3a<·~Èõ–ȯ"vJÁ!‚mWjvöáíŠ$WèÑxâf‰gHÄÆ© ž3 l²ÔZmÚ«;ç‹ÈPû]¤óΠDÊ ûb¸û¸ YÈO‡FIµ3Øk>Á„Ò|5|ÌÆ?¥ŸÏK™ ŠÈÝŽÍ‚¡/úÐÝÃç]Šù4—åµÕ-Ö.‘Ì–B³j„]Éf\eÙ[ H÷ù‚ º²ÑØÕFŸ~©WÔpl•D@ÞR(g`Êå &Úöþ:ÿŒqÿÉÖ#žf¾¦†çÞÖ{â°°K úóž™üèŽÆ„¸_”g`9Ìœ„3§9þvЉӪmXfÖz\†B§:ºqC¸×á[D'—­¿ Á—÷Ì—­wõÍ/”FðxC8Ack¶pÞš¼eôqLkâ¼^±mƒ…ðŠËö»ê5‹;³·’–”âz6+r5•9Y§–Y¿xx[çDÈÒ,ÔBH+pê”#©Ú®ªßÑB9ÍÎ îh\Q9ɽIâKÚ¼kó¹Db´tL >Øèÿ¡1Øõƒ)Ô=oûFí»ÃásÖ<÷–x扠¬óoèê×Z’·Ä]Üm>Øïà-»à¨×ºTãŸò¦¥‰WÌê±î&§Þ-DîE#‘Q_ålÇÀ.Þ†t•|ÓL4Ë1Š ÙN]¨p'Q˜Î³Ã´VIsDIý¸Æf)UùÉmc²^N÷™^~Ø×Ü']ïÁå§Peǃ qê¬ÞåÏÒwæ‘z”XD|ƒŽK„å³÷æ½.i¸óeÅ|Èy—mŠAãÀmøˆ!%\6Ïר÷üNæ¡D‡¿Œ7ÎßHEhˆ†˜Êj°  L‘!£Ú‹6ô/º€6†äd?¶¦ôdzu°á+ú:œo ­ÄÌC·iXã…2Ól «úŸ–МSSbZ'v *¹EôŒM¤ Yœ¦“ó¼ÕIé® ç¾‚ˆÆ’Ùh½¨^Ùj|Þo•}K³EÄ{™8SÁQxÉHUê4ðîöŠA-a“-ê;‰P/‹Y<ëRqb´e¹í*stÄÜÀg×ËT röfß Î°"<Þå×j3 ÅŽÞÎñ8)hEt©Ó‘–£”@S îS6‰ã¾ù…ÄËüP†©#9ò[þÕ%Û6-½~^~óèÑHL°'(/ΑêbCÑq–׫ž!ÜQšy¹”ÛÀPá/Ž3âzzõYéÞÀc‡ä@/5‹ÁÁAFÂÐë"höS¸´.êRÀF!êÖ–°=dÊ ñ¾”'©Î¤†)d$ž¸éCû'@…ØE{[_²•®ËG~Qtï"b²ú^¥exª,Ï]¬ÇÁŸÙÇ€¶D º¢Áï~a®’½.Ú*ì»ê0¼Q´ñ%#&U6Pñ¡{¥¯¾ÂF±#|ZðÙ~“”¦W}°L¹.KCi^o/Ç·4®¬Sõ%Û½çõu¬©—6ýnБT–Ø%¡ÐËÂÖâÐû3¾!™aa¡,€=A¸}[……•ß«R7Ài\8³.¢ä‚Q†²:Àh½²Kk±ý†¡Sw:"’˜rÇx»£pâ0×ÔJ«ÈõÙxßý˜_BÇ Ò&À*WC¼©? §$õa¸#ògø€°­xã èênëÈ!Å»zh>DóY‰j¨îªJ*ŸËËôª}ÖòÙú²—ZLÑapEpN:/ø2ÿ\¹Wð0\qc‘Öæ„Ü"Va€¤ìº½6@­—ßÏÃMzžaL)>Ç/þ}¯)Þ¶ËêÃÕ€¹ ɧÙjâEÊáÂýI‡ŒQý)zRîËÂAÜ“&èáøêÒQHåeÖøíÔ,óÑ6uÅ» N÷n+óQéøô%%áTàe¿gl.-E#7¦°qÏ%±{ =´:¤ïÕ"ÖéÕårÃ"¤f|L°¯3¡i./è#ò!mê[,4”÷ge?çôÂ[Bánø4¯ä2ãѸôÅÌD°‹„cYÀóâ?Üøûb "Qb¥Ö¤N=Ò²ªÌýS#(EP<ÞRLI‚øõvTÖ—ž|ëAßÖˆQÆTúŽ· ç¡J"¥[ªK®ÕNkC3Oà|]}Ù¼.u»A‡…ˆgǾÐb’/•Ùj»Yå½øedÒÚ`»¤Û8°)ÒÒ`¹njèDxù&[D÷* ¢ˆÎr3Ÿ/‚òØŽîFp¢Wo}"ÍXDß’"ÿñÇ2iZ„XÊêÛ¼ì6Ü'…jÓóå!³ˆöøúãGL4ðŽóqÔ…ýMI9YŠÖñ5ݶtZôM<줘Îܹà¿Ú´6= h½8ä»^Û æÆéÓ»ƒ>ié D›‡Ý›®}§&¾|é©Z|+'ÉçP·S¿+«Çoî’Wy‘CæëéìkÛéëxë[£Ir/i´5j¶Àòq°|y u¹t-ÌñÐ)ZU®P‡Ó\h›Æè0ï:´¿l#šœöàÔí[ü $¬åÐ{w¹Œácwè¶e°` _w{LÝ{§/à7Æq+cÂBJ:ø5݈ ‚ZtT’õµda¤û(<¢S%Pf¸JÝ«ÆW÷òE=-#*™ö‘ɳûö$ÃäêXœ¤· Ê¡Â,¶vÄ€îŒ!9j™ý¯z’—J2À;ºóìtJ²ZÑâÄe™Cø{ çäòkǯšÚ³‡{ÆÐþ^6loü—¢ ZL vC‹¸¡{EÆÙõW‡™Úè¶¹» î¯ìÁŽ:rd^Í›éþ²°ÅJD4wß&¼LðÌÔ¿§}.­à´‘Þ]ìÒµËÖßN6)cF“‰îîöêsÌÛ‚!¼]-dÃ[(¾ ºÆ£ˆ$°Ï/A×F|4L¼ËÌÖ r·åД|ãš›•¢ô‹qî6hd ŠN?¿ÿ…«F»liE&Iññ°Ûá¶úyw, aÝvïciëØò¤D¸?ÿé @µ·B¶9…ëš$EY¿€@ÉmžeЮ‰”ÏÒ’™¨üáJ´¼vø]òP†,̼äJ@±¥xãyKâÅ>C±B¨ä°‰“ž}î.øŒÈR ¦Íq¼bœ–+\Á¾O\œNÂkÙÒ£K²}1",4Åðš¬ßý–TíåR£ºHá¹çOëŒâRêMFx øiCLiû¡®A>ÑÜC\GZ?e‡n Žû뜊Zë€oF³õ¼˜(IÎh•-­X5umoWUC >[DC1‘­Wô°^gúÞš²†ÃHÖ«¨ž(/Ìš8­›ü¾(,Upˆvö<+§ki8V»g6GßÖV2©q¡Þ«ÀU‹Bõ„¬¿8¬Å>ͻǟ¤OŸ¤|Z9Eù·ï¿ï@o•¾‡xÀŸþÌ#j;¶@.SèqGîÝ—ùÀU)ôKŒ]ç¥=NiSqZp¬coKó¶ûj!s‰"Oº#+V[¼ ÃÙÑö'ó¸F¿$ÑçІûÛg ãc”»pâÌW®Lé»eè ŸµÝ‚]Eøèj%:njLÝ^ÌCº¤0Íê°Á0ú%nÆw›Ïâ¨ý<˜š9:â>‡™-`o9ëä÷ñðûÖÅõñžÕ‡ ÌÊôNëÜ÷Ž_‰ïƒ×Á Í´‘F(gw“j޵Ñ$d|ô7s÷9Æ&˜¶„Uçe¥·­á—fýÅ”ø2ÊÓo UXöû7¶d18q÷+›ÄáÙ-­C²(ß¼?¨³fía ñC wýpõ4ê<ÂñèY“Ü`í£÷,¿Ky¨1p)nÀ{ðÕ²yb4ðjß±©gáªFÓÔÍ)~ÉØBÂÐà³Ý­hH'<†²Sw¦*ªizF£ŠótuN@"¥sé‰ CROŒc7`Rp.©’‰ÄÊW _hküY‘¿Îdè_A½?ªùò1í± ° 5˜DFÍ.ÈÖîEf½‡"º=APKUJšÔö•Ùx”ïÑ IÂÃ!X c¢r ¸™_›8 -çæó›ëøÀ¾rÂqG‚ ë†çÜçX¦¸’:tíú„öÓqQE‚ˆeïå3©7È¡¾|ƒÄQ cÊø”! 4·.oEMæxR–h÷@|nw/Œ%¡–Š@ðÊæÅ“_^o<ûºW;?9Æ0x¾·ÆÓªWg¾5„/íût4LCdCë<”@àÔTÓäËXÜÆ”¹M¡X¤øK94µI7ê;ä¦ ‘À—¢aÚ˜+Kÿj±¢R®FƆCSÅ’†{ÜW× ›Ýhý ÝÄ 4öƒ)ìÐ Æ,q‹‚‹fx©”¥®8yZIHmyw ãnŠœ­v5f±mûùï<êQiÇåÃ&0&OL÷Ü eoö4'4\à­bÍJÂ&%Œ¢ÑÅ·«hÙyÅ<'-—9XË'V³9f;!{cY¿Ö¶‡r8-µ?ý2À¡R€&Q•ªƒ§ªDó£8 ž ÈjÇb½+~qè”ÁSu‡î‡Ý*ñ-x˜WÜÚÊ‘¦ª^#á¾Tã‹E¡G~›Ùþ…ÇïÃÿRZ)ß&epSkÖñý Ü7üøæ2T{¿ù#žÈê5¢`[)؉•Ï #øëy†Îél*´—|ãhiI\{ ·å€–Œ,ëÑá8¶Ÿ`Ë4>&ÛQáBárÙ“•WOm§ôMl€ Vä5|DÁìXøá$8…·ËÁ~ÃL=Ü VÔm8Ž}fp?àEdQ õ¤ûžÓ§÷|:…! :¨=¦‰Š+Ÿš±qlQ/ÇãÇÙ·[¯F #úø4ÄÙûë÷9˹Ð]ï}ò›Zð&€ßñc=|m(ù6%>?W«$Ð\çe]…„gÄýÎMè;ÚÜ^ód\×χ›ji Èªã»&Y ×ÛŸØú½¹€Úˆ…'C1x©õâÈlkß>t¢:3‚Ñuú‡§p‘|õI8Ú …¯­“’AqÙ!צ-×ífzÆj*fòÝd;5PEË)à²p=ë`µOn!y# 0DvUo³‹ëX¿UÙÜ‚W÷ó=*×8%Cô,~Q^'3eØ«Wc$JÚãê€&v$þQµ½£ 9ÖˆŠ¥Sy6ƒú:–=™Á¡VÊ—!Ìífùs}^™fêSA‰}Ó¯˜ŠÕ(Â}çsˆÐ³ÖÚmc=¾pmdéUìTcxñÄ~?ÓÙPßê“’c§×E ïï]õ@BÌŠÓ/Ãæ—?Ã#;\&pNêŒÁ”ónm_1¼ã†¸Îxª)Œ©/zÚe÷"H³æÃ#J¡7“|H<¸=ìC“´wœDެ?vi’{y»òÎUy®æ±X{i¶Ê·UÏk¥UQˆúkCt'Ëèß Dfžµ…ðéG]¤ÊËÏ’?}é'ÞA¿'YãÉn{ö´]zÍ6Þš%ú”é­>Û Ä)ÞŸ¿–'ì¼ÓUG·©¥ô3€yºJ¶.T±ñO5|¢½û˜(e¶xE~Ç^X?«°­ÿž´Ÿ” ‚æˆ=ư"ò¹ã•[W M³ì™#ksãÅYdò×´ÕPF_òÍ7ºã‰D”úïuï1¨¤1EÜHv\;Û§Á¾6¹ɇ|f°}ŽÒèP+ãú(ƪ%ícñ¤;u²v~åmß'›V•’ªâýLÈòºrí½û̔šÌ^L¹›7Z¡ûÆ)r›w†}\Ý+Yè1úºëÿ)Ú ÎE$•Œí ¨¸uù]ùJHÞ2-ÍŽG˜ ì=ë(óZ+ï#ÆùŒLùðÏ/%œai‹m' mÆ9Øp˜ZUê,Ot–ËüºÝ€G’èeFõvá=úàF鿌7Çýص^$Á±)ŒÕ³kgŸÆOBe[Ó×{_óóÓ”:•ä›ÔÛâáü‡Ö˜WTžaßWyaK°ÍòOqžßw²Q"µ\o:Œ³\˜ï$Ø)Zn`w4y‚éù†6÷`ãӌěïû#—5¾™*”$@öŠS Ë&i5ëÐÑvMh6ÃL¬gž‰îáHd©H¡qì–kí—# wDÞÎò±D@d&ò‡ 3± „XâÇùÈgZ‚Úäõæ7úÆiÇù²Ša³¤À”-ÓßÄ7Š0g‰IÀ¿”jªJ<Ç9jùEÐm“ØädÛÕt<[$†Y&’Z y¡± ‹å‹‹µS®l¡uýO{1{ÀxÈ'y3^~µÇF‡™óôÂÙïô²pÁ™o5¿=|€f…¼ ƒr1Ö• 00}KjŒèHƒ·s€ºßÉÅQÿís 6`“Ñæ8© é1æ¼Ï#åüêÛñ–-ù¾¨EE€AÓ‘ñö$õÎâF)Îø;÷Q®-x¼¯R!}˜YØá±lž3¾ CÞ»M&!諭/EËÑ©>2,Ä¢´¸X^­²ÂTÚv¾5 8v^ìß|÷³~Z:0lÞ´êxáÛvCzÿQ8„ÜŠÏš¸­“-)Ü£áXðkwÛ­6·¡+¤i´ë7$dK"ç„­È Ù¥à%BZ4 ƒ¿þô…—ê˜&ãÏÑzC¾07#u…Ý£;Z''j‹¸eƒê®ÌU‹Gp‘|ù›5Ö^Ui7‚¶Úq¸Ñg 9)CÀdeÅv#öÖyá­4æÞÖšu?gÍ.žå‘ÎÖ voÆ“êdÀ–Ä£ç×}>G†¼_•f;œF<;¹ËÞ} Žþ<Ê{º*1C toÿ—ùCÜrV{eòaœ’éOÓ­×.s}Ñ2zö`8ÊÍF­³\šH UxwcŠ#¾R{z¿|>Iwƒ å×.ZUó¾Å¨ˆÕ¤YºC’^‰Ô`ÞÑÊ$~F#[¿ÔrK³'>ùþÌfvÒö—ñÃ|ÍT¨]ñ÷«çŸò‹¾¶è*~16ts!pÑã3¼üÁðÃ)3 ‡#°I-Ísñ*Ùé¡íF(þn!ëí#æž]„R>EÉ ±Âzþà\"·l~ñ'Ã,`Ú3’2GÅ·WîÔ&/%†^@Ü!j}ÜÝP«Þ¢ÂUaÒˆ~þøA×Bb@mâ‰+¶"Þê–ÔLx°Qó·Ô ÍÙ¹ð>m¹Ù,ï»(3ööääÁ‰:%“XÒÉ gýM¬!tǯøÊIƒí© zO[qMä8ˆÎ~c…‚PG>âR&œ{vͪ¼úl‰ÔvÏH¨—‘ì^I: lxÇÊZ{q¾A%W1˜@ðÒ*åìéyͯÄó yk¨Ît¥ x‚‡~: ã1 ði’ueF=»SW{–œ@_“ÏÌfÍ)º¸Kñª"¾Jd4Ae¿d sò¾T3BóÞ®m,,»¼Ä{"r$Ý#EÈ0~¾ë‹W±•äñq…àG•…ÜçyÅк[Ô4ÈíG̸ÃÌÈL>wE+*.#Ïxþ?Y%­U†mZ»:ÐT³®®H­%B]çÖú°Fjƒr¬¸»Wauþ-溉ÊDÎdÐÛ°Ü‚y7ÖãÕ⛟Už”y…Ôˆ=‰ÎÕÝÆ²:9û`˜%]¤J޽è´ïÁòÐË÷ÛG‡ÙXbJaÞ:Ò'ò·ûõ ÔªP²:¯¢¦uüàšÆÀ'\äìÏu.Ô&ÛÆEœS#9Õ’йµè%²_ütÚý²`ŽÅ}ì0êÀ\Ó[z-ÒÂo†ºfå/#ÇÉEuøØV„Ç XÂúîR£¾ÿàܹf<2)þ$ôÿ“lñ®‰"±Ý‡ØM[å±O†®>°ßG*š8pá’XŽa¦œ«Àï>e®KgÍY›¿yYÌhûÐr`]ÛR­9®0 êØDÇã6^¼ñ€(Ïå Žúc¢wJg¿‚[Ä)øúÐ@ƒxkÞ¬jÅkþ‰ypvFÝ–ÒMGß3­ïòº¨nféB‰Qñ›'èå‹VÐ’½³¹ñ—Ð dŸ·Sž2â2¾îXJ3˨D,¯É 1ÐlÞ¬óœYÅ=ªº ñóˆÚáæ‡zs­I‘zlª2 ÙÃ+0Ïb‚ÓÕxn³m‘ ÌotÊ6ÍŸ ¸Cʲ{ø3 3=\²²¿êí¾f‹©áÚ!ç¸ïÝàä€ùË„P¶úᕹ‚z_{³o1›«,¸cìñxx s1â®4‘ÉϽqk$cX`¦“^ðtõÄõú%KžºWÂ(Û6Å;h[QÆ –¬ôÞ^54¾¬LšüÔ±ã+ÎÆŽlkË6Žm²¯&‰•Nᇋ¾ÄtÂÉQGC=¸`!ÏúK¶‰;UüdxÉæø¶0ð®óÚÙ.Y¸SüÂ…Ÿ½Ý .ÑIuÜ(§¸GseÈ-®¨z$|J³ÓñbÑ€e RãliÆYR†¶3 é·Ù{¬W pŒ0º_TgÎ-‘"­ù¦ë÷F‚(¾Äò£ÃB¡•å|Ç©¥vU™‰Ú§Q‰ÔhƒÐZñž\L_}Àa³imÜ|È%5Òì8›Ç0²‡5ë°H'@œ£H#8•95‹» üå/ÖÓO½—KuƒÜå$× <`^,n#àkî6 „¶¦ž¯SžŒ¿‹Ë³#§ïoy\KáêÝŽª,§D:Î9zÚ»"þ£v6ºE[ô'äÐ&¬Y¿;À«6¢/,Ÿ¤®Nýy†b]¼f´&F‡V2÷ò%´ùã¢HJ0›§=öuBñ…¦ÿʬ5ë# OOÂVˆô»|D8,È‚›e·m±æ‡&”­ê ÁAcIk¤­s¹Œ“·F«êMY>ƒæ.üÕPa[Öåûú WÝBWnš¿Ÿ¼© ÄÈÔ`#CeÝlÖ,‹gÂ-ضƩÁÆUÔÙ4v @ìÆSn´åu%ÜÓý#ÚÓš^ë,RIÍ|,…Ê%åù²Ÿä›\myf_Ì¥ÑP»¸0Q!Vqme¬ö –SÂrñ†%'A—dîVðYÀ.¾vÈHÊ»~ûcô‘Ýq&ÈÖZ†í3f§ž- ýé_5:M)ø‰É•½h¢e™p/ÒüàËh4ÞTÌjáÒ¶¼z@ªØbìs¥#èN<+oÎþ¼ëf¢Óï"“r­@Ó"«B?Y½b¡76á-dW–þ9˜X=©Él >ŽÁQô"4/äèÞÖö;¯d:ÜÝÕãäàÍ2ˆáiüï6ïcî€O¾J—-ZÛ³»â>n[èØ·=¬kžÇêßâ ê”LË4¡Eȹ¾¯•k„ù/5F{ÐZ||¼¢NÎ˯6N­>þV*òá¡Onk;¼¿AhÏÀ¥w¿jŠçÍþtiRœEÐß7䆽“nÀ+/yçhwfAðť낣MïÆÍ”>ï,0|Ÿ¬7‡©FAŸçÞeÜÑ­S5{ÜŸë­>ZtGìƒó‰qg…@O-p†…ìxÌs–j×» nj‘i߬÷¾%Ò!@žožõgjå;ÍR »š|³qéi¢Ü·õÒWPÓ4›ÏGSì´é¥s,uŸ°„Â=ù_lêFB ¸ä}Dð—È jJ~—ØíØê¤àñ[©EˆÛÖ–ÓC^#÷9Xq­¡×tY!t‰?ܨZ'Pw—O£òÒl¯ ´TÌÝÈ¢*";´¥¤áb{ª–s@Êøf­³o]ji$á*QâNEõÑU¬÷¸ÄÅÛy‚”ËC zÿ\êx†¾#ª‘•+j¤4œëÎ Z1®±ü¿c0]ré\ílÆÞФåyKÒûuÛN´r Õ·“  s‹ØÌÌD³YŠ,3 2øa°È7¸mpâ9Þ´7}ã.”@xuÔÉýŸwž€ÊR@t©œV¥oMªBo]ìAÏé5=)—„µ#J4œËY·üœâÃZsØ–o*~ËÁMϯb^Ç5 r±!õýŸˆ g ÍãwV  ÷.EÉsq‹l´úª®z¢-$Þò?unj^îê£Ü6.yšùëbñw¦Øa;YQVüÖâ7=èH’^'Yd&‹G)€Ôóˆ´~ø‡°Eþ}DŒÝ,DM=uÈó£üÆ¿͉vþ}8^T „4EuÍ:È[å´dÄ`KN}m`±HJå‘`%UdÏãæ…•úŽk5 ¥lO ¼­! r×v“{K;Ö\²éƒH^ƒßKsIB„V§eÆ{4øÑÀjºlõJʉš\Da–í½uàÃ?9ŽY›A'ŽƒcÙÜÒz%G—2ufÙûdãZ¾TÏ0¼BÄ"N¢ŒÌÒûç©„øyÓº’ߨ ƒ­£œ N^VãÛ|A¸à…]#*s˜7PÌ-¹°ÖưùËYª8²þëD‹Ð!æèùaGNb7£„ígA÷{'õvvôýfgåXb\êpôóQz䱯‡_¤ÿœE.yu¼òÝáXoÞÝ¿ÎãÞp2ÈJLH³Ä§€Š±{ÂŽ»Ÿ×AÃ?—âT_´Ãg æÞ!p³ó褋˜Um»½Z+â5ˆpjÕ³¤üGà 6NÉåœçkŒ¶z“àÅ…Þ ·G³sÁ‰Lmê­·ýÑÿÿgÇH¸µÛøcS»Ÿ­ö˜SŽÎžÄ/blÓLö¨åDy[³;ÏÙµdLùx³œ#¨²-Ÿ¢>0§Ï¾_BCľ 0MNãæ0Â('GM„ˆ»~ ­y`kЦ_;à;E!9ôçÑE.[dÁ(ƒ’QÏKŒ¸aKìbjŠªUGí˜û ‘J[éY„s}Üó69ôq󯡬^@®':ÓÆoO¼ÞïµÜˆ´SÎpGî8&œR:Â3Ê+ºÈ1tâWüÜióÆ™÷œFøÜEK¦@}GWd]æÔ˜7!¨³°Ls9Zm7ŒMæã+•¤;É@ËAp5ãCŠ„MÌ3®ø»××[l־ߥõÝÏãßÙyw:Tž{Ý 5B°É%‹ê›‰ pT™ê­&xÇc*‰xlÔÃG4머®Â=w„1@6*ÓÝïBN=íÓˆúiÒ a‹"ß[ÇÀÌŽ‰¼›[*•-UZ1ûÆT€IÍë7ñ°™{I!Z¢Ü%çüaRX]ΑY &ë ðÃúw2 6kï™å8×f1v°ëª’ysé×þAçkEI ™ýÒ ÉU >¥@ö¡¿ù}Y«Ô¯»e<˜Ïê„”QNµšT¥s3°¿O^#…üS—)Æ Ϲ>g-‹ïô­Öå2¡|kÖ©r0.êIc½£’vDˆÇÝ3Ü&­@ZÂ;àw?##úC#. Ò¤a»¢ö€oÙt·µq‘<ì|'SðüžÎG¡f‹> £¦št`TÞ|˜ÃÑäŒä;•1QÃÜ9ÁÛÅr£ÔüÓ Ç¨6òš;r ×ã4 *µvS^ endstream endobj 1019 0 obj << /Length1 2774 /Length2 12948 /Length3 0 /Length 14513 /Filter /FlateDecode >> stream xÚöTÕ[÷ Ó%HJƒŽM—t Òݽi6µiéîéFP¤»D¤»[º¤AênÏ9ïÁóÿ¾1îŒ.€÷½ü›ÿÿrÿKªdlõ7Ö'2`s{ßß)@k÷¿4\ÿ™ º–†ðß öÐi螆_•‹Õú‹íÿó üuäÿßäÿöòÿ:üÿ—‘”‹­í_zº¿ þôÆvV¶ÿX@§ÙÝ y{è~€ÿ¯©&èïu–™Y¹Øý_­ ĺ!¢` Û iå,eå2S²‚˜Zþ51ÿkÔ»­¤dïlõû¾0³±²þtåLm wŠ3´Y©@ÐúoDI°©½ÙïÕcçâ;9{ ±Bç‹‹ àÅÝQ3û_£ ²€í!Ð#hvÞs{'´ß-åæE‹þFÜ ØâÅŸ/(ñ„ø@É+(õ„Ø@é'ľyB ÌâeŸ”ËÛ'å"÷„ \䟔‹Â‚rQüñB¹(=!ht•'®ú„ ÑÕž4ºú‚F×xBÐèšO]ë A£kÿ‹ø –Æÿ"¨¥±t_~_…ÿÖ×òtjdò/bƒn-ÐÄØéI ­¦‰“±© úr™ÿqŒã_ùßKö¯JÈô_Äõnjo ¯ÿI89Kììžhþ<à?hîfö¶¶`ƒÞH@ГS¨è?A¹ë]  ü¯(?èàÙÛýáÚ ó'/P s+×?ÜþVÛ»üjbñª·øýê‚þ4¦cù”´‹–– ðP™ÕJÞúí˜ÍZ¯§$¸¡…±ý½OzhuÿȈ jðŠ ê ÝÛ§"@Cƒ]ìL~ߘP‚> @û'ÒPŸöœbƒ^ê@‡'54†ôõÿ§ÿœlÿHÿÛ}Nhvг²ê''´ˆ¶.$ýš:>%ù¹€œÿº…þeÎù[h™™<•ƒûá˜pðý#ý/66¨‹?Å­Å.è!gÕg“ë· ÈõîqA8CÈ“–ØÙÖØÙòÇPVOa¡ béúc¬ õƒ¸ÙÿqêÃå))hÌ¿¾…œMíþlt\ÿ€PÂn¬)Ô©ûÕãm çg¨'OÓß þs}›º8A;ùë……ÞíÿÃ}F@î S´ù{Ó×AÖÕA­×•¢$nÌ[#ìœ=§ç(š›’D®;Êâ7g‘s¢_¦¶#oVqØ?<6Øhá³Ú¬¼{É?_ÛŠhn²Áôn Gð׳œ ûöÛŽ#°™þq£JŸÛ¹È$=“ãÉÖtæž´Mãç«rËcdÚúCt¸‘èHdB^^t¸ 6Ñ̶ÏbU¢“Sí2¯œOEF~$’IíݼïdçZïY(c‚µZ{O²¿áðöWS9ä b°ÐßbÁ\CùܼîÄ^§D×* Í,6æ#fñyø²H˜JÛY$WÆK«ã„–|dfV}ŒŽžÃ›Í—Ëæ‡Ê´éË0«‚„“ó£üJݨµÓ_sï~å9ˆdÉJ×Ôo `žA¿!N/N©¾ ¬åÞ~§›p_G4ÑNc5?~«u•Ÿ¿”Ôa¨<,ÖªÕ›¼ ÀŽp'”!=¤1KΚ p”p¢dHStŒ2ˆ¨PÁcûöìÍO·¯«bÉiʯÏ–níÏ&1¤Ëpÿ¤g¹qÆ/žL{ÕA^-Ñ;täÜ“ÐÜ éS3½€hw¥Ò¥BM÷ެÍ3qÆëÕk±‹ä¶…ê¬ÄçC¦Òº-QÔ¿ÈѾ2¢*¸à½}Ъf 9¹±Õûæ6ï“{ÙÈÛ Ò¢ËwlÇÉZx1ö à)­€cµ7™‘Qáò‡OTEð¹Öi´ù/¿jÞ0˜½q’•òQ¬ÎлFAü–…úò³£b·Ìû2÷àgÈ$.uþŒwâ-kœÈ?„J¿iw«‡ «)¡Öã{¶vÍUMÔEšeÁIœø‡ƒe‹ëß§|–ƒ‹Aï¸<¤º_™1êHy+;<Ùø•Ø935_ ;p¬r‡ å“´R©+5’ÉŒÛ)N²‡†»WÌýÄ÷Îz|ÙŸùWx¾žHTXgûvÇü[ïý†J8­}õ¸ `¨ïÈ\$Ù¹‚C‹ó,È7¤/‹ã÷ÑPü 7ùSë~Ì}xL)¦oÛ£Ì/Ê#Õg..Ô 6Ïç2 H‘ïöqUjN'¿. é,µá…/ìí'ÝÍëì æÃÞ¹2‡o¯2Û2ÍÜ”ý´6aW1ÔIÒݵi¼\‹@_Á'$Aõ#ó|QKê.*`OôÌ…‹;Þ6Ò±™ë»º#ûùå]¿‚¿• ¶I'D.sJ@©Âtç8™,tœ­ŽÔݾVÊÅŠC½PíJS'Çh’U#¥9kR+”É3¸âºÁ–ÇÂm–fÛüH!tq—›50€c¯“®‰„_²A7ÉWy«Ô”Ƽ={å–ÕÂZ±ƒFPÓß@@±ÞêÒ_¤8š‘}3zþ©IÉË“±DSµü¢y HwwÑ÷0ãYM½ëš9Öö‚¤OÖцB†éžñ}q^ŸÀ§†:ÇÒˆ„•KÛ2Ê`e|0„Ò_à&ùþ}9„Š™mLo7®i›/x¥ÙÚ«%%ºÞf´Ø0Ê–sÏy¡,ûøщŸ¿¦çÁÁ#àõâ ¿ápÖK†àrcª|å—~I?)Ûm]º‘qÇO¬ª~¦lùÛzáy}B׉7ÉO ÜdXû~Q˜©_—D–ÆfH[­šPáJ65Wå6ÿÌóe\:|¬¿K_ñ‰:ß®zÕ…Kúeì ëm·ø,mïd['– ·Üºhèš&zt½©óá•oTÚÔ¯šåæ¢R<…ÌK‘PÔñ÷w1ª§Óíõ)åºã¡äžÖ .ì܃]áh¡Y­ôaí/ßy ïbBêï;ÍYˆÆ´ƒw;Ð6"„ê°µ0²¸Ãë`Öð>ýÀɬ2ݯ&SkðãÌÏÑÈZie[t®ß™ZD·î9ýùþ…(½çœK.'—b+SÞ4)Ç:/ò½–åsÏ좯÷ó°É5ÿbIU³øu±”=¬)×—IH ž’‚Ö?çx°ÊÛWé±ß™?Ì/JbØU–•jQÝ8æ|­6úÀìEŸ¬sÛJ¢¡®ÔçÅnËïN3¾68õU‡ý0eFÓ÷¦Hž#ÙþµÁ1ºqffÆáSXl H˜>¨å•K=ä\‰Ë—ð½Ù’Q.¾]+ÑnV ¢Ø5¯3VÇ^^©!#(†=H&kq¨¦ŽÕhÛ²k‘] ó“‚.o9¤¼d|ÜdÔêtêÝØŸ¦½ðÚty!yý=¨PwQ]e";T%ÞH•8¯‰}N×» Øk-`Æ^¤6Kšâk0 QÚ]…8vLì^sŸ<ŸÑbñíÁUÔ?†ÂnRø“¾ O·‘2jÿ™#¨"ƒ3W1ìãçðué³4žØ;܈˦Þ|üºø–˜—‘)–gŽúÂrE/TÑé0(ó·xï¢Ä>¬í'P1z'Ë(¿ø„äYY?ç‹' túúïSýHŸÜKÙŠäK½¢0sà?Hñ„i‘ªDˆÕ8dµ<<„Œ’Ô%ò/´™–Ž>Ç)Y¯Æ>Ý|vÖ÷s$éÜÈŠ}”_@ 3þ:î¶ÑCÙÿÑñç á´DèRjÑÓ‚sR)!¼­ížM_†çÆò†®‹ °óFFkÔ‚'*YûíæFé„âQvW•ç éÚÜßl~ì‹ðCóÒêRr”³ôKB«ý¥Ä~ ðM!l`Ë/óW°Ç—gð|_äÂîrŠ-øø0ÓZÆ-r~ñ‘­J‚áѰ¸3^6°Œ˜…©˜ž!'_x@Á` ëãKXïêÛ² ü$ˆÁ·gDoùyUجߪùDОð½|ŒŸ½‚ah$»j‹úÞ@à‚0»žNÁ]‰Ô€ §{¦vî]^ZÈr´Ü‰Ë¦i+-Íàš.ÎÞÕœ•ox£’o†ÝYJ¤[°sÉfœs‘ì|:88éŸ5ýÔø1uú,àû¶÷#j+:„ÜÞ>1Ážðê`òùUò²À4J-"¨‚Ž×cã*·]€éôKCi@ů2ÿãxzŽŸLÅä󀿯8í ,‘OO’Ø—üû”“NØ£øñJwT‡“¦yü¥Ì£…¶ð%õŒ.2( vËù—Æ “(ܽ´?(ÞRü"mX¿Wrºc,*9`d׉7Km}Qøhþ?mUè‹»]ïåçufÂÏÌ“› ÎÍLl§³˜b‚µDf½¹iÅ\;zçtS‹eà³Æž(ãfüÛˆ«.fFÆôç4ê†oéï›ò^K!#¨óAî‰*ÙDd‡†žúhTo"Ý=»7û˜1÷¤ÖˆÌñ¸'$ßé†s^& ×;ñúÐð¼)ø»ù–9=+¿^I–í’©(±’ËLGó\QcC& æ}‡E„ Œ$È"GŒª Óþ-»…ªÂ·±K‰|“Y¹!ty~[Zs±¾0- T"=·XLˆ}„X¢²ÑgQš¤¯ÍÍ`ªˆ€àÍɦNïÂD}¬‡Ì¡4ûrí „kjïõ·ÃÏ*eHkPr{3 £ 0/.µ…º$‹¦†.V½FÏÕnQ?f¯“¯‰g÷ä,üª!ŒXb¼e ÷üØìŠ¥+öÎÉšå¨ø‡ä”桇`¢ÒÎ 3„Ö´]ƒäªoD«=·ï›yßûcPEÈIê[V»·^ÿB Ú5ä‹”e·Ôu´)ˆ» &Ðj{ʹŽ,9 Ž´:›;?#øÜ9­ 6ÿâ[ÀÞ2k)Kf?bÜqåp¶æømÛOí)3ãæîâ_>ÞoâîmØ~ñ‹ß»m[s¸¹Oô¹»$’ÄÔSÀ{;é¶gìðr*=ÉÚ> ­1¼‰HôÝ>¼®±_ÁŠ&yòäÔ]VxM¤&‹E/ììäT˜Œ+ô—r€úó¢ÈZëËÔ•¬¨xK¸.Õæ¨ð°çîÌ;V”‹¢¨:EæÎZ¬j:öTL]¯“+ï> &.qÃï$L[’ð]k.í:ŸþZ]EDú)ÛÑ`Õá~-C¸[†hØi›ìŽT!¹‰”@¢ùÖ\m(~`SVK”+®’¿Òyñ.DiÊ®€Äñ}Ư5Õ…Idn)! [îʳ! ™XTª‰oXmkb—QÁ†QDbÌÐ]yìÂ-Å2V͆c3Óü¬ìŒ¨ö/H v<‡>ù§õÊXv~s¹¯ÒW˜¦M©,”¬~ðÔùD ˜Ò¸ÁÈ“ÔÚÄ%RP Ò ¾¹ÀëœÜÃòYŸæ~ïäÚöeª,5"áäÄÆíCÜøöiÜyœò>¡ú[Ù!OåH’× wÄUfÍmÂ+ŸÊ-qŽy¹öè U¥Õ9—ìêÅ›è÷2Eü¼8³‹çµ­©Å1¾·@÷çn\'æ'ä¶øÏ2w_ú©¸•ÐÓc¨§?àÀÞS!›*&‘Zx‘ô±ü¼ÁëΙÏâõCÖ%×UåA¾ƒùeà·'|ž»ŒšQùzcl†üd0¬Ïѹ¨L9û@åÚû؈õ¢«“ëµzšvÚÊD.uu÷ŽÌ{ |ó²­!Wn†ˆ‘ ê‰ÎdIZÛÏB‹†òïιkæ¦òEÍU•¿©0œ#ðZs_რÁ{(Žeä:Õ­ó¯=WY1ýˆÒ鈰°^_?§bŽ* iàp'8"zkðB!+‘h=§šUðÐû»!m?àbÊÁ4I3IŠèÙ;QpÆãøhq-oEF}z<ß,sý¾ú»·‹Ôè ú‘!ŒdΩÜùä}`»î\‚—ÿTºdH›ß§H°[°µ€µ×¹IC“ÞÌ&lè»´/Yümòà)ÙÓˆ}½÷ ‡Á§‡NGØT@'‚‰9]†÷íeWµ„pò7óFÖÙžÍéMDœÄ$´^ˆãX?_¾âª$µ¿dNë:HÎE&-اè 74Ð:^+$qZMH_°ó/bpNtߺBÃ÷tzEö·NÒüLKÓ¼)8›É8q(ŒÌ^w="®YŠ*ûBÒ7ðªO^oü§ÝóÞ^“$C†Ùï³6“ºŽŒÊ*ð>{îÓLÒ”Ý>\üEå–-îïëï “_a+Z­"èàÏú^'ßúd? ÿB|`|·‚3oÆät}‰û€.€Aâ8@%–©8M“ÇE¡M¬$¨”Nï~'ì®qÓɉ¶5ÙˆÓ'”&Y5KŽÜ̧V6,"%ÐÓz[@enq4Q$àç›I¹Ž»©¤\§MQŸ˜Ìg½AçoŸ€{ú®¿oPqžºP„ZROÙv(ÀÍ`µ›Ü†ºNK&쪱ëþÉûì,ú×hÙ7À"'O¶Tä$T‰bÄ1|ÛQ_`#óù+ >ðÔ–è4W—†IÞ䦴\ï2òvü0ç;žëï6\¡a¨ ½ šQûü¤åe|¯2­hn+”¯J¢¹2Û)&Œ‡Ô֨ƒ:)6‰ü­¾¢V!o—yÚÛ=IØØfÈ.’s¯üi@·¦k†•EÀTb.§N|¾#àyäwì×ÒGŸ÷Ph u5ko.¿D2ï'OÙäilvTYE3àŠëI£báÝÐOkÇJðàN&¹ “ÍšÉI5…o£m$ÏÇݶ`-¢\Åo™Áx$è+_ÕÎÒÔw!E:nš´!µê>Ø”ö²«c‡è–¦¼i}ÍýR¡ UÜ¥É-íkbPâÞúó5H~çÉÒwùB¬Ä¯y z!?tÕ¦1Ạ¿:®—$Fosõ?˜û7Öñmo‰ŸÒ7xÄ.Œ$Ìp±†ÈMfü"ˆQÆ¢yŽr¶šmXòâ,Ví›R8mÆ/=L|g,þ¬–ß¹dÀ–7ðEÜ^ЇØ5u±È8O¹ú*¦ûþây­Sîê”D÷Ý–oÈbjeËÆ¹Ô þhFÛºêÌ÷/È~—úWðjðîÆ·»N'/ædL0ÂzÆç-´^–;x7ÄN^ZHC\òŒ¿ÒµÛMoÇ÷‰xº0I‡Mç—'÷ì˜ä´¯,àZ•aI¨·k½Ó™:ûHÔ«‹ÎØ`¥Òa©aÂv:…î#æî6Âwì~/'æÉ¥iª]}âè>_á¥âtQ=Êslî±2P>Yðÿ”+ -c‚ýq}œ¶2Åè×™¸¼&Ä/P¥A%Ñ̯z&æì•s\µ;ÇCu>SeHÀòN¹Ò ~‰õ%ãÎŒ£P¨oMHJS„ðº~$ÈâÌ¡«›5Åèö+$„µó¬Ü¶KµjéÁu´]ƒ‰Ëwwj¹Šôj‘kϸ©6Ý®ò±²|Ãä¤Ã,ø{•½âÒàb—ZAWþø^TÑ«nvk•–ø9¤5Яîþ©##»é}òþXê2Ü(±{’<Ò¡1r•È5÷a§ïš?SÍ/« ’·×îÊÙ]·ì2ºn*‡¢wì³ c¥Y—[.ôÈ2îåq8 §|gUé#ÂpÕ÷è+Ícä,C òGŽH† Èl…²c¤Y†Iá-1¿Ó9ý8Ïfˆt©:Z’@:4#”#ãÃÁ¬[œGLªòV™&„¦;›†SÔ|ºSa%¸äØñ-“\D?¬,àméâ^4sŒŸÔ Y^ cI})Y+ó<Äûì“ÄLLz—VÜ©¿’zOøSETK&D»ßËà™wµE…5» <Ò·Ìó¸_@Ä[èÁ¬66ÐÅ3/ºÕo‡@‘7´„wp'A亗¡€7Ç Fj~ÕÑ]æ’f¾•›,’*GиšƒR8BîzäµÀ>_w¿mðBŒ±£ÿݱ_^GºGŒ" á¶Ð=°”u*ëMèî«t½çÕð¡çCLª­jrâ9#o>DÏLè²\þý£±qåël%k̲Ãiã8 ¡óÛØ‘êkjƒhÉWÅ®áíV‡º¨죱°À+ø!2ê÷1æ#wmâÃ7QïàŠOßùµù½IñÉHì\¨k߯*#¯Ðzfámª;ü‘åtuÔ­Sq% 9áÛªJKPâk×¢ª–÷9tE³<ÉåþsŸZ?ÖgÏ»T6€ðì¶3òó¥w÷ÙF/ÔƒE³K:]œWz¢¿Þ7Ôrá?/î®Òa cwð# é_sïb‘›¾–—5o"€?±ä÷ÿ¹Šÿp¿\¤‰À`IÏ’%E4ŸF]{ØeH‰;¤NLÉhÛUË¥Q”‡ÿA,š_Ùï™÷–åš…Ù!‰Aºž[•rÔÛ ˜E6úªÄ1¼o0O˜]Bmu¨C¶ÎðƒÓ/d[8§aÁã«§D§âô® ý;÷OÛ|w<#8ÖyæŽÓä¤R†òu%+úgæºÖø®Û0s$¨¥fRI#|åXa™ Áøïéªß>6M¿´S)‘ ¡0ºcGƒ±Eo¡¹°4D•{¬“§ièŒÙu4O/š€ÕyÏñçÄK-©ä—Üz €ò£”GžÏ;—Nž3·v'uòÍŠÓÀ.ǰ@.OjŸehpHm‘‚œñ6,` ñú¼”ÑijHˆÖ»æ£rñèÀ©Å!yÅÜ^zÙLAþÙÅ( evaÝÒ'Õ×ÒŸ7wÚ 3‰z3%>¸…Æà‚“ñ¸ÆÔrHdŽÅ={—Z`o‹g3ÛÞÏ~_Dæ5{¾ &_í±{v.#@ÍU ÿÓ¥uåAå×d<*â;¡o²ê»ç†,-,”„BIζì¼b£‡Öúë¸6»Áš&&?œôý¯÷zLPÞ¦5óßĕޝx ‰=9›:Ͻ¬Œ¿ÈùÏ=‡Y ë:GŽñPøŽCbãr‡wc»—MÓÏV-^Sßœ)|¼‘dû§’G ¡ËáNÝM)…®»¤¿þ›Bãr)!ƒh2p2?õ!á%dïnn6TcÛc”×5:RÐÂîïoK_­éZPžåÛ_—§ÓÀmPÝüjwå¦þ60 ÙäÝ Ž`”€lCâF<À‡™Sl±æèj}`BŽ/$aî64nñ££ÕpÃk·¨ö)x£Ý¬MÜ=&^Ug”ì…‹<6 |ñ-åSýŽÂ–¯cѪ¬±~³ÌI¢úDjéôÛú’¤©©Õ]ðª7 G, (;_Õ®“QIwìóÞqdƒ,ÿg^©Böm›F8ç1r1£\!^æ.Ç—­UjH$œåŒ å°õ~•}ø! ’8LßNýFïj'âÊne¨ì°ÀÀm¸"RÑÒ³_™nnüð¯â¯å…\й] 6è‹8€–³Å«¦!þVó','V4Ö%¹Ô|­]Þ;çC´»ì^´/¦,'5Óq4”‰é„•”ûfù t`âÞµ‡@'SIöþáœçÍ•q°½9E[x&þêÙ«–ƒÆ0¸ÚÔÒŸ 3ÆuâCœSAÛk]IuŽW§04ŸèS*,K/14%zõ¨ü0SL®±ìð$[€æ¡“<œ8óKð¥a…zk¾³df Â °á'wÎÚŒI­‚ËøÒ<ûàU“õ…kÙJ¼s§L)²òâõ„E™ÄØwði²ìâ̓†M²Ábƒ“øöÏÛìÆc`ìÚ#…û)䉘¤:3ÔŸhû\OÜG½Úƒq«~k5V> í™êuSåþ.Ìé™ghÝÂðáÊ2~”ûHÇ–MŒÍŒ$OQIŒr,]Eà-UO×Òº;‚¼ÿ]?­%ät$Õ)n]Ú V¿Ÿe[³Vþ6‡Ÿ½Y= m½^•ÆÌ‹“5ÄTÖ“Š#pÊB’‰:ŸæÑìà‘5ó†”Bë ,DrpÅôC— (!i¾/ ú¼pž%󗂤ÊÉ7HjX>r³+@ì‡Z7VË ‰ŽÐJ TËÚi/i]´Éî¶/9 ¬?{ÉI kÐy$Â:÷=u­Hñ[ÀpuéÙ¥n†b ’)Û!‘4ÃWý{êÒÅì:mý1¾ñz³*×Cä¨c7ÆQ²¦:G˜F³ò»ª{~•äÆùËt?òÞö'Îâ­J;pq=Ûi(vF;@»¬“xÕó.3Êö[’0ò޹[1 K‹áRXîv>Í<Üd‚•×àìíK…ç2W¦6 °ž~#ˆcô±|>û{,̌ڦóÐÇû%u×wÑ×U‘óbý¼5Œºð² —)·­†€e÷2¢Gªë”ó(ÀvZ;Âc¡à'™ú¾lÇ6å)d?M‡k¡à2`€?ÊA~¦PvŽ"‡ÿܰðe¾/Õi×õF±ø·±îëˉw Á¾(¿¨îbòyÕ"›ƒ^±#RyNõü¤÷Pgo†Uߨ“ò,/õ¨–÷ßby^=Üÿ ‰?¿Éq3YRiV¿éÂwó Îo‡BÀÃVp$PØsUòË´‚s·—-rH×~•þǤ;ß¹°Å(ÞDÉï, t#¦7ˆ:ÎÂq]Éè:Êi7³ð§‘ ï|/L½c©å6HèýPUp³*ØÃR" VÝŒº(«¿Z™¿ªŽ=]2vÎ?M»yz‹ ¶}#ø ÎÛGëj/òåÀÔEÞžF9f¢Ñ ³ÕÀáz­9n R4I‡ëOºó¥\’@8Ïñ"$ÏP+Î|éŽ;`¸8F56^å’K‹ç.Z¸þ§©ð—W¦ô/è¯ 0˜]c}­§æ“)a’Ý$.6™v¯?Duä»ê“ñÿüÙÓ–pñ÷MšAÛ%ÍJp÷¤?Qow$tE»š¬IV î|áR<Õ>„6Û.ਠÙy€’Ö¬o2;ÏY³ $>§ü¹œg/Ôr”i |½>Ût“6Í”3Uá®Ã†èìùJÝÞ.µøÕ–æOÿ*‘aáö’¤èaô”Lˆ\Ï:¬vÒk$ˆß¶¬!Yª}ceüHø3)Q­Ñç¶ÛÅö8‚üUd,Lí})D‚cˆ‚¨’ç—'0Cë&yT‘8ôºsaAgëd׳._±! Lx™L7–U”ƒ¢ C!OŸ°ô™-“º#[[" _WWµ&rù™ä‹8굇‡µ¦™Ú*Á“Kb±xKCî@Á»äÕO¤hÒ»ÄM4˜Ø/\\ÒáˆÇcÕÈ«û—W´_…0,'ŠwÐSÆ¡xßh†Ï¹Ð•YlØ3nRU¿Ìâ°ýI]'&¤sÊ:È »0ýJE‚ÄVGDØ Ï[°õŠ'¼™‹|.vóæ6Z}»UpNBS^œ48AôûPtiþrÀ„.FÁSëÂÖˆqʵÈrØS“&Ù ?6ž4´_A2$<JËzȪ¶QÚ[ B³ŸæS-,õ” SuF£3NƘMîöLF'_U2;?)~8üÑá+è¯>j²´U¢aa8­Ýþ&[†‚jTH^]ÆÞô—¿0Gá²óVI?;F„w1mt벪…\JçÙñ»³LÙøÂ‚ØIàæ‘–(Ÿÿ*qɦˆêHòiõk‹ûú GO8m‘]~ÿ6š]²DÖZ-ËÖ²öÅwµ=ŸœgX†rô4¹3‘YB¦|ð7ã§û3FSXh¼7¬—¹|<íX$Ô³¿B9Þ`5`b;1÷Yän13d¡Ë%ÁOĤKÌç M} A’ÿ†H„Á‘i¡õÃcÈÅ’½Üž–²5ÛŒ¡Â»÷H‹k¤Ï¼¸`(Šà¡O+7­VÖ71E¾z©ÑG½³·ùúâ%Öur:úrÆ,×SMº¥d–o=÷-x+ÞÅŠ4êFÔ”jsì+”Ç&$3^*H×F Ów¯? Òjeçøª0Þ Ë4_"å~`û‰NZåkwÐ6‰ e0gqO—¡Ö• £”¦Fû£¤mîÞ\ͨò+^ûæ/.F§ 75A—üCZï’VŒ}XÑc%e^©T·c´«½8mRÖ…_@¦^ŒN’žŸ•ļ¥ä4h“Fb¦ƒÌ²÷ ¤DÖ‰W&”-Êq´X*€ÆnŽß\¥^†{^:8Z°"îÔí×u½Ù=*(gÃÿZèŸ:ÅÅj§¶ÉIBz_+H ÄÖr¹¿#' .o¶,(“þXœPؾkëé Ê×DéÚëÔºz©D+÷Rtùö–Ÿ ‡÷‘‡*‘Lþ§…¼±ÍqqÝ µNNË.Ôž”fºÙ¤q~Ø9#ãPA®Øôúû,¯õØÌÁ7tUBpúPJËÇ”È<Œe¸Lcšàè`Rœ÷G³<4t¼KnÊ=ñÛø"²èæi`ßܤŽóq¸ý¨]uâU¼”ûñ‰Äm<p¤>H˜v)W˜q|íÜã`Åè’%®xm%JNóBäzs¢¡y¦;:íÝžÿE@ü3Ò€©µbèp g¹(\rE§ð –âJÅÛFÊv R/ă¥´°¸/¶ì³Ìß[öY§ 1…?Ó ëÌ…¹ µúq‘ÙX>¿Ð¢ö!Ë3„Ýh!£| `˜ÃrÜé"Â9VM ûŠæþŒÍC°K+b³œó“pú2®þY»s/è°_"7ã§ésÝdTcYÒzEÛB¶ÎÚÀÔÈ ý-vä¨@¯á>ï<=~|ûéWÑ8ì®=‰Ž0¼ÙùÕšqŽ ƒF]¡ÓµeFä+ìâY×1°µ¦ý$è`*Hä³öžw~ði+™¼±Ï½y¤ÓçøM5ÿ»CË2À¶áîššs)âFe/2Ö'ýªX¼Pé·ƒl•ϯÂÌê7Ù²“´0ñ_XC=é$ᙆC"˜¨Á@MU'üÈÎí ” áAP6Q¡Ñkpžc¾‰‘ZÈâ¯,j•w“MeþãòQdùUüQvÏžÅzˆgb± FŒá÷¤iB23›cù±Íål“_ˆæ”®QúëôøfÉÙ(õÊ)5o'áît˜C£î>`r”°ðö$²§ÐÊ¢ÅmKœõx®˜Z8‡œƒ¨¤ÄÎDÒÊM 3Z¢Íw¸z7ÚçÛêÊð,HÓ–u4ø¡ªŸÚ´OGAŸÄYз!@ïZŠúù”&Fì²¥ê‹h:é í¶àû¢Cpµœ¯ü néðXIp¡˜E¨HD&utJCLë&¿¸T‹zúÝô<`‰ÎávX"øÓ7ïƒ@kOC^5„n7½"¥?ù#A‰îb¢ —ÈFóœuCŒ'7i‰¯Ÿ¯å/¦‰2lô`ZL6¬õàçZ1>sÈKÄH jÂg¦Êü÷ñŸS>xÆÈ¿zdÒR•`ñ«p0Õ›¸ñ&nÜQ²ø!+jñ…ÀN+cÖv9†õ%QX箦 ©'^¿J¬j×3«åâ{¤ÚÌâ.¡{2-¾‘úH›.þïœzÖMDÙQJŽW⓾(oºAÜÁŸù½CÑt>­¬pu¢ Ö4Üi´d¼!îÌÉ¢·?›ž Šèè‡|Dôl£‰Î%ôúÖ¼•õ“ùKR~³²²ì›”‡^5õƈ1¸ˆ‡¸˜TÃøvZ÷+awX€sc«L>äܡҙýo‰ŒÙšÇ9ä">—ÊUv_©l”Ô/ïn–I7Œ2¼!Wx7_‚9/¡[Ô“/ǯWžóšÿá_JÓLín_OYëÞïUmÒ*òÜm$‡©Ý=ŸsÈcC¤ä¬¡EåÁð¶‡Lª: Uqq­+V3L7«ÅŽŒfònØy•–ÓÜq_8U72dù›Þ¢ Ž%l;ïÛ¿+úm†³ðyO¼—×6Ùš†»¼×VY+@¬eæc™²æ4ù~¥Y1§vöÊð­¿­Þ?ú]kY€U#O…m:‘épÛêb@Ý%п£V0ØíJÔW«W‡„ïŸaXÙTMËMñ&ª8ĉçÓK–)=CÍ̈{}3ìâàÚÚñ–rLhé‡oK:ÞJª¾0]LÂöí#û.IÝ I³‹Åu¡­:âYƒ¤"µmÙ5ŠûüX.B’Å%¡…%#â@ÄÜd”Ü{áçä˜=sݺÞÒ":¹¸_L¬Zóih- ½¶ùZÏ* œ¬*ÔÒ ‹2··ºÐ-Ý\ð ¢Ø~*(¯ áz¯ÿ­«M§á–ß¹Ñ>ºÇÂ1ýa¶ñÁÂö‡!ê‹’©X¼ å-Lð„{úÃ>6F0Šü™‚lÒçz–8„“GAò‡//-0î´”xÈ8åæõ¸­Õiíß6ìFgPß®’}l¹7°1ˆ]öȼkáüÁè3÷ 3±@î#}TÈkÊ׉g5Â4àÀ;úјÓ÷r‰®6tÇí ÿ/½?Çaia½u%¯Ï{²êÌ Zg¶QlDˆÊÆH`õG“p~U’µ›‡àª•0Í8e¤Ïê%qèáÀtéq2ü¼#ÁÖr)ê\Чˆ»Û«ø ¹©D 6²"A,Ön\SâP}®pªé«m\ŠJÖ¼`é%Ç¥ÇÜU#`Ñàqàä<Û×±FÝ#ÉEœb“—%n]÷±Å_Kap;E`Ë­š4´ÉYÁ‘>ý[¡%ÛÒºóô›Ä gA­Eݰ1eŸæ«•›Õ~?%L¤fú¾­6XÉk´aÓešÞ~µØôÍtvêã‚4iFµ.öËd“Ii+´–ß½' øˆ¢S±‡ƒ®¿§ÃAb™GMŠ-w„C-?shéÓ[:‘qïª)15Üî4aÛ.o¯{ÊR“?,™;Îi¬›†¸u:ý^'h4gËä¢Ï+þý2a Ä톩Äw ³.tŒdŸ†FS,¸Åø‹ûqªk¼ò¨(/Ö^e¾Â]ô#÷j–áU"S–žwߺÈñ÷£ß6¦±íè’ª<^5–²é"ÖDVlÐØôbP¤õ".(ˆ@©Ê£xÙtògnƒè¥].¸2uÕ?—ö<áøÈª6|B(=Zðqµ6KWÎ6´5³Å_ÿUŒÛ/UC®‰½ LÒ1Ö.whÝ0þ<ú ±5n¿ú,oà> stream xÚ·P” .Lw+­²tÃÒÒÝ ) °À«°ÔÒ)4Jw#ÝÒ !- " ÝÝgõ |¿ÿŸ9gv†ÝëîëŽçè©Õ5Ù%ÌmMÁ²¶P;P ¥¢¥%y8€@n,zz-Ìü·‹^ìà±… ýa åÁà2i n§b (:Y¸x\üB\B@ €|ú¡­ƒ@ä 1¨pm¡`G,z)[;7ˆ¥ žæŸŸ&3f×Ó§l¿Ý6`ˆ PÁ¬À6ðŒf k€¦­ sûO¦gV0˜'§‹‹ ÈÆ‘ÃÖÁR”™ àYžƒÁÎ`sÀ/ÂU ø/fXô-+ˆã_rM[ ˜ È € ¬!f`¨#Üà jvÀ“4”jv`è_ÆÊ°þî €‹ƒëßp{ÿ þv™™ÙÚØ n¨%Àb ¨É*sÀ\alÔü—!ÈÚÑîrA¬A¦pƒß•ƒ²œàßôÍ v0GGˆõ/Šœ¿ÂÀ»,5—²µ±CaŽX¿ê“†8€Íàmwãük²¯¡¶.P¿jnñ‹„¹“§6bïVþÛ.º—Y‚a> (È€í`W3+Î_áµÜìÀ¿•\¿Äp^v¶v 8 °Ä ÿÂòp9ƒ0'°—ÇŸŠÿ",..€9Ä 0[B X÷Ñáb°Å_>|ˆ+Àß=.ð×çß_/áëen µv»7ÿ=_N5] 9eÖ¿ÿ«“”´ux°óعy¸|¼|þ§O^ÿ ò/ý¨ÿ–ªƒ —¼§µ°<ý‹¼uÿ°pþ{)˜þ>fÀ3¨ÚÂ7 `º_|C Ð þ‡ëÿyý»üÿmý¯(ÿ·Åÿß‚d¬­«™~ëÿ?j ÄÚíoø";ÁàG¡b ? èÿšê‚ÿ:d°9ÄÉæµ 0ü8$ –Öÿ¶â( q›«C`fV¿×åŸ!À£[C `u[Gȯ' € üüÚÌ^ß&ŽðQýVáÇôߌ2P3[ó_WÇÍÇ98€Ü°€ðåâæãxpÁÏÓìú{¯œP[Ügç°°uÀú5P~>§Ä/Ñ_ˆÀ)yœR÷HÀ)}ž8eþE\N¹{Ä à”¿Gð˜Ê÷SåÁ£¨ý‹Nõ{÷Óù=…ûî³óÂì^ /Íô_ÄŠך‚îÕð,fÿ">¸±™­5¼áÿHxyIllîãÿš§ùÎ|^Ù_[po§lqoÀGç?<~©mþp€›Xþá%XÝŠ•›ú‡\ùÂûñú'eý„3¶¹‡\p6÷¡øà®Pørý¡‡Ó³½Ïw¶ý^½Ý½ÌþZƒ-î;ÀËõ·Ôá?á…·Ê~ä¶4þå´ÿ©ÿÑ.8OÇûZáµ8‚m ÿß/°óíáƒq„?CïÃÀß—ìp¬ÀLÎæbû‡¼+N÷+ÏðûÕèhfëðg+à}vþÂËsùcñàAÿ¨žÕí¾pWw°Ã_)ÿsÃfNðÆÁ~?dáþþýƒ]ÁfX3S¶f¯ªš/+$(]Ø×¾póâ~>~{Š¡»*Cá'õìÇ ONØW‰ö‰õ°‹D;Ü…w_ë‘_-x&… ‘ÌÔ4£Z˜®°yމ\í8*;q¯+µµé›ð@Í-IêŸ÷ºœŠ3“²Ù­M¦nÉ=c¨/»(µ:@g¬ÛåÀAú†N&(ȃƒÐ"‘ÚR&Y)1>Ѫ@çx,þeïÝcÙ­IÝÜ|ËŸ¿±!B–’(··qí”NS·E7;ø)”LFãô«2d×ÑL~§Ío˜LÕc‘~wƒ [!ç+W1Ç<ª³‚­3õgf¼{Þ¦t‘¹=zÖ«ÒŽçË¿âKxÎrõaz˜õ€ovVÁÂ&Tp[OÐ2ƒÛk±Ò°§~³Ò¹O)ÍŽÇIøê+4×TÅ«ÀpWœç(pjVU …sNÅa²ç˜* œUµP.ÄŸAìÚ¥/ó‹‚­èÃÖºÊÙvR§{Ž°Ã˜…—M{wšÎΔë÷½TS§ªÈŽåÆ t UB5ÏX £ùíÑÎä(â®ì+p&P*ée¼Å#Â^OÕ<9¼ìC›Bürpay¡ôÙÞ 2x î|™cê€?6á=Ô³’ôy‘Ë=²™ßïP”œ­) ÕðºÜ¶ÎÕÖôB‚áûjˆL]opÀ$ÜL¬o-ê½p Áq³W±µÉ“¥3k´ÿB ô\Ï'ñî“Y9U;B¼Mv‹LªëËaDßüムe?Ù ‘À¦=^coh­*²Î®lŠpC•AÃf&~jd#³bàœ˜pMÍÁœÍ”Þmùºäù QÈÛ€ÊÍ‘g7´9þë|Eç†=S?%j£ñ¾lÜ땆fwÍS7UJ™ìGyWì÷¶~Ö†dA^ÍOI8~ÚZISޏŠâššIž°e¤”ö•_BwWM_äÏëN®”U*rŒH{¨@¾åO§.mƘó„P‰°”Î0£–¢¡CŠþgRꂼI2íÒfbxÓúÆ–Åeë¶—º¸‹¿×²ìâ•#±»+e¿`²~ã(&™z‘ kÌœjKðŒeΘ8ˆ$¦Ýc‡ŽéÆ‚¬Î°“»~ìÑÎ1yÇ!ê:Š±Úƒv>Ä I=*>ö ÿyBtÞ³y=ø~ÆO„³Ônm›x˜r{Ër“Ä‘‹%²µîÉMõLº ác_Ưæ` ”ç+-öxñ¾FKP”80²£œsÞh8,‰ J³ŽŠÖüþ”Ý|Èò>¸-rƒ#fæ=nx–œˆvûcd|± gM뜭GûÚ/mþõÉ%£{)Þúí »G­i/!˜ÓN´h–q!ìÜ?Ã?àÊf Ùd·c Œ4¼¿F~m;·®ÌÛk|Æñ6I½ç‚:Šç2µF-I·V˜¯šüÅÎdnwGŸÇÄ£“8Ýå‹yË.þ„¤7íUž°µrßöªš‘4H·]nжÖ#}¦NéóÇ®B—„Ÿ ã–­½KG Èœ…¹°JJeçöëÔ“KÝzê˜é œû‚¡ƒ„ÈÄöÄî9Í»øCr3Z£Ÿ…K'üc3K<“,€ On˜¦»l3Õk~PNw<ÞaÔÐ98÷Jêûà¨H/¼­Ww$œU¯ÜòX) lm–eÇ:„„‡sÅO:#n¦.Žn0PvWçÄ~æXq›¤Â Äª¥öf³;³ûyNö: O*ÿ¡sòs½ 9 ¬š»Ã®MñM,ºETtƒEAiÿ²ÊÚ49ÈrÒéÔOç…êh.÷(JÌOûxMÅ…ùÇ¥Píÿ-l`Ë)…ùǰ—uËúfBÈvýŠ™èc£p`wª òíã7?[zúj ðkÃÄ­½£~ qî?Ar­õ¨\Zï›,ï¾ÏféßGâÎrÑa¾–2ðGcÂ\ÂÙù-@ÖP’ž—BûfÂæïÃÂNã'¯ò®¼„Ÿyâ§pÞV@gž•ÆŒ£Irª ,·õE;¾š/Ãnïß3¼Õ”2 ÈF#ŸÇ$]Ñw.¥’?T®Ž1iJ=ßíÎXÜ@«8ý„m NË΢ÝH¼fîÄ{¸½îŒ}çõˆ½¦j¨yeZÖ[pü¦±Æ^)ô±V°°HuFÄÍŠä@!Ï*Ý‹¶†ï‡8Do 0ˆ(üè$v?¼¼0$zÀ–Çñ$k‹&8Q&kþ_.0Ÿ+w6Ú_ÌäÅ0˜\˜èx_L¾€±;Ôê’I®zíØû5Ü9èy1û1ƒNê„Ïew-™Â;‚H!D'ó7™Ý†ÊíÞæ)cqIQ×Õ»:/¬— ºØÛ"íÖ…Ÿûjퟓ­™ WO—âU5§\`YÍâW2ñb4ÐPªã±o)R’ÅŠ6nž¼à@J¨¿Ëþvñð2Gûðà[ËPÅQpHví·v‹ç×{ø’Õ·®tBXsß‚»útNÝ™“Nh¤ùprx;ÇÍÆhâ¦>·äÍ1Ä-–/øõµ?$,™TóNæ¤Ì¬¿7~vð;(Û 0æX–vuch÷kìæ÷¢²É– c½ñP=ÈÕ}ÎòÀ(ôs¯n"¿¸UGU1/)6Mã|)©0yËg9I§3/>ê'atÿ£¯"_Eøæ›1”½ÏŽRå^¼ÆÝ^aøáC¦ž·ÃiŒ¥JS›9 æ‘¼t†ˆ D¯XŒý;6ê®GÅ8ÞOñTNpn{²À»¨¨­ã}[ˆFäžv9¸W³W]eyžŒüŒzaŠ®ÍÒƒo¤£Fý uåÚËêH|. ÆÄ!×Ní+Cù@¿±˜ÜSÐàMøÒ•¢'¨ÿ-ç…6ÖhjÏÍ©á¾ùÏ8²IÊÝ—:z£ÀžW`â/<òÝ–«¶¦¬è W¶™|YÃh¾ {yqè«U˜?ùZÝõ¥œáäî®>õcöÇwÏizAY¬?qâI‡’bh³\1®^¡‚’›ôÉã'(I  Ür–Æ60ØßIæ…y†±kŸ ærpþ Ú áÙGC2t0VئÕö(’µW‰Ðsçß»¹ºÍ¿|šxG3HüqÜÊ2ù4g1€gûûíætîb“®³Œ†Ùw¡z ƒ‚§À-ƒ½ ‰[«žµÇUêUαB™”“jñ.¹¯Ãéeð3KQ]/(i³8­pÖÓhãЊ{cNIùuxñ>š$ÓÜ[è_=_Óu-•¾SØà?ÙâÎÍÏ`­*ÁD€¢Ñ8øQ—àÚ™rd;$/“*]¾áC#™ýéíö˜¹0þm)f€dk‹Æ»º…bӦ⚰sD1d:½÷¼Ù )Ü—áþ!ög¸©IO›4ydxÁº4L“Ñ©?~1eƒàUãbMÈ®Ž&#Õ]ñ~þ¸ ÜŸ»: !Æâí³`H7ØUúä»\ºËj@sóÐõÆ í©t[׬H•[œÖ¬Õ6H3a5CJÐ>ìòÕèZ<60&]¢’ç}M8ù IŸ@Ì#:.„§‚u&tƒ-Aø1‰ÅõßÛUdz~¯úùµNïcõ—墮Þ²iÌŒ#AÌ&¡¥;¦t7¬®Bã9Bš? †Kꙑ\cÙMïz]»ì~`"˜W²¥q1§YsóæZ›¡l7<¶ø±“!X•ÑN燸Ùï÷Àõc,Š*Á ×Ýì–[–MÙ;ô‡ŠÀ/|† Ú²‘8qƒ ²ç˜!.$–œ6ê‹äAÞi¯p¶ðbGA¦WXkrÁñŤ™•S¬K²Xn@r„¯J0.bþfþyPYQïÃ#kû3-1 9í”ïòÙT :›“(7‘6ì œ5G9šŽü••VعzâÔ?ýã_÷|gÁÔmèÚ•ž7óKËψi±RÊí¼¹DúyY÷M”³´B¡–½„©˜=Hùq€Ù&@u¯ /Îív~ó£ÅLPæÙÒÑ÷ü[`çȪüå7‡÷à,]¤2 vÀ «ç7 l¾„àsï׎ü©€‰V aÍÝ€÷u"bÁ;k åMÒ¤ázxnÂ-ÞK™ÏIÓé õÞmØxvÎ)> йÄÇõ}€À‚i°Ñ%Ç&‚Ä\0ÊvãË@Œ¾T‰T?ŽæW[âSï\hðæ‹ ¯Ì2ø—Óý~<ÌæçÊŽ_ô*Œ!Jxº%‘Î.ֿܾѫ.õ!ædmŒFÖ±\›åk¸&X€êZ§Œ|í²RkÃð*3¤‡Íœ•ÁŒÜÃ~¨fûù™»á )‡ò¥ò÷—sO­t’܉:À®¤µHdÉ‘ã%©1~‡ ‹ëšGáèËP3J’ƒ÷ëNFÂÝ1¦Ò}À·šˆoú·rYæE+N)ê"¿õÑ¡4¥Ç>f<:5>è>“lÐ~=éDõ?]i9p˜×à›®â,jDí 0e’×-×'õ½›ÅaŽ1Óq}‰È†Í5îÖ‰iUví#Ó«^Ï–ûÃωSoŒ– ¿Ýƒ% ¿\›Ê],mMÕc§ü0Î—Ž† î(,HNm¸ÆýdÆ/ñèœ O°Š8Ÿ&…=bbz4«Ë(Ü 0½CËöÆÍè·ê2VAaæö÷£æÍF_í7îÞôŠ·ßà*ÉyÎN3È;³Œê|vÖG&@U¥¹¢.l‚7”¼êb`8ìÈ´—Ce>ðÝóZuyáÍr“REÜÙÿ2±üKÂ’ïëô;4ã4M˜õsuÊÇt²Æ[AC%¤[F`–â¨ÖpIÓ»p:éø7Ã¥³âl‘¢OŽ|Rt^q÷*ÈlsÏ"¥?Öçß4©ð¹ÒÐS˜¦˜Ê~S"Õ‡mË Y%G~ëíÐD:XajXÊ$õ2º™ªÈÛWѵ¢½É²ôG ÃîDÕi¥“Á{¹ÅÄñÍ܈…;îH`} c$PG(öœ¨‰Û,ž`¼Sjqiÿ4UkÅòT²Ž¡§¹:‰‚&åÐë¥Ìè jzÍ‹¢ç Û õe*û•ùÁ»s‰%U„ ϬϮ†n+¥W5žó…Ó~ÉuÈyk|"`Ÿ±NÙ×£…¨ž…‡÷ã¶ÝéºTþëïV{ìe{'O·9äÚTYt’ô3²lŸ¹§b-击6&æn ê*¶pë‰øÕ+óú÷† 5òØJjS³¬ëŽö²gý/ë%’²w{E@5D ffe”EÉ;)(j­èôã#÷yµqÞ ª˜¨ð(, ŒD!kàÿ^“èÔÜ[ú¢úÜL±:;Ú-s|Ï%kx7RY.Z(ùyIsÇ}ÒÿqˆŸÒß-ž »ÙQ7…¾#ÍL'['ºâB™#µFD”Q!…#M½[+ß5_¾4ë÷alGîw««_=߀S{ú™ž7ö•Z²ºj<ðŠ|ýænAf…âðr\Š«p‚:G¼b„f¢9pík]òÀp4—¶W7OÐ\l³M¸]¤oH~ôÓ+4ï»Ï§dO}ÏžÛ¨n>m{F5-ÀÒªµx©ø£%•¢[ t‰5éØÚX·ÚÚ‘BÎquu­l6¹ô1ë‹\‘IjÖÏ)FŠƒØòN)ßwQH7L¬Š~¶»^¼¹9à)ÿÜ~Ycñ¨ÀXqµ+ƒñ´{.4ˆìÃ+ÑTÃÄù0‘Æ ÙN&¿eõ‘ƒÇwÏÑÄJÅ &c*º³2º¦K\”1–ž 2*è¶óaQ·–ãnëBîPývO°®/HÜ\3ËôqŒÝ'£ žÈ$  ÚŠÚ‘.ì,Ó]ÅÖÚ-¼êb“z#½ïP|ýÑŒŠ²n÷]Þ…£w~éüÙ{\ÞDAMë¤lÙ„oñMçE!;œmbÅ™{ñç\$åGH:äÖ³3qµKú—­/´b Ëw_è³XÓ}4°œºù¿r|Õ¯¬÷ý!>ñcø†jø„*‘s¤8Ðsœoð,"Îà¢ýÐ8,ý`kÐLknÞá"T`.Zfƒ¤õIz=úiFß®yçó†cÂïõßÞõ®êˆ/ÝéÐâ³ÜyÍã ⹘ßéÙˆ2h_DF’m”6‡ž}ÚfðòVI*Ðu²p‡ÊÈp²Ù:ù$ª5/d4ï<å•úf ¶š!¯Ó^ð&aá–¸~âÅ¿¥„]¢@n× äŸµ^—z‰1ó\Ý@U®{äÛI~çnï8dðp_/F\vœšT ›½4ˆatD¿›è¤vÝË=ʆ»u¼nY!\òÄ~rS@ž·„I'„az€Ù§pT²“ü|a+rìqȬ”zÅtEÚgük¯g©Ú<ËŸÚ »SäJûÑýùE„!—y[I"kc$ê22%Ýäôb_·d2ßöµÊ ØþlGÚ?…g“Sc¯«¢ÒèÑ&‡ð/|¶c³Lâ–ÓG¢ ¡D¢9É´áµöQ¬"­CŸÒ†â%ʦð;›Æ©‰²ß΢ZƒŒãgöבPì1ó"Å\‹’ýÛ¿ƒ¹7—póÉá¦=jJ©B}IÞØ$G?IòUvQì˜OÕ…ÇvëaŠÏ>ª å5\·ÛLºm ¿a©m^È3¿ÍñlîÉü8—ÝrX·ß*yºíM±à–'ŸîÝ~èò“ÑõjÚ(ì™OÐŽ°þ·Èò…Éb ¼à,vV¡ÂÉ›íòw¥+„.¥xØ }]¢ü9êŠC?kÝEëë©@þ¯‚k§1¢éâ¤çœ@uT{gÿ–Sbþ7–Fîèþ_#\õ6ûÙèÐʾîÑB;C«ÈÄg–57·Ç¶ó†® m(ž,îÚf{·yÍJƒ>Ó'†u:k}1u 5±½|Ølâ×y§1ÅÔú˜á"¯ÑåîÀ1;BèÒßó*m®ídtMW¡²I¼8KÇŒ‡üåQg*º–Ä´øµ®q Ùûd)Í1hg 륗ºªÚæÕ´ªªÔÔv­ø™w­Y£Oõ®úÎc$拯<ªçó!;Æ0­CE;Z*]¤¨›²ËÅÉtT¹³”HwÞÜwºþ¹O­êòŸ5ºFUÝd—#ˆgh?<­šFÓ¹5=%WÌWzÖô)L:R¯ÂÉ©©ðrÜN>ôi©¶c3W$D‹¤]O¯˜ì‘vj:,”IÝÞ)’‚‹¯Úñƒ¸¥‰yrAC†*÷ÞùWV¶4JJü=—4³l²Õñ£¸ « ¶æì‘jSðRMLJ»hà@܉½uðA+õiÑ ”H¦Ç³Ã;cWu[<‡)¦àؽ„ÙŠk2±Ï=ÿøèIÜ“cÿ{p¦zõ6U«Vó –ÑèZ¦ ÑÒÅ›ÇaMU)l" ÃˆåuµN;݈+T>!çì]ã#´§å“ôEYë»#+ªŽ:+,{½W9B®Q\·jvUÏÿY…'U²+ÅÜÊÑE„ZõtÄZ`º%sFnP±z®¶–a pwô*Úøt#ôí›dcðå±v4¶Üvg3ŸÑ‡Î‡žŽ•ò>œ„§TAì­ª[43®¦¼YwÏ?àƒyÖî°/=+*RÐÉd#ï Çš÷öRY/©·ÁLO±.;ƒº-%w³é#_ï(yU*§‚ì ¦x°>ðprלlöM~¶¯»=m&A£±¹Ä2qƒá~M™aJy 3,¿ü“JšW•ZßE¿/¡µ(·{M²ltb´û!Kõ7¤žÑqLqŠïuì¡A§õ£ÍÚü©¶ÈËä’º®>1Åb>[¿*¦YžH'K*¬“m5ð2Žô0§Š ë¾Zïy!ÞÛ&[ykŸºGmÞ€cCëÎul$hJM蜖ݑ-³çL¯ôÓ4h:¶ìµt-í¼‚ÑdŒ4Áü°l.Ïëò’Cz¯u×cѹ¸T(ÉíKì‡…Ò ßV|kðDi|‹¸ï"H§D†5 :$šùIÑ:ýÃ.œR_-üÒ¾°ÌÿÜJ4‹—R©c>+u ýñÚ–ƒªÛè¢MÒ“~b6§,|¸ÞןSc⌕Bµ5 ª×oŸqƒ='Õþ'a“õÓrRQå _bjF–I…Tž÷¯p|ùj¯Çå`NàIî.BU+t–ÖDÆ©÷«À€¬Í€Aß°Èy0²·Š_é¨H‡mðŠ^}‘<ßhïg—VcÓ„í s~{ŒÝ›ÃJic£¶Q"IÂvvI¹&ÀÝÈË‘“f¢U¼Û,ÝŒÝj®_ ŒMøë¢"+N'i«õ¥5˜ÍFèõô&»™„œ½¾èr½Â3¯¤=Qï,Àþ¸q6~ÞPG Ä0›\ç*áø…;K`FþY`ùq3ó\Wæj<€È~Oje…9Ž-z‘F½1F™º'§p„ȹ,^ *ÓIª 0ª–lY} ŸIS3œŒëµ+”ç)ÚdŒXrìuÑ%,¤—ë@$L\™.ë·AReõ^·O¾vX0DU¸v=å›×Kô =á -`ûku™í2!iý<©6VÈ®u “kánuÕ|yA˾Ó1ºf#kÚb¶-uoûA¡~\:_®÷é.ÞÎB“g’<0gT.Å#lïO]ù½¥‰<ëaÚm8öû a󸯏gÜê7ÁÛÕò>{µrÎ}‰#‡èÝ£Níù‘ å¼¾OXWX}¨ZÂè“ÈLÕ ­ý˜?4yË8Jü,7•[šð’ÆÛ¬…ù7¢zpÏ `Z¥ ·0 z“b“‘< €IðžÌ Ù€ Hž›qæ[óI‰qG´öøWùÊù³ê‡U|Ô ê®ú«Ó@óªq!ù¯U;#¬y\Í‘¼>BÞ 84l'-Eâ;ŒA ÀëØÕÊq[ŒžŒyáy]ƒ«u(¹K(ÏŽ;hæGMQ»åckˆc v(MLÎŽÞFh*+é‚%ÙÚåN+ôs”ÑØXÙ¤‚k ²ë'a>*4®œ·UM¯?ÄÕš#Ž7v9Ô­•)+ˆ|1ŽPkR›ÞYÍ©ãðÉjó]LßrßêÅÉÅÂc¤±SqøîÎÉccµ@¼óˆŒE"°B>úBQ€dN¯Ðk ?ùÿ©~ä endstream endobj 978 0 obj << /Type /ObjStm /N 100 /First 984 /Length 4535 /Filter /FlateDecode >> stream xÚí[[sÛF²~ç¯ÀãžÚ²æ~«ÚÚ*É–d%¾(vâØ›Ê%Á7”¨ð’ØûëOwÏ€,Rª}Ù”­Á˜¾}ÝÓÓ3$ƒs/‚ …rpõ¼p¯¢ð^ÃUBùUˆ tt!•Ð1…’ÇX u:®ÐZ‹Ið¾Ð‡À cPY˜ -tta% ÁÖ(_X§t!8<¶´€ž,œR{ºpAPÏ^8?ž/¼Vž ^x ZAO>pêJR ò@!ì¡v)$¾PÖclãZ‰Æ ƒ¬ÀžÖf¢@?!Œ .pÔ4ß"E½`ÐWÉÁX È)Aã°§˜Ã±§)4ÇqðUôÖq3ÑôÖ+Yhá Œ¸@AÅ\ o•œu•Ò( ´RÔ×(”±¡ÐÇYÀÍ Šà ô›“‹V«úZ(8¼!@¤)Ú¦¥³àu| Ä7ÈÐêöŒCô%¬-ªÄ‰ÆY‹]`®½E§H`˜Dl4FŽí„áÚ@X[=Š"°ÀHm¡FAPI$hÐ3R#„ÜD*¤°d(¤p ^J¤ð°Ae †”H€«D\-‡1ˆ£°¼ yÀD¸DŸXÔ#RX%ÂD õVc˜ J¢pñ,,ÅúØZD×#…ƒ)¼I)( 1Àl@«2ÇÑ N7°Ð‰Tˆ“ ˜(R5RŒSÔ\„q€–b)p¶ ôˆóèÔÛyï'¿€ã¯¿ÿÚ߯“_Ð I§? Þê™JW³ÃŸÊþÉxBÌ„ÂzùŸ)ìÁÔÀ–úÎØ—Æ)‡-$bz.’úžžÇ1È5ÒzɈ¸Ëf\Èi¢¼±MutǾ6ñ¯ê+ÞÜWãð^ŸGšÌV¢òÀ¢*áOmâªb¯A_L£ØÂªr  ˜`äÔèkxûñícÚÈ'oIh‘ËŒý\—¼ÿVp‹†ç¢Nü Öé2ü&—Ý~Ó"m?³:ÀðØŽI^Y=rÜÃèØÂš ObË០• 6Žˆ AÄh¥67!JöЂ.AÃ,€Åãª)¨Ï<Ä8ò±XpŒ ã j!9zŽ_ÅpQ¶¨†·_hlœVÈÄBÃa€ã L`í±Â±Ú+K+>7Ý« ,cÊÒà8x‡5©)âĵÀßò4Ú :Æ9RÈãôúÈôÐX³A»•.þiÐÃ>A[ñsVÔÏò¾”  ö@d& D ë©ÁB« ç$:H ã´Âd4¢åa%·Ö¢öÚ¡S½‹NîÁ¾#×hƒO¸$TPŽ…ÕÕ8tf9Èl¬¨†`œòø6osœ´à”5ô,j%yÉ£ß yÏ#G¨¶pyŠ0¬ä0ð@©CÊ“WÇHÑÃFä¥Ú1rÄ$.½.©}JéÞCZª—ë5áÁd`JMÿÓJ^ó$ÜÜ[ž‹mïP‰%´¸LÅê@:¶4ñaÞØÔÆdªÄHm¦d”æ‚Çù<%úêaô+Í6'#ÚÄ]a°EÀá„-V-ÞTžn íö2ˆYòFÖϼGO[>• ä ÓG(J€Š"+9${›").tØâR)4-µµ#-æ/ˆp7•Ö…fŠa¹uZU–l÷S1›iüC.øGÅL å´èAþZ™z\Î?>ñTà… ër¨]x¡´¦×ŒÈË‘¼˜¢w±0~’â­Ò&+Ý,–`±MH)< ¢=_´OS:¢rÌ*HYqõ‚QÊÐΊ+¢”EòM *Uñ‹”‰·äqu¬xã¨xÌgë|Ëàv¯¹C6ÑM/w#>m\‹©§{„ž(êQñ]å[W‰Í»>Ôm–R#/ű†}¬Õ×F>yëD É´õ¥6>AwáYž¦âÂQhÒ®Aâ~ëcAÛr•F*‰c4L†È¬t’¸€ÐûÄ•¨SßcÑc¨:Ž’Ljƒ¡z){‚•±h!±ÝÏŸDΚӖ8ëCIH•w3&ÑÆç´¦&lœ¤U•hsž4÷H¸åG[©©ÄPHÃÚKë¯Âò-¶Š”Vi›hÛ¸¡¤СO”ÞUïñ”/xÅçoÚ—x‘$ÆÑ±ßŒÒt¯³‡º7®áCÚÄ1ÓŒ,P"œHº¶º(“6@­Ò1Sœ!Þc zJÊZ²ÐÓ\²à1<3¶´y¥XlÇ|bRß+Ü&£;œ§­¡Õ4.†P‰ÇnÚÆûÆW('G#·Èh:’ÑOt¥2<÷/>my=ÐÎN4^!ºzl|¯ ê¡5í ›Qô."û©Å(A¿Nþñ ûñë}Y°“ÅÝúE¹º\Îî׋å„îßLoáÍáwß}<;ùûó×G…„óéõªÐqÄÑÑâKñË3£ŠgO›…¢³º_'ìpuYÞ­±¬Ÿ°çÓû—åìún½0ƒïž |y¶žÎg—‡w×ó²àö~]Þ~À>&ìc"‚‚xÜL—ïËuñ7vÈŽØsö‚³vÊ^²3öнfoØ[vÎÞ±÷ìGöû™}dŸØ”MoïËåjzwÅ.Ø%»\Ìw슕Œ³òîjººaŸÙgø?ƒÿ”ìób³d×ì†Ý|½¿)ïØŒýÆæì–ݱ»Ù]Élí=»Ÿ.Ë»yùy{Kâ²f‹+v?߬ØïlÉVlUþ#À‡2ŽŽ $~ùàIðþvºyQÎ×Ó”t"ö˜z¾«“ÏÛô‹æåf]fKçtIh¶ú \u±œ^þV® ÜÔØù0-±åï›éœ•_.!y¥õ–Ü´æÎ+O_/§pŸùûß{/¿¿oÊ.'cAwÍó,LÊÛY4¨YÁëÐyÐ:Sk§eëäãË“N)†Ü@ ©8iƒÆƒcÈ ÄQy ñ<†ÞB<\Ô™©Œ^šþÍb“ÃÑÁNËÍOG‡ç‡”·ì@Š®Ò~;á)¦‘WƒÓ(¥ º$ŒáןUvcì´H|:=>ÿ é*¤|ÜpÞF[Á¨Ž=;-D¯Î>£=k®²Õ:äøÓØc‡J)¨q(ù²7`þh9¶ƒÁNkÃÑùñáÉÀàý§Á=Ϩ>x‡ß¨PHö«<°°Àá9¬g°¼cÓårñçÅb}Sgx(Àoؤõ˜ë.¦KÊòeïSмØ@6…¤?[^ÎËËÅý×åšÝÎî·ÛÍ|=»ŸmC&vJ…‡ï^žždCq‰ ÜŠ{ü-<bÑsÑÊ1ŠÆÞ/g·eÇÒ2Þ»#Ø\cÆûqx¯b«­5WOµWQØ«œ¦r¡)ªõоºYú?÷×l‹o,ÜÝ5;[އ6Ððwʶ?>÷¯Oþƒu2`¯ðжôB´ ÇÛz)å>Urw“خԶ6ÖXmÍÔÝj³NQ–T;Ï­J,í:S9v·¹½€8˜]ß=ª2{|¶¹»=.Ër°¦‡ðØiñ:?ýðîÕq ¹‰»_üœ@âæñáazN¾R¨ì W‹ùÆÿÄI_¤ì´Ä¿ýù‡ÓãW)ë•Á@Á‡ðÉðè@©rÚ ÃãC“1–cÛí':ý}Ð'{ÌZ9P;›‹5ÝâC@áhº*ñÍö‘uËuôÅdÉNfËÕ±+øWÓêFÂùóìj}³¢ ûÎ⻇²]ñrK¼ÏÄûÐHwjwéÝЮtÝ•.yn¼0™ñrwñCît»e;7¹xž‰w{ˆïôuÅû®xZžç™t»»ôÎÑ[[:}¥¬#¾½ôzwés¨-ér\zõ{ØÞ9ÁØ’¾wø±Nw6ïvß>=Ø’¾wXð×ÒËünö°½µsß¾u::“Ýnoo³»ÂÅVÌéÜí69¾»ðîþvKüxЉÌv¿G²ëì·¤ë1é^fÂ÷XfºÛ·-é[A§üÐ|wawùÝÌ–ü­¸Sª%_gò÷˜rݹ+_ò‡Ë÷{̺Náµ%^ŽF~Ûü÷ŸO¯ËW‹ –j¸_baF?7#ÆßÏ®VÅ/2.ø{Ãxµ"^×ׅоýº—O“ñG$ñª£P„èè?üfÿ#„„$$~Þ„_#×$Ôˆt/õþBðg•ÄDótMÂLb’k!Ä&&> ‰á…¿Ó «åé³ã~Bl,M +£V¥«NÏ“ðÇ@»Ñ-!&1±2]£e6EMZo!Ä'¦±8,l¬“ íÂÅ<¸ºý…¸—“Qs—Á©è—`s¶=…$¸œMLÓüp.Yâ’e±´ÝSHš'>VTpðù˜pa]QéúM¸ô üí 1Q‘iˆØÁúo1U-ÕM+Yù”7xÊÉãøë\ºÆê‡¾?ô-)zPŠ5U<Éäò„~zîâ6€~Ãû )ŽWL«éW#Õ!{»YÏa‡ºJ ¿Hhb¾§ŸýÒ]d*TM:[Ã.S¦²‹B7®™ii?_–Я†ó…"‘óšÜºQr“^¿)¿4Zµ™YÛ0S-f5uREôQËš:‚½Me[ÓCm|CmÆ ÕF.1 ÙR[k–°O’öÏdWfƒ½ic/µÈíÕ}ЛzíF©M®°éC^7ÈkÕÏ+R÷j¢äUù¬¨IkØ(Á2­@}Ö TÕ8HµT³BTŸªZ‰1jrs•ëãÕ/Ý(¯ð½zÉx©FyµÜ ûÜ 7ˆ0ÆK´¦ƒì›¢A[Œ¢>ö©xõMLÑ`/F±ç-ìEö¢ÁžbÏ[Ø‹>ìyƒ}u@Ðå©yÚéK@-ª³•nЧ)#ZAÏ[AŸ¬ úÐ"ÒןHˆÏJ²5É][&ÏeV õg%‘¾)G2ù¨L™£TYÝf–¾Ó‰Ì¼m3“¹¿DçÔ'Q›†ZŽR·4éœ\&^¿œãål‹WŸ^®q‹Óc¼´nñâ}¼¸]îŠ:ò²}VÙ_kG©[štίm+GyµÐî׫AÛø1^¦…¶íCÛ4h=ÊK¶xõ¡m´Í(ÚÚç¼L_lë{=€}¢îC[7hëÑØÖ-´]~²Ò¨I3»rk5³]Wdã5:TË)ºÏ)ªqŠªåÝçÕ8Eñ1^²åÕçÙ8EŽ&Ùr‘ês‘l\$\©eß ÚÂåÑvòj}FÒ¨œ2[å`ÁQæÿJ£]2 endstream endobj 1073 0 obj << /Author()/Title()/Subject()/Creator(LaTeX with hyperref package)/Producer(pdfTeX-1.40.14)/Keywords() /CreationDate (D:20151005141246+02'00') /ModDate (D:20151005141246+02'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian) kpathsea version 6.1.1) >> endobj 1027 0 obj << /Type /ObjStm /N 74 /First 668 /Length 2604 /Filter /FlateDecode >> stream xÚZÛnäF}÷WÔc¼@Öu¿A€ Áb¯³‹½<-ò Û²­L_ŒîödæïÃSê’YRI“'Ë$‹<â:årl±x‚§îó~‡ÆKÍ<ÞQqóv”ñþøØ §.acë||»?Ñ^ÁÎsºÒàØ¸ï»q$˜JÓï!ãÖ—½0®­äŸè°Œvã¥u‘In¶ªÐ¯/=õŠT÷ðÊ;àKwx–’ıš>YŒó­šl&{#ØÏÅ;ûšÇÓðüvÊgµ§Ì"†çÝzýªѶvM¬¹R•×î9ÇÒQqÚ¬6Á¥ $.AÏ-µ÷°“ÙÚ¨@ñÊI:J°S§­ªá°*çý(ÁöÓ•M„dQþ)êdµŒúÂŒ’1Úr«œzYŽ]ƒyÇ‘jïUWº}·jãÒËwzO]ƒžX=±ZzReƒ}:~Z³†¨“U,Ïù2ýÌ#\=ue£!ᄃ]^Ipâ-'k :­ÀrX¹?bÇ» 欫l°=/¶ÉSŒ³L°LhÓ… Å¨ Ë‚œÀCZSÍ‚œªhä¤ ÈIžKp'\ÞÖ¦¨“Õ 0å•Cb'(^5‹ƒCñYÜP«Ê:#¼ï^tlãò·ïVm\'zµ^Y §Çá c+ÜÆªê;ÐSÕÚ!ãqG-€!êdµ ôTSÒžÀ)tù/™ÄãBÈéñ 'òŽóùíªÝ÷:YµqùünU9ÌïV¼{<Þ­t… ïVº†w«j‹ú€SÍ5ùiäû°Œè‰¶ Jô¤ªŸÞx!Ñ“_„ÛYuäÛe»¿²-@û‡Ëp<ü )©OB°XΕIHD¦BÛU˜WÏ$„Y%7â˜]ÞJ8n»†6¼ÚÇ™s¦K/!¶I-!+U§„a¦fHЯà_¢ß-Waâ6£û%Õ¢@3YBø‚òíþTP¤Ê¡Ö€+×0cÈÌí—À™Êw¢r¯5™~»Ð¸¼Ä4äXrœ›ª!Çñ²Øc tó5[ù¸<”—ÄùüYOhÈqµä˜³ª!Ç´u y€ÿh6rÉÈæK¶R €–Z¡°5SCŽ—¦¡@›ËÐPx4¥j([¥Éèæk¶Ò‰¹§mÇ!CC£±¤¥Àön´TÌ×P€“62Šó^‹ÍMÏõ Ï¶2}¡…S ¤†£ 2Wõ4È;NÚU56žŒ›É•ɰXÙLqf…™[®¹ µ…Ú¯ª‰z­åªÚC½ž[€:®ª#f‘n¥¾Ì¡½þ÷e-CËcíª:Ï츪»®É®KïÔš2¿zýŽäÓm{õWr÷#o.­ÅÇÕ¼ÙµaDÎwu­Äpk¦Ça­lXÓb*,?1h"o®þJÒqœþʹ5ù&‘Ö´˜4mR ÅÌð«©åÁq¥åÒÝïúñܲÛÉ^O+ Ž 4Kùd|”ä÷tÃ%xõ^žcÓúÉj ñ·á‘,òuà&ÿVg|¸~T”©s}ÐåÁl}¡²ö‘n 5~9þ´çúàËC(ŽI_ýÐuññM dK¶d`K×±Ÿt}p_ù†¿N p[€ÛÜ]AáÔú›eë>]‚¸ÚЮ€v…AW€¸°}^9§X¾+ð}ï ‰¾àñæ«GÖj¿ù’‚/)ø’‚/\úƧ­~[Äø©?“QþqÿÎòËk/î~ì.ÝîøŒ/+Ÿ{•ïÿùvÙ ‡QT¾¾ÌÛ/ÿ4êúýæsÿãc÷¿s_Ìiákø!çL·gW"þk€7g endstream endobj 1074 0 obj << /Type /XRef /Index [0 1075] /Size 1075 /W [1 3 1] /Root 1072 0 R /Info 1073 0 R /ID [ ] /Length 2556 /Filter /FlateDecode >> stream xÚ%˜[h]YÇ÷·Ï9I›{Ò4÷K›¤MÒ¤éJÒ6÷¦¹_Ú¦izÒ¦·´iADÍÐæ¥ Âø0Š£ŽÌ0¸t`ÄŠOÅ|…‘qƒ¸|3VÍøâƒ2¢xaFÁz~óðËþþkï}ö^ß­õ­Eöñ³8ŠâÈ¢¨šûq”Í´¡ˆÑšÐZ 3 ‹v ­…0JÐŽ£5–‚h½hM„AZZ#a9¨@;‰Ö@X ªÐ†ÐVƒ´Shõ„µ m í¡Pv­ŽP7h@›EÓeúñ&´E´B=x Úm4ý¤^ºØ––¡U¶ƒ´4=n'8‚Ö€VAxt¡é™õªÝ Í¡•ÇÑ&ÐÔM½ mía?8¶Ž¦.ƒhÐJO‚!´M4¥çphÛhYÂa0‚v M©§Ñn¡Å„gÀY4õ‹l1Æã(ÎÇhá˜D+vI¦ð€p L£U¡Ý'œçУí΂óhGÐîÎy´ãhw À"Ú0Ú.áXF›D»C¸VѦÐn®u´y´[„ÀE´U´›„—ÀÚE´„—Á&Ú%´Â+` m í:áUG»†vp\C»‰¦P'ï'ZžP?tí šn¥‡¼Vƒ¶E¨ÜESÿé1Ô9÷ÐÐ6 Õ±÷ÑÑô $%{ÝbDC hd5ÄhmhôAÀ!‹¦¤\$ÄM¡íýpb8€v m‡2´14ú>0Bš’²JÈè UhÓhä-0òB Úy´eBFm¨C›C#çÁêÑ–Ð ì¡m ¿{hB[G›'d°‡´ hx-0ØCšžÁ:Ю£áÓÀ`GÐn¡#d°‡â`ϸ  öÐâá8``‡åÞeÌ„>ÐÏêönÀ] â0t4ÄÁ†n Øp0LÃYÀà ã€!&1L=šžY/£·Ôë«_ÔaêIu±ú^IQ¶”FåW‰—#ð_À\aÀ¢Ò½–ì#_áØ€•˜?0*# 0޾Œ¼€Ûc5àñÀè8;0ü˜AÂ&i­V´Fe€V¦ÐzT ´ Z{ÊVœJ u¦Èa›U¼¥;k¼ßèú—ZXƒfPgQ[«Z5莂^ÂVÀª±ßX+ö;ÁQÀ’°ßZ,êú¼nÀ’°Ïú±ÜÀ,àôÌ€Ù{¿èœM]1ȯéÎLáû£€‰{ [4úžÎ;Ëy}€%fÿ GCÜY1 ¦À4XM}W×ÎA=î˜ `¬‚5°.€‹àØ—Á&¸¶ÀUÛà¸vÀ pÜ÷ÀPâï€e‹¿¤‡d º À²ãXg\5 ƒ®Ôrä˜ ³žk- 0ü\;è€YÏi±Æ\©¼¶kÑF9¿›êÇïsÔeѿߑ†ëÒØ¢û(ĉ)žL1aJ§¥}æ¡ZñdŠ SL˜â°‡¥µ Â¢¾­óx™3«;FØŠÖûB»ZY ¤Ãz)ÆL)bÒÖ¨ø÷Œ#Õ%*bTµ4YôÒc]‹;ÓnÐiÑ+¿—†‹*ýšnÚcÑ7KÕª © ‘>‹¾ó5HS!r`Çt‡Ð÷¿®Sp]A5ˆ Œ3@eÅÀ„éˆEowéäq~H¿×Rœ˜žÓý¸S§œã~:e,‚9‹~þYµâÓtàÓO¦KVœYÔŠmSl›âÎc¦—,zºªVl›bÇtË¢÷ÿ# Ǧy~R‹aÐ bÖŸ¦ø4ÅéŽE|¢Ëpq*—àÝ´hŸ¿=¯†= Í<«i>2Ël³&ç dKo>gö³ƒj`5Í—ÖÆ|©YÕ§ÔÀ’šWÍpŒ#™€#ÖËü!ÀŠ˜¯5kþ»®¨çd¹iÄ µV¿|;`ÍË7ƒF³ž]¦r¡QÐGA‹ÙЇjÕ˜§3;KC7è½ Ëlâ]¡Ç=úÌV¥õƒA0̶žªá$Ðïž2»S)ÍÓà £fŸøH­šúô@jP:nöðcµN•¡³@Åç˜1{ô-B©áTå.Õ˜k`Ñì‹/ê” bqÝìå¤]*¯‚Ëf¯©á ¸òfo¼-m›‡Ô+Ü;f;ÔpPæåo›ý QÚ@™—Ç>‰¬r×ìGVëpŸgž°ø“¿U…§R-6û¥näæJTש@+齿ªU5\%(7Kß•ÆÌZ w“ZPeö‡7ÕP 0W‚K’:³/ªAJŠÞøÇ§¥1ÇÈj‚œ“t˜=“¯’N@â ’tY|p\ ˜&9pI‚©Ý3$˜!ÁIŸÅuÿ*M2$Þ±pShôn¢W —ɰÅmÏt2îLFÁ (öZï¼ØÅ$l=’s?' —$¤;Y°xòkÒØ‰$—ÁªÅK?‘†A’K[$äÐ)*üÐÀÃ(néßÈ)<r?¿­°”Mÿõ?*UƒV­=Ť¼ø;iªPNÕLîxÿ¯TªUû2ÍÞì²Ü¬Å¯^Uu„[TëŽòÜ­v^n Pž;êqGîØj¹ pl‚+€ý–» ˜CÈÑŽÝ퀀ý–S}pÜ»à.¸Ôu3ô•çI=}åc@-ï³ è&O7y 4Ï”ëË@9`¤xjO ♆=5ˆ§ñÔ žn÷L¾žŽõ”$ž’Ä3³zJOIâ.ž’Ä3I{JÏôêY{<9òì<©ð,EžÝ˜guö½€iÝ“#OŽü ^°hÛ×>Ò Rú~‹¿÷U…ä×;@òü`ÚôÌãžyÜ3¢<îô¤ÖO˜g'çq¬Ç±3øY@º=¨Ç~}Oö=Ù÷dß“}Oö=Ù÷dß“}Oö=Ù÷dß“}Oö=Ù÷dß“}Oö=Ù÷dß“}Oö=Ù÷dß“x?`ñ[ÿÒûb<>ðøÀã<>(DVRóœ¶æ˜¡€ ÚØa†f(`†f(`†‚Öß2‹ø².+·ø¿¯è¨Â2m?ÕQ¥eöÞÔQ•e>÷TGÕ–y¼¨£Ëüe\Gµ–]{IGu–}Ø¡£C–}µSGõ–}R££Ã–ýu¤£ËþóW:j´Üá_è¨Ér»§tÔl¹'}:j±ÜŸ4 šIcAM´!Ÿ¶’î÷#¾ç´ƒÐ Ž€£  tƒ €úê§Ï|ú®×N€0ôqO_óô)Lß¾†Á§Ápè“Þ8ÐG1}›Ó`è Ÿ>és`,}×[Ë`¬‚5+éz½˜ß¡GÑÿ•Äò endstream endobj startxref 405114 %%EOF phyml-3.2.0/doc/phyml-manual.tex000066400000000000000000004513231263450375500165620ustar00rootroot00000000000000\documentclass[a4paper,12pt]{article} \usepackage{fancyvrb} \usepackage{graphicx} \usepackage{tabularx} % \usepackage{color} \usepackage{xcolor} \usepackage{psfrag} \usepackage[fleqn]{amsmath} \usepackage[hyphens]{url} % \usepackage{vmargin} \usepackage{cite} \usepackage{caption2} \usepackage{hyperref} \usepackage{makeidx} \renewcommand{\captionlabeldelim}{.} \def\thesection{\arabic{section}} \renewcommand{\thefigure}{\arabic{figure}} \renewcommand{\thetable}{\arabic{table}} \newcommand{\hl}{\noalign{\vskip3pt}\hline\noalign{\vskip3pt}} \newcommand{\hrf}{\hrulefill} \newcommand{\tc}[1]{\textcolor{black}{#1}} \newcommand{\dc}[1]{\textcolor{green}{#1}} % \usepackage[none]{hyphenat} \newcommand{\rep}[3][1] { \psfrag{#2}[c][c][#1]{#3} } \newcommand{\x}[1]{\texttt{#1}} % \setpapersize{A4} % \hypersetup{colorlinks=true,linkcolor=blue,urlcolor=red,linkbordercolor=000} \hypersetup{colorlinks=true,linkcolor=blue,urlcolor=red} \renewcommand{\baselinestretch}{1.} \makeindex \begin{document} \sloppy \begin{center} \thispagestyle{empty} \vfill\vfill % \rule{\linewidth}{0.02cm}\\ {\Huge \textbf{ P~h~y~M~L~~--~~M~a~n~u~a~l}} \vspace{-0.4cm}\\ % \rule{\linewidth}{0.02cm}\\ \vfill {\huge Version 3.0 \\ \today \vfill \normalsize \href{http://stephaneguindon.github.io/phyml-downloads/}{http://stephaneguindon.github.io/phyml-downloads/}\\ \vspace{0.4cm} \href{http://www.atgc-montpellier.fr/phyml}{http://www.atgc-montpellier.fr/phyml}} \end{center} \clearpage \tableofcontents \clearpage {\par \small \noindent \copyright Copyright 1999 - 2008 by PhyML Development Team.\\ \noindent The software PhyML is provided ``as is'' without warranty of any kind. In no event shall the authors or his employer be held responsible for any damage resulting from the use of this software, including but not limited to the frustration that you may experience in using the package. All parts of the source and documentation except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. } { \noindent \setlength{\baselineskip}{0.5\baselineskip} \section{Availability} \begin{itemize} \item Binaries: \href{http://www.atgc-montpellier.fr/phyml}{http://www.atgc-montpellier.fr/phyml} \item Sources: \href{http://stephaneguindon.github.io/phyml-downloads/}{http://stephaneguindon.github.io/phyml-downloads/} \item Discussion forum: \href{http://groups.google.com/group/phyml-forum}{http://groups.google.com/group/phyml-forum} \end{itemize} } { \noindent \setlength{\baselineskip}{0.7\baselineskip} \section{Authors} \begin{itemize} \item { St\'ephane Guindon} and { Olivier Gascuel} conceived the original PhyML algorithm. \item { St\'ephane Guindon} conceived the PhyTime method. \item { St\'ephane Guindon, David Welch and Louis Ranjard} conceived the PhyloGeo method. \item { St\'ephane Guindon, Wim Hordjik} and { Olivier Gascuel} conceived the SPR-based tree search algorithm. \item { Maria Anisimova} and { Olivier Gascuel} conceived the aLRT method for branch support. \item { St\'ephane Guindon, Franck Lethiec}, Jean-Francois Dufayard and Vincent Lefort implemented PhyML. \item { Jean-Francois Dufayard} created the benchmark and implemented the tools that are used to check PhyML accuracy and performances. \item { Vincent Lefort, St\'ephane Guindon, Patrice Duroux} and { Olivier Gascuel} conceived and implemented PhyML web server. \item { Imran Fanaswala} interfaced PhyML with BEAGLE. \item St\'ephane Guindon wrote this document. \end{itemize} } \clearpage % \section{ML in phylogenetics: the basics.} \section{Overview} PhyML \cite{guindon03} is a software package which primary task that is to estimate maximum likelihood phylogenies from alignments of nucleotide or amino-acid sequences. It provides a wide range of options that were designed to facilitate standard phylogenetic analyses. The main strength of PhyML lies in the large number of substitution models coupled to various options to search the space of phylogenetic tree topologies, going from very fast and efficient methods to slower but generally more accurate approaches. It also implements two methods to evaluate branch supports in a sound statistical framework (the non-parametric bootstrap and the approximate likelihood ratio test). PhyML was designed to process moderate to large data sets. In theory, alignments with up to 4,000 sequences 2,000,000 character-long can analyzed. In practice however, the amount of memory required to process a data set is proportional of the product of the number of sequences by their length. Hence, a large number of sequences can only be processed provided that they are short. Also, PhyML can handle long sequences provided that they are not numerous. With most standard personal computers, the ``comfort zone'' for PhyML generally lies around 100-500 sequences less than 10,000 character long. For larger data sets, we recommend using other softwares such as RAxML \cite{raxml}\index{RAxML} or GARLI \cite{garli}\index{GARLI} or Treefinder (\href{http://www.treefinder.de}{http://www.treefinder.de}). \section{Bug report}\index{bug} While PhyML is, of course, bug-free (!) (please read the disclaimer carefuly...), if you ever come across an issue, please feel free to report it using the discuss group web site at the following address: \url{https://groups.google.com/forum/?fromgroups#!forum/phyml-forum}. Alternatively, you can send an email to \url{s.guindon@auckland.ac.nz}. Do not forget to mention the version of PhyML and program options you are using. \section{Installing PhyML} \subsection{Sources and compilation}\index{compilation} The sources of the program are available free of charge from \url{http://stephaneguindon.github.io/phyml-downloads/}. The compilation on UNIX-like systems is fairly standard. It is described in the `\x{INSTALL}' file that comes with the sources. In a command-line window, go to the directory that contains the sources and type: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure; make clean; make V=0; \end{verbatim} } By default, PhyML will be compiled with optimization flags turned on. It is possible to generate a version of PhyML that can run through a debugging tool (such as \x{ddd}\label{ddd}) or a profiling tool (such as \x{gprof}\label{gprof}) using the following instructions: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure --enable-debug; make clean; make V=0; \end{verbatim} } % {\em Note} -- when PhyML is going to be used mostly of exclusively in batch mode, it is preferable % to turn on the batch mode option in the Makefile. In order to do so, the file \x{Makefile.am} needs % to be modified: add \x{-DBATCH} to the line with \x{DEFS=-DUNIX -D\$(PROG) -DDEBUG}. \subsection{Installing PhyML on UNIX-like systems (including Mac OS)} Copy PhyML binary file in the directory you like. For the operating system to be able to locate the program, this directory must be specified in the global variable \x{PATH}. In order to achieve this, you will have to add \x{export PATH="/your\_path/:\${PATH}"} to the \x{.bashrc} or the \x{.bash\_profile} located in your home directory (\x{your\_path} is the path to the directory that contains PhyML binary). \subsection{Installing PhyML on Microsoft Windows}\label{sec:install-windows} Copy the files \x{phyml.exe} and \x{phyml.bat} in the same directory. To launch PhyML, click on the icon corresponding to \x{phyml.bat}. Clicking on the icon for \x{phyml.exe} works too but the dimensions of the window will not fit PhyML PHYLIP-like interface. \subsection{Installing the parallel version of PhyML}\label{sec:MPI}\index{MPI}\index{bootstrap!parallel} Bootstrap analysis can run on multiple processors. Each processor analyses one bootstraped dataset. Therefore, the computing time needed to perform $R$ bootstrap replicates is divided by the number of processors available. This feature of PhyML relies on the MPI (Message Passing Interface) library. To use it, your computer must have MPI installed on it. In case MPI is not installed, you can dowload it from \href{http://www.mcs.anl.gov/research/projects/mpich2/}{http://www.mcs.anl.gov/research/projects/mpich2/}. Once MPI is installed, it is necessary to launch the MPI daemon. This can be done by entering the following instruction: \x{mpd \&}. Note however that in most cases, the MPI daemon will already be running on your server so that you most likely do not need to worry about this. You can then just go in the \x{phyml/} directory (the directory that contains the \x{src/}, \x{examples/} and \x{doc/} folders) and enter the commands below: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure --enable-mpi; make clean; make; \end{verbatim} } A binary file named \x{phyml-mpi} has now been created in the \x{src/} directory and is ready to use with MPI. A typical MPI command-line which uses 4 CPUs is given below: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} mpirun -n 4 ./phyml-mpi -i myseq -b 100 \end{verbatim} } \noindent Please read section \ref{sec:parallel_bootstrap} of this document for more information. \subsection{Installing PhyML-BEAGLE}\label{sec:install-phyml-beagle} PhyML can use the BEAGLE\cite{ayres12} library for the likelihood computation. BEAGLE provides provides significant speed-up: the single core version of PhyML-BEAGLE can be up to 10 times faster than PhyML on a single core and up to 150 times on Graphical Processing Units. PhyML-BEAGLE will eventually have of the features of PhyML, even though at the moment the boostrap and the invariant site options are not available. Also, please note that in some cases, the final log-likelihood reported by PhyML and PhyML-BEALGE may not exactly match, though the differences observed are very minor (in the 10$^{-4}$ to 10$^{-4}$ range). In order to install PhyML-BEAGLE, you first need to download and install the BEAGLE library available from \url{https://code.google.com/p/beagle-lib/}. Then run the following commands: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure --enable-beagle; make clean; make; \end{verbatim} } A binary file named \x{phyml-beagle} will be created in the \x{src/} directory. The interface to \x{phyml-beagle} (i.e., commandline option of PHYLIP-like interface) is exactly identical to that of PhyML. \section{Program usage.}\label{sec:phyml_new} PhyML has three distinct user-interfaces. The first corresponds to a PHYLIP-like text interface that makes the choice of the options self-explanatory. The command-line interface is well-suited for people that are familiar with PhyML options or for running PhyML in batch mode. The XML interface is more sophisticated. It allows the user to analyse partitionned data using flexible mixture models of evolution. \subsection{PHYLIP-like interface} The default is to use the PHYLIP-like text interface by simply typing `\x{phyml}' in a command-line window or by clicking on the PhyML icon (see Section \ref{sec:install-windows}). After entering the name of the input sequence file, a list of sub-menus helps the users set up the analysis. There are currently four distinct sub-menus: % \begin{figure} % \resizebox{15cm}{9cm}{\includegraphics{./fig/interface.eps}} % \caption{PHYLIP-like interface to PhyML.} % \label{fig:interface} % \end{figure} \begin{enumerate} \item {\em Input Data}: specify whether the input file contains amino-acid or nucleotide sequences. What the sequence format is (see Section \ref{sec:input_output}) and how many data sets should be analysed. \item {\em Substitution Model}: selection of the Markov model of substitution. \item {\em Tree Searching}: selection of the tree topology searching algorithm. \item {\em Branch Support}: selection of the method that is used to measure branch support. \end{enumerate} \noindent `\x{+}' and `\x{-}' keys are used to move forward and backward in the sub-menu list. Once the model parameters have been defined, typing `\x{Y}' (or `\x{y}') launches the calculations. The meaning of some options may not be obvious to users that are not familiar with phylogenetics. In such situation, we strongly recommend to use the default options. As long as the format of the input sequence file is correctly specified (sub-menu {\em Input data}), the safest option for non-expert users is to use the default settings. The different options provided within each sub-menu are described in what follows. \subsubsection{Input Data sub-menu} \begin{center}\framebox{\x{[D] ............................... Data type (DNA/AA)}} \end{center} Type of data in the input file. It can be either DNA or amino-acid sequences in PHYLIP format (see Section \ref{sec:input_output}). Type \x{D} to change settings. \vspace{0.7cm} \begin{center} \framebox{\x{[I] ...... Input sequences interleaved (or sequential)}} \end{center} PHYLIP format comes in two flavours: interleaved or sequential (see Section \ref{sec:input_output}). Type \x{I} to selected among the two formats. \vspace{0.7cm} \begin{center} \framebox{\x{[M] ....................... Analyze multiple data sets}} \end{center} If the input sequence file contains more than one data sets, PhyML can analyse each of them in a single run of the program. Type \x{M} to change settings. \vspace{0.7cm} \begin{center} \framebox{\x{[R] ............................................ Run ID}} \end{center} This option allows you to append a string that identifies the current PhyML run. Say for instance that you want to analyse the same data set with two models. You can then `tag' the first PhyML run with the name of the first model while the second run is tagged with the name of the second model.\index{run ID} \subsubsection{Substitution model sub-menu}\label{sec:submenus} \begin{center} \framebox{\x{[M] ................. Model of nucleotide substitution}} \end{center} \begin{center} \framebox{\x{[M] ................ Model of amino-acids substitution}} \end{center} PhyML implements a wide range of substitution models: JC69 \cite{jukes69}, K80 \cite{kimura80}, F81 \cite{felsenstein81a}, F84 \cite{phylip2}, HKY85 \cite{hasegawa85}, TN93 \cite{tamura93} GTR \cite{lanave84,tavare86} and custom for nucleotides; LG \cite{le08}, WAG \cite{whelan01b}, Dayhoff \cite{dayhoff78}, JTT \cite{jones92}, Blosum62 \cite{henikoff92}, mtREV \cite{adachi96}, rtREV \cite{dimmic02}, cpREV \cite{adachi00}, DCMut \cite{kosiol04}, VT \cite{muller00} and mtMAM \cite{cao98} and custom for amino acids. Cycle through the list of nucleotide or amino-acids substitution models by typing \x{M}. Both nucleotide and amino-acid lists include a `custom' model. The custom option provides the most flexible way to specify the nucleotide substitution model. The model is defined by a string made of six digits. The default string is `\x{000000}', which means that the six relative rates of nucleotide changes: $A \leftrightarrow C$, $A \leftrightarrow G$, $A \leftrightarrow T$, $C \leftrightarrow G$, $C \leftrightarrow T$ and $G \leftrightarrow T$, are equal. The string `\x{010010}' indicates that the rates $A \leftrightarrow G$ and $C \leftrightarrow T$ are equal and distinct from $A \leftrightarrow C = A \leftrightarrow T = C \leftrightarrow G = G \leftrightarrow T$. This model corresponds to HKY85 (default) or K80 if the nucleotide frequencies are all set to 0.25. `\x{010020}' and `\x{012345}' correspond to TN93 and GTR models respectively. The digit string therefore defines groups of relative substitution rates. The initial rate within each group is set to 1.0, which corresponds to F81 (JC69 if the base frequencies are equal). Users also have the opportunity to define their own initial rate values. These rates are then optimised afterwards (option `\x{O}') or fixed to their initial values. The custom option can be used to implement all substitution models that are special cases of GTR. Table \ref{tab:modelcode} on page \pageref{tab:modelcode} gives the correspondence between the `standard' name of the model (see \url{http://mbe.oxfordjournals.org/content/18/6/897/F2.large.jpg}) and the custom model code. The custom model also exists for protein sequences. It is useful when one wants to use an amino-acid substitution model that is not hard-coded in PhyML. The symmetric part of the rate matrix, as well as the equilibrium amino-acid frequencies, are given in a file which name is given as input of the program. The format of this file is described in the section \ref{sec:customaa}. \vspace{0.7cm} \begin{center} \framebox{\x{[F] ................. Optimise equilibrium frequencies}} \end{center} \begin{center} \framebox{\x{[E] ......... Equilibrium frequencies (empirical/user)}} \end{center} \begin{center} \framebox{\x{[F] . Amino acid frequencies (empirical/model defined)}} \end{center} For nucleotide sequences, optimising equilibrium frequencies means that the values of these parameters are estimated in the maximum likelihood framework. When the custom model option is selected, it is also possible to give the program a user-defined nucleotide frequency distribution at equilibrium (option \x{E}). For protein sequences, the stationary amino-acid frequencies are either those defined by the substitution model or those estimated by counting the number of different amino-acids observed in the data. Hence, the meaning of the \x{F} option depends on the type of the data to be processed. \vspace{0.7cm} \begin{center} \framebox{\x{[T] .................... Ts/tv ratio (fixed/estimated)}} \end{center}\index{$\kappa$}\index{ts/tv ratio} Fix or estimate the transition/transversion ratio in the maximum likelihood framework. This option is only available when DNA sequences are to be analysed under K80, HKY85 or TN93 models. The definition given to this parameter by PhyML is the same as PAML's\index{PAML} one. Therefore, the value of this parameter does {\it not} correspond to the ratio between the expected number of transitions and the expected number of transversions during a unit of time. This last definition is the one used in PHYLIP\index{PHYLIP}. PAML's manual gives more detail about the distinction between the two definitions (\url{http://abacus.gene.ucl.ac.uk/software/paml.html}). \vspace{0.7cm} \begin{center} \framebox{\x{[V] . Proportion of invariable sites (fixed/estimated)}} \end{center}\index{invariable sites}\index{proportion of invariants} The proportion of invariable sites, i.e., the expected frequency of sites that do not evolve, can be fixed or estimated. The default is to fix this proportion to 0.0. By doing so, we consider that each site in the sequence may accumulate substitutions at some point during its evolution, even if no differences across sequences are actually observed at that site. Users can also fix this parameter to any value in the $[0.0,1.0]$ range or estimate it from the data in the maximum-likelihood framework. \vspace{0.7cm} \index{gamma distribution (discrete)!mean vs. median} \index{gamma distribution (discrete)!number of categories} \index{gamma distribution (discrete)!shape parameter} \begin{center} \framebox{\x{[R] ....... One category of substitution rate (yes/no)}} \end{center} \begin{center} \framebox{\x{[C] ........... Number of substitution rate categories}} \end{center} \begin{center} \framebox{\x{[A] ... Gamma distribution parameter (fixed/estimated)}} \end{center} \begin{center} \framebox{\x{[G] .........`Middle' of each rate class (mean/median)}} \end{center} Rates of evolution often vary from site to site. This heterogeneity can be modelled using a discrete gamma distribution. Type \x{R} to switch this option on or off. The different categories of this discrete distribution correspond to different (relative) rates of evolution. The number of categories of this distribution is set to 4 by default. It is probably not wise to go below this number. Larger values are generally preferred. However, the computational burden involved is proportional to the number of categories (i.e., an analysis with 8 categories will generally take twice the time of the same analysis with only 4 categories). Note that the likelihood will not necessarily increase as the number of categories increases. Hence, the number of categories should be kept below a ``reasonable'' number, say 20. The default number of categories can be changed by typing \x{C}. The middle of each discretized substitution rate class can be determined using the mean or the median. PAML, MrBayes and RAxML use the mean. However, the median is generally associated with greater likelihoods than the mean. This conclusion is based on our analysis of several real-world data sets extracted from TreeBase. Despite this, the default option in PhyML is to use the mean in order to make PhyML likelihoods comparable to those of other phylogenetic software. One must bare in mind that {\color{red}{likelihoods calculated with the mean approximation are not directly comparable to the likelihoods calculated using the median approximation}}. The shape of the gamma distribution determines the range of rate variation across sites. Small values, typically in the $[0.1,1.0]$ range, correspond to large variability. Larger values correspond to moderate to low heterogeneity. The gamma shape parameter can be fixed by the user or estimated via maximum-likelihood. Type \x{A} to select one or the other option. \subsubsection{Tree searching sub-menu} \begin{center} \framebox{\x{[O] ........................... Optimise tree topology}} \end{center} By default the tree topology is optimised in order to maximise the likelihood. However, it is also possible to avoid any topological alteration. This option is useful when one wants to compute the likelihood of a tree given as input (see below). Type \x{O} to select among these two options. \vspace{0.7cm} \begin{center} \framebox{\x{[S] .................. Tree topology search operations}} \end{center} PhyML proposes three different methods to estimate tree topologies. The default approach is to use simultaneous NNI. This option corresponds to the original PhyML algorithm \cite{guindon03}. The second approach relies on subtree pruning and regrafting (SPR). It generally finds better tree topologies compared to NNI but is also significantly slower. The third approach, termed BEST, simply estimates the phylogeny using both methods and returns the best solution among the two. Type \x{S} to choose among these three choices. \vspace{0.7cm} \begin{center} \framebox{\x{[R] ......................... Use random starting tree}} \end{center} \begin{center} \framebox{\x{[N] .................. Number of random starting trees}} \end{center} When the SPR or the BEST options are selected, is is possible to use random trees rather than BioNJ or a user-defined tree, as starting tree. If this option is turned on (type \x{R} to change), five trees, corresponding to five random starts, will be estimated. The output tree file will contain the best tree found among those five. The number of random starts can be modified by typing \x{N}. Setting the number of random starting trees to $N$ means that the analysis will take (slightly more than) $N$ times the time required for a standard analysis where only one (BioNJ) starting tree is used. However, the analysis of real data sets shows that the best trees estimated using the random start option almost systematically have higher likelihoods than those inferred using a single starting tree. \vspace{0.7cm} \begin{center} \framebox{\x{[U] ........ Starting tree (BioNJ/parsimony/user tree)}} \end{center}\index{BioNJ} When the tree topology optimisation option is turned on, PhyML proceeds by refining an input tree. By default, this input tree is estimated using BioNJ \cite{gascuelNJ}. The alternative option is to use a parsimony tree. We found this option specially useful when analysing large data sets with NNI moves as it generally leads to greater likelihoods than those obtained when starting from a BioNJ trees. The user can also to input her/his own tree. This tree should be in Newick format (see Section \ref{sec:input_output}). This option is useful when one wants to evaluate the likelihood of a given tree with a fixed topology, using PhyML. Type \x{U} to choose among these two options. \subsubsection{Branch support sub-menu} \begin{center} \framebox{\x{[B] ................ Non parametric bootstrap analysis}} \end{center} The support of the data for each internal branch of the phylogeny can be estimated using non-parametric bootstrap. By default, this option is switched off. Typing \x{B} switches on the bootstrap analysis. The user is then prompted for a number of bootstrap replicates. The largest this number the more precise the bootstrap support estimates are. However, for each bootstrap replicate a phylogeny is estimated. Hence, the time needed to analyse $N$ bootstrap replicates corresponds to $N$-times the time spent on the analysis of the original data set. $N=100$ is generally considered as a reasonable number of replicates. \begin{center} \framebox{\x{[A] ................ Approximate likelihood ratio test}} \end{center} When the bootstrap option is switched off (see above), approximate likelihood branch supports are estimated. This approach is considerably faster than the bootstrap one. However, both methods intend to estimate different quantities and conducting a fair comparison between both criteria is not straightforward. The estimation of approximate likelihood branch support comes in multiple flavours. The default is set to aBayes, corresponding to the approximate Bayes method described in \cite{anisimova11}. The approximate likelihood ratio test (aLRT) \cite{anisimova06}, Shimodaira–Hasegawa aLRT (SH-aLRT) statistics are the other available options. \subsection{Command-line interface} An alternative to the PHYLIP-like interface is the command-line interface. Users that do not need to modify the default parameters can launch the program with the `\x{phyml -i seq\_file\_name}' command. The list of all command line arguments and how to use them is given in the `Help' section which is displayed when entering the `\x{phyml --help}' command. The available command-line options are described in what follows. \begin{itemize} \item \x{-i} (or \x{--input}) \x{seq\_file\_name}\index{command-line options!\x{--input}} \\ \x{seq\_file\_name} is the name of the nucleotide or amino-acid sequence file in PHYLIP format. \item \x{-d} (or \x{--datatype}) \x{data\_type}\index{command-line options!\x{--data\_type}}\\ \x{data\_type} is \x{nt} for nucleotide (default) and \x{aa} for amino-acid sequences. \item \x{-q} (or \x{--sequential})\index{sequence format!interleaved}\index{sequence format!sequential}\index{command-line options!\x{--sequential}} \\ Changes interleaved format (default) to sequential format. \item \x{-n} (or \x{--multiple}) \x{nb\_data\_sets}\index{multiple data sets}\index{command-line options!\x{--multiple}}\\ \x{nb\_data\_sets} is an integer giving the number of data sets to analyse. \item \x{-p} (or \x{--pars})\index{command-line options!\x{--pars}}\\ Use a minimum parsimony starting tree. This option is taken into account when the `-u' option is absent and when tree topology modifications are to be done. \item \x{-b} (or \x{--bootstrap}) \x{int}\index{bootstrap}\index{command-line options!\x{--bootstrap}} \begin{itemize} \item \x{int} $>$ 0: \x{int} is the number of bootstrap replicates. \item \x{int} = 0: neither approximate likelihood ratio test nor bootstrap values are computed. \item \x{int} = -1: approximate likelihood ratio test returning aLRT statistics. \item \x{int} = -2: approximate likelihood ratio test returning Chi2-based parametric branch supports. % \item \x{int} = -3: minimum of Chi2-based parametric and SH-like branch supports. \item \x{int} = -4: SH-like branch supports alone. \item \x{int} = -5: (default) approximate Bayes branch supports. \end{itemize} \item \x{-m} (or \x{--model}) \x{model\_name}\index{substitution models!DNA}\index{substitution models!amino acids}\index{command-line options!\x{--model}} \\ \x{model\_name} : substitution model name. \begin{itemize} \item {\it Nucleotide-based models}: \x{HKY85} (default) \x{| JC69 | K80 | F81 | F84 | TN93 | GTR | custom} \\ The \x{custom} option can be used to define a new substitution model. A string of six digits identifies the model. For instance, 000000 corresponds to F81 (or JC69 provided the distribution of nucleotide frequencies is uniform). 012345 corresponds to GTR. This option can be used for encoding any model that is a nested within GTR. See Section \ref{sec:submenus} and Table \ref{tab:modelcode}. {\em NOTE:} the substitution parameters of the custom model will be optimised so as to maximise the likelihood. It is possible to specify and fix (i.e., avoid optimisation) the values of the substitution rates only through the PHYLIP-like interface. \item {\it Amino-acid based models}: \x{LG} (default) \x{| WAG | JTT | MtREV | Dayhoff | DCMut | RtREV | CpREV | VT | Blosum62 | MtMam | MtArt | HIVw | HIVb | custom} \\ The \x{custom} option is useful when one wants to use an amino-acid substitution model that is not available by default in PhyML. The symmetric part of the rate matrix, as well as the equilibrium amino-acid frequencies, are given in a file which name is asked for by the program. The format of this file is described in section \ref{sec:customaa}. \end{itemize} \begin{table}\index{custom models} \begin{center} \begin{tabular}{ll} \hline Name & Command-line option \\ \hline JC69 & \x{-m 000000 -f 0.25,0.25,0.25,0.25} \\ F81 & \x{-m 000000}\\ K80 & \x{-m 010010 -f 0.25,0.25,0.25,0.25} \\ HKY85 & \x{-m 010010}\\ TrNef & \x{-m 010020 -f 0.25,0.25,0.25,0.25} \\ TrN & \x{-m 010020}\\ K81 & \x{-m 123321 -f 0.25,0.25,0.25,0.25}\\ K81uf & \x{-m 123321}\\ TIMef & \x{-m 132241 -f 0.25,0.25,0.25,0.25}\\ TIM & \x{-m 132241}\\ TVMef & \x{-m 102304 -f 0.25,0.25,0.25,0.25}\\ TVM & \x{-m 102304}\\ SYM & \x{-m 123456 -f 0.25,0.25,0.25,0.25}\\ GTR & \x{-m 123456}\\ \hline \end{tabular} \caption{Nucleotide substitution model names (as defined in \cite{posada01}) and the corresponding custom model code used in PhyML.}\label{tab:modelcode} \end{center} \end{table} \item \x{--aa\_rate\_file file\_name}\index{command-line options!\x{--aa\_rate\_file}} \\ This option is compulsory when analysing amino-acid sequences under a `custom' model (see above). \x{file\_name} should provide a rate matrix and equilibrium amino acid in PAML format (see Section \ref{sec:customaa}). \item \x{-f e}, \x{m}, or ``\x{fA,fC,fG,fT}" \index{frequencies!nucleotide}\index{frequencies!amino-acid}\index{stationary frequencies}\index{command-line options!\x{-f}}\\ Nucleotide or amino-acid frequencies. \begin{itemize} \item \x{e} : the character frequencies are determined as follows : \begin{itemize} \item {\it Nucleotide sequences}: (Empirical) the equilibrium base frequencies are estimated by counting the occurence of the different bases in the alignment. \item {\it Amino-acid sequences}: (Empirical) the equilibrium amino-acid frequencies are estimated by counting the occurence of the different amino-acids in the alignment. \end{itemize} \item \x{m} : the character frequencies are determined as follows : \begin{itemize} \item {\it Nucleotide sequences}: (ML) the equilibrium base frequencies are estimated using maximum likelihood. \item {\it Amino-acid sequences}: (Model) the equilibrium amino-acid frequencies are estimated using the frequencies defined by the substitution model. \end{itemize} \item ``\x{fA,fC,fG,fT}": only valid for nucleotide-based models. \x{fA}, \x{fC}, \x{fG} and \x{fT} are floating numbers that correspond to the frequencies of A, C, G and T respectively. \end{itemize} \item \x{-t} (or \x{--ts/tv}) \x{ts/tv\_ratio} \index{$\kappa$}\index{ts/tv ratio}\index{command-line options!\x{--ts/tv}}\\ \x{ts/tv\_ratio}: transition/transversion ratio. DNA sequences only. Can be a fixed positive value (e.g., 4.0) or type \x{e} to get the maximum likelihood estimate. \item \x{-v} (or \x{--pinv}) \x{prop\_invar}\index{proportion of invariants}\index{invariable sites} \index{command-line options!\x{--pinv}}\\ \x{prop\_invar}: proportion of invariable sites. Can be a fixed value in the [0,1] range or type \x{e} to get the maximum likelihood estimate. \item \x{-c} (or \x{--nclasses}) \x{nb\_subst\_cat}\index{gamma distribution (discrete)!number of categories} \index{command-line options!\x{--nclasses}}\\ \x{nb\_subst\_cat}: number of relative substitution rate categories. Default: \x{nb\_subst\_cat=4}. Must be a positive integer. \item \x{--freerates} (or \x{--free\_rates} or \x{--free\_rate} or \x{--freerate}) \index{FreeRate} \index{command-line options!\x{--freerates}}\\ FreeRate model of substitution rate variation across sites. \item \x{-a} (or \x{--alpha}) \x{gamma} \index{gamma distribution (discrete)!shape parameter}\index{command-line options!\x{--alpha}} \\ \x{gamma}: value of the gamma shape parameter. Can be a fixed positive value or e to get the maximum likelihood estimate. The value of this parameter is estimated in the maximum likelihood framework by default. \item \x{--use\_median} \index{gamma distribution (discrete)!mean vs. median} \index{command-line options!\x{--use\_median}}\\ The middle of each substitution rate class in the discrete gamma distribution is taken as the median. The mean is used by default. \item \x{--free\_rates} \index{command-line options!\x{--free\_rates}}\\ As an alternative to the discrete gamma model, it is possible to estimate the (relative) rate in each class of the (mixture) model and the corresponding frequencies directly from the data. This model, called the FreeRate model, has more parameters than the discrete gamma one but usually provides a significantly better fit to the data. See \cite{soubrier12} for more information about this model and an illustration of its use. \item \x{--codpos} \x{1,2 or 3} \index{command-line options!\x{--codpos}}\\ When analysing an alignment of coding sequences, use this option to consider only the first, second or the third coding position for the estimation. \item \x{-s} (or \x{--search}) \x{move}\index{NNI}\index{SPR} \index{command-line options!\x{--search}}\\ Tree topology search operation option. Can be either \x{NNI} (default, fast) or \x{SPR} (usually slower than \x{NNI} but more accurate) or \x{BEST} (best of NNI and SPR search). \item \x{-u} (or \x{--inputtree}) \x{user\_tree\_file}\index{input tree}\index{user tree} \index{command-line options!\x{--inputtree}}\\ \x{user\_tree\_file}: starting tree filename. The tree must be in Newick format. \item \x{-o params}\index{optimisation!topology}\index{optimisation!substitution parameters} \index{command-line options!\x{-o}}\\ This option focuses on specific parameter optimisation. \begin{itemize} \item \x{params=tlr}: tree topology (\x{t}), branch length (\x{l}) and substitution rate parameters (\x{r}) are optimised. \item \x{params=tl}: tree topology and branch lengths are optimised. \item \x{params=lr}: branch lengths and substitution rate parameters are optimised. \item \x{params=l}: branch lengths are optimised. \item \x{params=r}: substitution rate parameters are optimised. \item \x{params=n}: no parameter is optimised. \end{itemize} \item \x{--rand\_start}\index{random tree} \index{command-line options!\x{--rand\_start}}\\ This option sets the initial tree to random. It is only valid if SPR searches are to be performed. \item \x{--n\_rand\_starts num} \index{command-line options!\x{--n\_rand\_starts}}\\ \x{num} is the number of initial random trees to be used. It is only valid if SPR searches are to be performed. \item \x{--r\_seed num}\index{random number} \index{command-line options!\x{--r\_seed}}\\ \x{num} is the seed used to initiate the random number generator. Must be an integer. \item \x{--print\_site\_lnl}\index{likelihood!print site likelihood} \index{command-line options!\x{--print\_site\_lk}}\\ Print the likelihood for each site in file *\_phyml\_lk.txt. For $\Gamma$ or $\Gamma$+I or FreeRate models, this option returns the posterior probability of each relative rate class at each site. Such information can then be used to identify fast- and slow-evolving regions of the alignment. \item \x{--print\_trace}\index{command-line options!\x{--print\_trace}}\\ Print each phylogeny explored during the tree search process in file *\_phyml\_trace.txt. This option can be useful for monitoring the progress of the analysis for very large data sets and have an approximate idea of what the final phylogeny will look like. \item \x{--run\_id ID\_string}\index{run ID} \index{command-line options!\x{--run\_id}}\\ Append the string ID\_string at the end of each PhyML output file. This option may be useful when running simulations involving PhyML. It can also be used to `tag' multiple analysis of the same data set with various program settings. \item \x{--no\_memory\_check} \index{command-line options!\x{--no\_memory\_check}}\\ By default, when processing a large data set, PhyML will pause and ask the user to confirm that she/he wants to continue with the execution of the analysis despite the large amount of memory required. The \x{--no\_memory\_check} skips this question. It is especially useful when running PhyML in batch mode. \item \x{--no\_colalias} \index{command-line options!\x{--no\_colalias}}\\ By default, PhyML preprocesses each alignment by putting together (or aliasing) the columns that are identical. Use this option to skip this step but be aware that the analysis might then take more time to complete. \item \x{--constrained\_lens} \index{command-line options!\x{--constrained\_lens}}\\ When an input tree with branch lengths is provided, this option will find the branch multiplier that maximises the likelihood (i.e., the relative branch lengths remain constant) \item \x{--constraint\_file} \x{file\_name} \index{command-line options!\x{--constraint\_file}}\\ \x{file\_name} lists the topological constraints under which the tree topology search is conducted. This option should be used in conjunction with \x{-u} \x{file\_name}. See Section \ref{sec:topoconstraints} for more information. \item \x{--quiet} \index{command-line options!\x{--quiet}}\\ Runs PhyML in quiet mode. The program will not pause if the memory required to run the analysis exceeds 256MB and will not output the progression of the log-likelihood scores on the standard output. \item \x{--ancestral} \index{command-line options!\x{--ancestral}}\\ PhyML calculates the marginal probabilities of each character state at each internal node and each site of the sequence alignment. \end{itemize} \subsection{XML interface} \begin{itemize} \item \x{--xml=xml\_file\_name}\index{command-line options!\x{--xml}} \\ \x{xml\_file\_name} is the name of the XML file containing the information required to run the analysis. More details about this type of file is given in the section \ref{sec:xmlio}. \end{itemize} \subsection{Parallel bootstrap}\label{sec:parallel_bootstrap}\index{MPI}\index{bootstrap!parallel} Bootstrapping is a highly parallelizable task. Indeed, bootstrap replicates are independent from one another. Each bootstrap replicate can then be analysed separately. Modern computers often have more than one CPU. Each CPU can therefore be used to process a bootstrap sample. Using this parallel strategy, performing $R$ bootstrap replicates on $C$ CPUs `costs' the same amount of computation time as processing $R \times C$ bootstrap replicates on a single CPU. In other words, for a given number of replicates, the computation time is divided by $R$ compared to the non-parallel approach. PhyML sources must be compiled with specific options to turn on the parallel option (see Section \ref{sec:MPI}). Once the binary file (\x{phyml}) has been generated, running a bootstrap analysis with, say 100 replicates on 2 CPUs, can be done by typing the following command-line: \begin{verbatim} mpd &; mpirun -np 2 ./phyml -i seqfile -b 100; \end{verbatim} The first command launches the mpi daemon while the second launches the analysis. Note that launching the daemon needs to be done only once. The output files are similar to the ones generated using the standard, non-parallel, analysis (see Section \ref{sec:input_output}). Note that running the program in batch mode, i.e.: \begin{verbatim} mpirun -np 2 ./phyml -i seqfile -b 100 & \end{verbatim} will probably NOT work. I do not know how to run a mpi process in batch mode yet. Suggestions welcome... Also, at the moment, the number of bootstrap replicates must be a multiple of the number of CPUs required in the mpirun command. \section{Inputs \& outputs for command-line and PHYLIP interface }\label{sec:input_output} PhyML reads data from standard text files, without the need for any particular file name extension. \subsection{Sequence formats} \begin{figure} \begin{small} \begin{Verbatim}[frame=single, label=PHYLIP interleaved, samepage=true, baselinestretch=0.5] 5 80 seq1 CCATCTCACGGTCGGTACGATACACCKGCTTTTGGCAGGAAATGGTCAATATTACAAGGT seq2 CCATCTCACGGTCAG---GATACACCKGCTTTTGGCGGGAAATGGTCAACATTAAAAGAT seq3 RCATCTCCCGCTCAG---GATACCCCKGCTGTTG????????????????ATTAAAAGGT seq4 RCATCTCATGGTCAA---GATACTCCTGCTTTTGGCGGGAAATGGTCAATCTTAAAAGGT seq5 RCATCTCACGGTCGGTAAGATACACCTGCTTTTGGCGGGAAATGGTCAAT????????GT ATCKGCTTTTGGCAGGAAAT ATCKGCTTTTGGCGGGAAAT AGCKGCTGTTG????????? ATCTGCTTTTGGCGGGAAAT ATCTGCTTTTGGCGGGAAAT \end{Verbatim} \begin{Verbatim}[frame=single, label=PHYLIP sequential, samepage=true, baselinestretch=0.5] 5 40 seq1 CCATCTCANNNNNNNNACGATACACCKGCTTTTGGCAGG seq2 CCATCTCANNNNNNNNGGGATACACCKGCTTTTGGCGGG seq3 RCATCTCCCGCTCAGTGAGATACCCCKGCTGTTGXXXXX seq4 RCATCTCATGGTCAATG-AATACTCCTGCTTTTGXXXXX seq5 RCATCTCACGGTCGGTAAGATACACCTGCTTTTGxxxxx \end{Verbatim} \end{small} \label{fig:align_tree} \caption{\bf PHYLIP interleaved and sequential formats.} \end{figure} \begin{figure} \begin{small} \begin{Verbatim}[frame=single, label=Nexus nucleotides, samepage=true, baselinestretch=0.5] [ This is a comment ] #NEXUS BEGIN DATA; DIMENSIONS NTAX=10 NCHAR=20; FORMAT DATATYPE=DNA; MATRIX tax1 ?ATGATTTCCTTAGTAGCGG tax2 CAGGATTTCCTTAGTAGCGG tax3 ?AGGATTTCCTTAGTAGCGG tax4 ?????????????GTAGCGG tax5 CAGGATTTCCTTAGTAGCGG tax6 CAGGATTTCCTTAGTAGCGG tax7 ???GATTTCCTTAGTAGCGG tax8 ???????????????????? tax9 ???GGATTTCTTCGTAGCGG tax10 ???????????????AGCGG; END; \end{Verbatim} \end{small} \begin{small} \begin{Verbatim}[frame=single, label=Nexus digits, samepage=true, baselinestretch=0.5] [ This is a comment ] #NEXUS BEGIN DATA; DIMENSIONS NTAX=10 NCHAR=20; FORMAT DATATYPE=STANDARD SYMBOLS="0 1 2 3"; MATRIX tax1 ?0320333113302302122 tax2 10220333113302302122 tax3 ?0220333113302302122 tax4 ?????????????2302122 tax5 10220333113302302122 tax6 10220333113302302122 tax7 ???20333113302302122 tax8 ???????????????????? tax9 ???22033313312302122 tax10 ???????????????02122; END; \end{Verbatim} \end{small} \begin{small} \begin{Verbatim}[frame=single, label=Nexus digits, samepage=true, baselinestretch=0.5] [ This is a comment ] #NEXUS BEGIN DATA; DIMENSIONS NTAX=10 NCHAR=20; FORMAT DATATYPE=STANDARD SYMBOLS="00 01 02 03"; MATRIX tax1 ??00030200030303010103030002030002010202 tax2 0100020200030303010103030002030002010202 tax3 ??00020200030303010103030002030002010202 tax4 ??????????????????????????02030002010202 tax5 0100020200030303010103030002030002010202 tax6 0100020200030303010103030002030002010202 tax7 ??????0200030303010103030002030002010202 tax8 ???????????????????????????????????????? tax9 ??????0202000303030103030102030002010202 tax10 ??????????????????????????????0002010202; END; \end{Verbatim} \end{small} \caption{\bf NEXUS formats.}\label{fig:nexus} \end{figure} Alignments of DNA or protein sequences must be in PHYLIP\index{PHYLIP} or NEXUS \cite{maddison97}\index{NEXUS} sequential\index{sequential} or interleaved\index{interleaved} format (Figures \ref{fig:align_tree} and \ref{fig:nexus}). For PHYLIP formated sequence alignments, the first line of the input file contains the number of species and the number of characters, in free format, separated by blank characters. One slight difference with PHYLIP format deals with sequence name lengths. While PHYLIP format limits this length to ten characters, PhyML can read up to hundred character long sequence names. Blanks and the symbols ``(),:'' are not allowed within sequence names because the Newick tree format makes special use of these symbols. Another slight difference with PHYLIP format is that actual sequences must be separated from their names by at least one blank character. A PHYLIP input sequence file may also display more than a single data set. Each of these data sets must be in PHYLIP format and two successive alignments must be separated by an empty line. Processing multiple data sets requires to toggle the `\x{M}' option in the {\em Input Data} sub-menu or use the `\x{-n}' command line option and enter the number of data sets to analyse. The multiple data set option can be used to process re-sampled data that were generated using a non-parametric procedure such as cross-validation or jackknife (a bootstrap option is already included in PhyML). This option is also useful in multiple gene studies, even if fitting the same substitution model to all data sets may not be suitable. PhyML can also process alignments in NEXUS format. Although not all the options provided by this format are supported by PhyML, a few specific features are exploited. Of course, this format can handle nucleotide and protein sequence alignments in sequential or interleaved format. It is also possible to use custom alphabets, replacing the standard 4-state and 20-state alphabets for nucleotides and amino-acids respectively. Examples of a 4-state custom alphabet are given in Figure \ref{fig:nexus}. Each state must here correspond to one digit or more. The set of states must be a list of consecutive digits starting from 0. For instance, the list ``0, 1, 3, 4'' is not a valid alphabet. Each state in the symbol list must be separated from the next one by a space. Hence, alphabets with large number of states can be easily defined by using two-digit number (starting with 00 up to 19 for a 20 state alphabet). Most importantly, this feature gives the opportunity to analyse data sets made of presence/absence character states (use the \texttt{symbols=``0 1''} option for such data).\index{binary characters} Alignments made of custom-defined states will be processed using the Jukes and Cantor model. Other options of the program (e.g., number of rate classes, tree topology search algorithm) are freely configurable. Note that, at the moment, the maximum number of different states is set to 22 in order to save memory space. It is however possible to lift this threshold by modifiying the value of the variable \x{T\_MAX\_ALPHABET} in the file `\x{utilities.h}'. The program will then have to be re-compiled. \subsubsection{Gaps and ambiguous characters} Gaps correspond to the `\x{-}' symbol. They are systematically treated as unknown characters ``on the grounds that we don't know what would be there if something were there'' (J. Felsenstein, PHYLIP main documentation). The likelihood at these sites is summed over all the possible states (i.e., nucleotides or amino acids) that could actually be observed at these particular positions. Note however that columns of the alignment that display only gaps or unknown characters are simply discarded because they do not carry any phylogenetic information (they are equally well explained by any model). PhyML also handles ambiguous characters such as $R$ for $A$ or $G$ (purines) and $Y$ for $C$ or $T$ (pyrimidines). Tables \ref{tab:ambigu_nt} and \ref{tab:ambigu_aa} give the list of valid characters/symbols and the corresponding nucleotides or amino acids. \begin{table} \begin{center} \begin{tabular}{lr|lr} \hline Character & Nucleotide & Character & Nucleotide \\ \hline $A$ & Adenosine & $Y$ & $C$ or $T$ \\ $G$ & Guanosine & $K$ & $G$ or $T$ \\ $C$ & Cytidine & $B$ & $C$ or $G$ or $T$\\ $T$ & Thymidine & $D$ & $A$ or $G$ or $T$ \\ $U$ & Uridine (=$T$) & $H$ & $A$ or $C$ or $T$ \\ $M$ & $A$ or $C$ & $V$ & $A$ or $C$ or $G$ \\ $R$ & $A$ or $G$ & $-$ or $N$ or $X$ or $?$ & unknown \\ $W$ & $A$ or $T$ & & (=$A$ or $C$ or $G$ or $T$)\\ $S$ & $C$ or $G$ & & \\ \hline \end{tabular} \end{center} \caption{{\bf List of valid characters in DNA sequences and the corresponding nucleotides.}}\label{tab:ambigu_nt} \end{table} \begin{table} \begin{center} \begin{tabular}{lr|lr} \hline Character & Amino-Acid & Character & Amino-Acid \\ \hline $A$ & Alanine & $L$ & Leucine \\ $R$ & Arginine & $K$ & Lysine \\ $N$ or $B$& Asparagine & $M$ & Methionine \\ $D$ & Aspartic acid & $F$ & Phenylalanine \\ $C$ & Cysteine & $P$ & Proline \\ $Q$ or $Z$& Glutamine & $S$ & Serine \\ $E$ & Glutamic acid & $T$ & Threonine \\ $G$ & Glycine & $W$ & Tryptophan \\ $H$ & Histidine & $Y$ & Tyrosine \\ $I$ & Isoleucine & $V$ & Valine \\ $L$ & Leucine & $-$ or $X$ or $?$ & unknown \\ $K$ & Lysine & & (can be any amino acid) \\ \hline \end{tabular} \end{center} \caption{{\bf List of valid characters in protein sequences and the corresponding amino acids.}}\label{tab:ambigu_aa} \end{table} \subsubsection{Specifying outgroup sequences}\label{sec:outgroupspecify} PhyML can return rooted trees provided outgroup taxa are identified from the sequence file. In order to do so, sequence names that display a `*' character will be automatically considered as belonging to the outgroup. The topology of the rooted tree is exactly the same as the unrooted version of the same tree. In other words, PhyML first ignores the distinction between ingroup and outgroup sequences, builds a maximum likelihood unrooted tree and then tries to add the root. If the outgroup has more than one sequence, the position of the root might be ambiguous. In such situation, PhyML tries to identify the most relevant position of the root by considering which edge provides the best separation between ingroup and outgroup taxa (i.e., we are trying to make the outgroup ``as monophyletic as possible''). \subsection{Tree format} PhyML can read one or several phylogenetic trees from an input file. This option is accessible through the {\em Tree Searching} sub menu or the `\x{-u}' argument from the command line. Input trees are generally used as initial maximum likelihood estimates to be subsequently adjusted by the tree searching algorithm. Trees can be either rooted or unrooted and multifurcations are allowed. Taxa names must, of course, match the corresponding sequence names. \begin{figure}[h] \begin{small} \begin{minipage}{\textwidth} \begin{verbatim} ((seq1:0.03,seq2:0.01):0.04,(seq3:0.01,(seq4:0.2,seq5:0.05):0.2):0.01); ((seq3,seq2),seq1,(seq4,seq5)); \end{verbatim} \end{minipage} \end{small} \caption{{\bf Input trees}. The first tree (top) is rooted and has branch lengths. The second tree (bottom) is unrooted and does not have branch lengths.} \label{fig:trees}\index{Newick format} \end{figure} \subsection{Multiple alignments and trees}\index{multiple data sets} Single or multiple sequence data sets may be used in combination with single or multiple input trees. When the number of data sets is one ($n_D = 1$) and there is only one input tree ($n_T = 1$), then this tree is simply used as input for the single data set analysis. When $n_D = 1$ and $n_T > 1$, each input tree is used successively for the analysis of the single alignment. PhyML then outputs the tree with the highest likelihood. If $n_D > 1$ and $n_T = 1$, the same input tree is used for the analysis of each data set. The last combination is $n_D > 1$ and $n_T > 1$. In this situation, the $i$-th tree in the input tree file is used to analyse the $i$-th data set. Hence, $n_D$ and $n_T$ must be equal here. \subsection{Custom amino-acid rate model}\label{sec:customaa} The custom amino-acid model of substitutions can be used to implement a model that is not hard-coded in PhyML. This model must be time-reversible. Hence, the matrix of substitution rates is symmetrical. The format of the rate matrix with the associated stationary frequencies is identical to the one used in PAML\index{PAML}. An example is given below: \begin{center} {\tiny \begin{tabular}{p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}p{0.33cm}} % Ala & Arg & Asn & Asp & Cys & Gln & Glu & Gly & His & Ile & Leu & Lys & Met & Phe & Pro & Ser & Thr & Trp & Tyr & Val \\ &&&&&&&&&&&&&&&&&&& \\ 0.55 & &&&&&&&&&&&&&&&&&& \\ 0.51 & 0.64 & &&&&&&&&&&&&&&&& \\ 0.74 & 0.15 & 5.43 & &&&&&&&&&&&&&&&& \\ 1.03 & 0.53 & 0.27 & 0.03 & &&&&&&&&&&&&&&& \\ 0.91 & 3.04 & 1.54 & 0.62 & 0.10 & &&&&&&&&&&&&&& \\ 1.58 & 0.44 & 0.95 & 6.17 & 0.02 & 5.47 & &&&&&&&&&&&&& \\ 1.42 & 0.58 & 1.13 & 0.87 & 0.31 & 0.33 & 0.57 & &&&&&&&&&&&& \\ 0.32 & 2.14 & 3.96 & 0.93 & 0.25 & 4.29 & 0.57 & 0.25 & &&&&&&&&&&& \\ 0.19 & 0.19 & 0.55 & 0.04 & 0.17 & 0.11 & 0.13 & 0.03 & 0.14 & &&&&&&&&&& \\ 0.40 & 0.50 & 0.13 & 0.08 & 0.38 & 0.87 & 0.15 & 0.06 & 0.50 & 3.17 & &&&&&&&&& \\ 0.91 & 5.35 & 3.01 & 0.48 & 0.07 & 3.89 & 2.58 & 0.37 & 0.89 & 0.32 & 0.26 & &&&&&&&& \\ 0.89 & 0.68 & 0.20 & 0.10 & 0.39 & 1.55 & 0.32 & 0.17 & 0.40 & 4.26 & 4.85 & 0.93 & &&&&&&& \\ 0.21 & 0.10 & 0.10 & 0.05 & 0.40 & 0.10 & 0.08 & 0.05 & 0.68 & 1.06 & 2.12 & 0.09 & 1.19 & &&&&&& \\ 1.44 & 0.68 & 0.20 & 0.42 & 0.11 & 0.93 & 0.68 & 0.24 & 0.70 & 0.10 & 0.42 & 0.56 & 0.17 & 0.16 & &&&&& \\ 3.37 & 1.22 & 3.97 & 1.07 & 1.41 & 1.03 & 0.70 & 1.34 & 0.74 & 0.32 & 0.34 & 0.97 & 0.49 & 0.55 & 1.61 & &&&& \\ 2.12 & 0.55 & 2.03 & 0.37 & 0.51 & 0.86 & 0.82 & 0.23 & 0.47 & 1.46 & 0.33 & 1.39 & 1.52 & 0.17 & 0.80 & 4.38 & &&& \\ 0.11 & 1.16 & 0.07 & 0.13 & 0.72 & 0.22 & 0.16 & 0.34 & 0.26 & 0.21 & 0.67 & 0.14 & 0.52 & 1.53 & 0.14 & 0.52 & 0.11 & && \\ 0.24 & 0.38 & 1.09 & 0.33 & 0.54 & 0.23 & 0.20 & 0.10 & 3.87 & 0.42 & 0.40 & 0.13 & 0.43 & 6.45 & 0.22 & 0.79 & 0.29 & 2.49 & & \\ 2.01 & 0.25 & 0.20 & 0.15 & 1.00 & 0.30 & 0.59 & 0.19 & 0.12 & 7.82 & 1.80 & 0.31 & 2.06 & 0.65 & 0.31 & 0.23 & 1.39 & 0.37 & 0.31 & \\ \\ 8.66 & 4.40 & 3.91 & 5.70 & 1.93 & 3.67 & 5.81 & 8.33 & 2.44 & 4.85 & 8.62 & 6.20 & 1.95 & 3.84 & 4.58 & 6.95 & 6.10 & 1.44 & 3.53 & 7.09 \\ \end{tabular} } \end{center} The entry on the $i$-th row and $j$-th column of this matrix corresponds to the rate of substitutions between amino-acids $i$ and $j$. The last line in the file gives the stationary frequencies and must be separated from the rate matrix by one line. The ordering of the amino-acids is alphabetical, i.e, Ala, Arg, Asn, Asp, Cys, Gln, Glu, Gly, His, Ile, Leu, Lys, Met, Phe, Pro, Ser, Thr, Trp, Tyr and Val. \subsection{Topological constraint file}\label{sec:topoconstraints} PhyML can perform phylogenetic tree estimation under user-specified topological constraints. In order to do so, one should use the \x{--constraint\_file} \x{file\_name} command-line option where \x{file\_name} lists the topological constraints. Such constraints are straightforward to define. For instance, the following constraints: \vspace{0.2cm} \begin{Verbatim} ((A,B),C,(D,E,F)); \end{Verbatim} indicate that taxa D, E and F belong to the same clade. A, B and C also belong to the same clade and the two clades hence defined should not overlap. Under these two constraints, the tree ((A,B),D,((E,F),C)) is not valid. From the example above, you will notice that the constraints are defined using a multifurcating tree in NEWICK format. Note that this tree does not need to display the whole list of taxa. For instance, while the only taxa involved in specifying topological constraints above are A, B, C, D, E \& F, the actual data set could include more than these six taxa only. PhyML tree topology search algorithms all rely on improving a starting tree. By default, BioNJ is the method of choice for building this tree. However, there is no guarantee that the phylogeny estimated with PhyML does comply with the topological constraints. While it is probably possible to implement BioNJ with topological constraints, we have not done so yet. Instead, the same multifurcating tree that defines the topological constraints should also be used as starting tree using the \x{-u} (\x{--inputtree}) option. Altogether, the command line should look like the following: \x{-u}=\x{file\_name} \x{--constraint\_file}=\x{file\_name}. It is not possible to use as input tree a non-binary phylogeny that is distinct from that provided in the constraint tree file. However, any binary tree compatible with the constraint one can be used as input tree. \subsection{Output files} \begin{table} Sequence file name~: `{\x seq}'\\ \begin{center} \begin{tabular}{ll} \hline Output file name & Content \\ \hline \x{seq\_phyml\_tree} & ML tree\\ \x{seq\_phyml\_stats} & ML model parameters\\ \x{seq\_phyml\_boot\_trees} & ML trees -- bootstrap replicates\\ \x{seq\_phyml\_boot\_stats} & ML model parameters -- bootstrap replicates \\ \x{seq\_phyml\_rand\_trees} & ML trees -- multiple random starts\\ \x{seq\_phyml\_ancestral\_seq} & ML trees -- ancestral sequences\\ \hline \end{tabular} \end{center} \caption{{\bf Standard output files}}\label{tab:output} \end{table} Table \ref{tab:output} presents the list of files resulting from an analysis. Basically, each output file name can be divided into three parts. The first part is the sequence file name, the second part corresponds to the extension `\x{\_phyml\_}' and the third part is related to the file content. When launched with the default options, PhyML only generates two files: the tree file and the model parameter file. The estimated maximum likelihood tree is in standard Newick format (see Figure \ref{fig:trees}). The model parameters file, or statistics file, displays the maximum likelihood estimates of the substitution model parameters, the likelihood of the maximum likelihood phylogenetic model, and other important information concerning the settings of the analysis (e.g., type of data, name of the substitution model, starting tree, etc.). Two additional output files are created if bootstrap supports were evaluated. These files simply contain the maximum likelihood trees and the substitution model parameters estimated from each bootstrap replicate. Such information can be used to estimate sampling errors around each parameter of the phylogenetic model. When the random tree option is turned on, the maximum likelihood trees estimated from each random starting trees are printed in a separate tree file (see last row of Table \ref{tab:output}). PhyML estimates ancestral sequences by calculating the marginal probability of each character state at each internal node of the phylogeny. These probabilities are given in the file \x{seq\_phyml\_ancestral\_seq}. The bulk of this file is a table where each row corresponds to a site in the original alignment and an the number corresponding to an internal node. It is relatively straightforward to identify which number corresponds to which node in the tree by examining the information provided at the beginning of \x{seq\_phyml\_ancestral\_seq}. This section of the file displays the tree structure in terms of a list of node numbers rather than in the NEWICK format. For instance, the tree \x{(A,B,(C,D));} corresponds to the following list of nodes: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=List of nodes corresponding to \x{(A,B,(C,D));}, samepage=true, baselinestretch=0.5, fontsize=\small] Node nums: 0 4 (dir: 0) names = 'A' '(null)'; Node nums: 4 2 (dir: 1) names = '(null)' 'B'; Node nums: 4 5 (dir: 2) names = '(null)' '(null)'; Node nums: 5 1 (dir: 0) names = '(null)' 'C'; Node nums: 5 3 (dir: 1) names = '(null)' 'D'; \end{Verbatim} The two integers following \x{Node nums} are the node numbers. They are displayed in a recursive manner. The number on the left column is that of the ancestral node while the one on the right column is the direct descendant. The following columns are the node names. These names are set to \x{null} except for the tip nodes, where the corresponding taxon names are displayed. \subsection{Treatment of invariable sites with fixed branch lengths} PhyML allows users to give an input tree with fixed topology and branch lengths and find the proportion of invariable sites that maximise the likelihood (option \x{-o r}). These two options can be considered as conflicting since branch lengths depend on the proportion of invariants. Hence, changing the proportion of invariants implies that branch lengths are changing too. More formally, let $l$ denote the length of a branch, i.e., the expected number of substitutions per site, and $p$ be the proportion of invariants. We have $l = (1-p)l'$, where $l'$ is the expected number of substitutions per \_variable\_ sites. When asked to optimize $p$ but leave $l$ unchanged, PhyML does the following: \begin{enumerate} \item Calculate $l' = l/(1-p)$ and leave $l'$ unchanged throughout the optimization. \item Find the value of $p$ that maximises the likelihood. Let $p^{*}$ denote this value. \item Set $l^{*} = (1-p^{*})l'$ and print out the tree with $l^{*}$ (instead of $l$). \end{enumerate} PhyML therefore assumes that the users wants to fix the branch lengths measured at \_variable\_ sites only (i.e., $l^{*}$ is fixed). This is the reason why the branch lengths in the input and output trees do differ despite the use of the the \x{-o r} option. While we believe that this approach relies on a sound rationale, it is not perfect. In particular, the original transformation of branch lengths ($l' = l/(1-p)$) relies on a default value for $p$ with is set to 0.2 in practice. It is difficult to justify the use of this value rather than another one. One suggestion proposed by Bart Hazes is to avoid fixing the branch lengths altogether and rather estimate the value of a scaling factor applied to each branch length in the input tree (option \x{--contrained\_lens}). We agree that this solution probably matches very well most users expectation, i.e., ``find the best value of $p$ while constraining the ratio of branch lengths to be that given in the input tree''. Please feel free to send us your suggestions regarding this problem by posting on the forum (\url{http://groups.google.com/group/phyml-forum}). \section{Inputs \& outputs for the XML interface }\label{sec:xmlio}\index{XML} \subsection{Mixture models in PhyML}\index{mixture models}\label{sec:mixtures} PhyML implements a wide range of mixture models. The discrete gamma model \cite{yang94b} is arguably the most popular of these models in phylogenetics. However, in theory, mixture models are not restricted to the description of the variation of substitution rates across sites. For instance, if there are good reasons to believe that the relative rates of substitution between nucleotides vary along the sequence alignments, it makes sense to use a mixture of GTR models. Consider the case where substitutions between $A$ and $C$ occur at high rate in some regions of the alignment and low rate elsewhere, a mixture with two classes, each class having its own GTR rate matrix, would be suitable. The likelihood at any site of the alignment is then obtained by averaging the likelihoods obtained for each GTR rate matrix, with the same weight given to each of these matrices. PhyML implements a generic framework that allows users to define mixtures on substitution rates, rate matrices and nucleotide or amino-acid equilibrium frequencies. Each class of the mixture model is built by assembling a substitution rate, a rate matrix\footnote{the rate matrix corresponds here the symmetrical matrix giving the so-called ``echangeability rates''} and a vector of equilibrium frequencies. For instance, let $\{R_1,R_2,R_3\}$ be a set of substitution rates, $\{M_1,M_2\}$ a set of rate matrices and $\{F_1,F_2\}$ a set of vectors of equilibrium frequencies. One could then define the first class of the mixture model as $\mathcal{C}_1 = \{R_1,M_1,F_1\}$, a second class as $\mathcal{C}_2 = \{R_2,M_1,F_1\}$, and a third class as $\mathcal{C}_3 = \{R_3,M_2,F_2\}$. If $R_1$, $R_2$ and $R_3$ correspond to slow, medium and fast substitution rates, then this mixture model allows the fast evolving rates to have their own vector of equilibrium frequencies and rate matrix, distinct from that found at the medium or slow evolving sites. The likelihood at any given site $D_s$ of the alignment is then: \begin{eqnarray*} \Pr(D_s) = \sum_{c=1}^{3} \Pr(D_s | \mathcal{C}_s=c) \Pr(\mathcal{C}_s=c), \label{equ:mixtlk} \end{eqnarray*} where $\Pr(\mathcal{C}_s=c)$ is obtained by multiplying the probability (density) of the three components (i.e., rate, matrix, frequencies). For instance, $\Pr(\mathcal{C}_1=\{R_1,M_1,F_1\}) = \Pr(R_1)\times \Pr(M_1) \times \Pr(F_1)$. We therefore assume here that substitution rates, rate matrices and equilibrium frequencies are independent from one another. Note that, using the same substitution rates, rate matrices and vector of equilibrium frequencies, it is possible to construct many other mixture models. For instance, the mixture model with the largest number of classes can be created by considering all the combinations of these three components. We would then get a mixture of $3\times 2 \times 2=12$ classes, corresponding to all the possible combinations of 3 rates, 2 matrices and 2 vectors of frequencies. % : $\mathcal{C}_1 = % \{R_1,M_1,F_1\}$ $\mathcal{C}_2 = \{R_1,M_1,F_2\}$, $\mathcal{C}_3 = \{R_1,M_2,F_1\}$, % $\mathcal{C}_4 = \{R_1,M_2,F_2\}$, $\mathcal{C}_5 = \{R_2,M_1,F_1\}$, $\mathcal{C}_6 = % \{R_2,M_1,F_2\}$, $\mathcal{C}_7 = \{R_2,M_2,F_1\}$, $\mathcal{C}_8 = \{R_2,M_2,F_2\}$, % $\mathcal{C}_9 = \{R_3,M_1,F_1\}$, $\mathcal{C}_{10} = \{R_3,M_1,F_2\}$, $\mathcal{C}_{11} = % \{R_3,M_2,F_1\}$ and $\mathcal{C}_{12} = \{R_3,M_2,F_2\}$. \subsection{Partitions}\index{partitionned analysis}\index{data partitions} We first introduce some terms of vocabulary that have not been presented before. A partitionned data set, also referred to as partition, is a set of partition elements. Typically, a partitionned data set will be made of a set of distinct gene alignments. A partition element will then correspond to one (or several) of these gene alignments. Note that the biology litterature often uses the term partition to refer to an element of a partitionned data. We thus use here instead the mathematical definition of the terms `partition' and `partition element'. Phylogenetics models usually assume individual columns of an alignment to evolve independently from one another. Codon-based models (e.g., \cite{yang98,yang00b,yang02,guindon04}) are exceptions to this rule since the substitution process applies here to triplets of consecutive sites of coding sequences. The non-independence of the substitution process at the three coding positions (due to the specificities of the genetic code), can therefore be accounted for. Assuming that sites evolve independently does not mean that a distinct model is fitted to each site of the alignment. Estimating the parameters of these models would not make much sense in practice due to the very limited amount of phylogenetic signal conveyed by individual sites. Site independence means instead that the columns of the observed alignment were sampled randomly from the same ``population of columns''. The stochasticity of the substitution process running along the tree is deemed responsible to the variability of site patterns. Some parameters of the phylogenetic model are considered to be common to all the sites in the alignment. The tree topology is typically one such parameter. The transition/transversion ratio is also generally assumed to be the same for all columns. Other parameters can vary from site to site. The rate at which substitutions accumulate is one of these parameters. Hence, different sites can have distinct rates. However, such rates are all ``drawn'' from the same probabilitic distribution (generally a discrete Gamma density). Hence, while different sites may have distinct rates of evolution, they all share the same {\em distribution} of rates. This reasonning also applies on a larger scale. When analysing multiple genes, one can indeed assume that the same mechanism generated the different site patterns observed for every gene. Here again, we can assume that all the genes share the same underlying tree topology (commonly refered to as the ``species tree''). Other parameters of the phylogenetic model, such as branch lengths for instance, might be shared across genes. However, due to the specificities of the gene evolution processes, some model parameters need to be adjusted for each gene separately. To sum up, the phylogenetic analysis of partitionned data requires flexible models with parameters, or distribution of parameters, shared across several partition elements and other parameters estimated separately for each element of the partition. The likelihood of a data set made of the concatenation of $n$ sequence alignments noted $D^{(1)}$, $D^{(2)}, \ldots, D^{(n)}$ is then obtained as follows: \begin{eqnarray*} \Pr(D^{(1)},D^{(2)},\ldots,D^{(n)}) &=& \prod_{i=1}^{n} \Pr(D^{(i)}) \\ &=& \prod_{i=1}^{n} \prod_{s=1}^{L_i} \Pr(D^{(i)}_s), \end{eqnarray*} where $L_i$ is the number of site columns in partition element $i$. $\Pr(D^{(i)}_s)$ is then obtained using Equation \ref{equ:mixtlk}, i.e., by summing over the different classes of the mixture model that applies to site $s$ for partition element $i$. Hence, the joint probability of all the partition elements is here broken down into the product of likelihood of every site for each partition element. As noted just above, any given component of the mixture model at a given particular site is shared by the other sites that belong to the same partition element and, for some of them, by sites in other partition elements (e.g., the same tree topology is shared by all the sites, throughout all the partition elements). PhyML implements a wide variety of partition models. The only parameter that is constrained to be shared by all the partition elements is the tree topology. This constraint makes sense when considering distantly related taxa, typically inter-species data. For closely related taxa, i.e., when analysing intra-species or population-level data, not all the genes might have the same evolutionary history. Recombination events combined to the incomplete lineage sorting phenomenon can generate discrepancies between the gene trees and the underlying species tree (see \cite{degnan09} for a review). The phylogenetic softwares BEST \cite{best}\index{BEST}, STEM \cite{stem}\index{STEM} and *BEAST \cite{startbeast}\index{*BEAST} are dedicated to the estimation of species tree phylogenies from the analysis of multi-gene data and allow gene-tree topologies to vary across genes. Aside from the tree topology that is common to all the sites and all the partition elements, other parameters of the phylogenetic model can be either shared across partition elements or estimated separately for each of these. When analysing three partition elements, $A$, $B$ and $C$ for instance, PhyML can fit a model where the same set of branch lengths applies to $A$ and $B$ while $C$ has its own estimated lengths. The same goes for the substitution model: the same GTR model, with identical parameter values, can be fitted to $A$ and $C$ and JC69 for instance can be used for $B$. The sections below give more detailed information on the range of models available and how to set up the corresponding XML configuration files to implement them. \subsection{Combining mixture and partitions in PhyML: the theory} The rationale behind mixture models as implemented in PhyML lies in (1) the definition of suitable rate matrices, equilibrium frequency vectors and relative rates of substitution and (2) the assembly of these components so as to create the classes of a mixture. The main idea behind partitionned analysis in PhyML lies in (1) the hypothesis of statistical independance of the different data partition elements and (2) distinct data partition can share model components such as rate matrices, equilibrium frequencies or distribution of rates across sites. More formally, the likelihood of a data set made of $n$ partition elements is written as follows: \begin{eqnarray*} \Pr(D^{(1)},D^{(2)},\ldots,D^{(n)}) &=& \prod_{i=1}^{n} \prod_{s=1}^{L_i} \Pr(D^{(i)}_s) \\ &=& \prod_{i=1}^{n} \prod_{s=1}^{L_i} \sum_{c=1}^{K_i} \Pr(D^{(i)}_s|\mathcal{C}=c) \Pr(\mathcal{C}=c), \end{eqnarray*} where $L_i$ is the number of sites in partition element $i$ and $K_i$ is the number of classes in the mixture model that applies to this same partition element. Each class of a mixture is made of a rate matrix $M$, a vector of equilibrium frequencies $F$ and a relative rate of substitution $R$. Branch lengths, $L$ and tree topology $\tau$ are also required for the calculation of the likelihood. Hence we have: \begin{eqnarray*} && \Pr(D^{(1)},D^{(2)},\ldots,D^{(n)}) \\ &&= \prod_{i=1}^{n} \prod_{s=1}^{L_i} \sum_{c=1}^{K_i} \Pr(D^{(i)}_s|\mathcal{C}=c) \Pr(\mathcal{C}=c) \\ &&= \prod_{i=1}^{n} \prod_{s=1}^{L_i} \sum_{m}^{\mathcal{M}_i} \sum_{f}^{\mathcal{F}_i} \sum_{r}^{\mathcal{R}_i} \Pr(D^{(i)}_s|M_m^{(i)},F_f^{(i)},R_r^{(i)},L^{(i)},\tau) \Pr(M_m^{(i)},F_f^{(i)},R_r^{(i)}) \mathcal{I}(m,f,r,i) % &&= \prod_{i=1}^{n} \prod_{s=1}^{L_i} \sum_{m}^{\mathcal{M}_i} \sum_{f}^{\mathcal{F}_i} \sum_{r}^{\mathcal{R}_i} % \Pr(D^{(i)}_s|M_m^{(i)},F_f^{(i)},R_r^{(i)},L^{(i)},\tau) \Pr(M_m^{(i)}) \Pr(F_f^{(i)}) \Pr(R_r^{(i)}) \end{eqnarray*} where $\mathcal{M}_i$, $\mathcal{F}_i$ and $\mathcal{R}_i$ are the number of rate matrices, vector of equilibrium frequencies and relative rates that apply to partition element $i$ respectively. $\mathcal{I}(m,f,r,i)$ is an indicator function that takes value 1 if the combination $M_m$, $F_f$ and $R_r$ is acually defined in the model for this particular partition element $i$. Its value is 0 otherwise. In the example given in section \ref{sec:mixtures} $\{R_1,R_2,R_3\}$ is the set of substitution rates, $\{M_1,M_2\}$ the set of rate matrices and $\{F_1,F_2\}$ the set of vectors of equilibrium frequencies. We then define the first class of the mixture model as $\mathcal{C}_1 = \{R_1,M_1,F_1\}$, a second class as $\mathcal{C}_2 = \{R_2,M_1,F_1\}$ and the third as $\mathcal{C}_3 = \{R_3,M_2,F_2\}$. Hence, we have $\mathcal{I}(1,1,1,i)$, $\mathcal{I}(1,1,2,i)$ and $\mathcal{I}(2,2,3,i)$ equal to one while the nine other values that this indicator function takes, corresponding to the possible combinations of two vectors of frequencies, two matrices and three rates, are all zero. As stated before, our implementation assumes that the different components of a mixture are independant. In other words, we have $\Pr(M_m^{(i)},F_f^{(i)},R_r^{(i)}) = \Pr(M_m^{(i)}) \times \Pr(F_f^{(i)}) \times \Pr(R_r^{(i)})$. In practice, the joint probability $\Pr(M_m^{(i)},F_f^{(i)},R_r^{(i)})$ is obtained as follows: \begin{eqnarray*} \Pr(M_m^{(i)},F_f^{(i)},R_r^{(i)}) = \frac{\Pr(M_m^{(i)}) \Pr(F_f^{(i)}) \Pr(R_r^{(i)})}{ \sum_{m,f,r} \Pr(M_m^{(i)}) \Pr(F_f^{(i)}) \Pr(R_r^{(i)}) \mathcal{I}(m,f,r,i)} \label{equ:weights} \end{eqnarray*} The probabilities $\Pr(M_m^{(i)})$, $\Pr(F_f^{(i)})$ and $\Pr(R_r^{(i)})$, also called `weights', can be fixed or estimated from the data. \subsection{The XML format and its use in PhyML}\label{sec:XML format} The few paragraphs below are largely inspired from the Wikipedia page that describes the XML format (\url{http://en.wikipedia.org/wiki/XML}). XML (eXtensible Markup Language) is a markup language that defines a set of rules for encoding documents in a format that is both human-readable and machine-readable. An XML document is divided into {\em markup} and {\em content}, which may be distinguished by the application of simple syntactic rules. Generally, strings that constitute markup either begin with the character `\x{<}' and end with a `\x{>}'. Strings of characters that are not markup are content: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=XML markup and content example, samepage=true, baselinestretch=0.5, fontsize=\small] content \end{Verbatim} A markup construct that begins with `\x{<}' and ends with `\x{>}' is called a {\em tag}. Tags come in three flavors: (1) start-tags (e.g, \x{
}), end-tags (e.g., \x{
}) and empty-element tags (e.g., \x{}). A {\em component} either begins with a start-tag and ends with a matching end-tag or consists only of an empty-element tag. The characters between the start- and end-tags, if any, are the element's content, and may contain markup, including other elements, which are called child elements. In the following example, the element \x{img} has two {\em attributes}, \x{src} and \x{alt}: \x{Foligno  Madonna,  by
Raphael}. Another example would be \x{Connect A to B.} where the name of the attribute is ``\x{number}" and the value is ``\x{3}". In practice, building a mixture model in a XML file readable by PhyML is relatively straightforward. The first step is to define the different components of each class of the mixture. Consider for instance that the fitted model will have a Gamma distribution with four classes plus a proportion of invariants. The rate component of the mixture can then be specified using the following XML code: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=$\Gamma4$+I rates, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} In the example above, the \x{} component completely defines a model of substitution rate variation across sites. This component has a particular identity, i.e., a name associated to it (``\x{SiteRates1}'' here), which is not mandatory. This \x{} component has six sub-components. The first is the \x{} component, followed by five \x{} components. The \x{} component defines the type of distribution that characterizes the variation of rates across sites. A discrete Gamma plus invariants is used here. Two parameters specify this distribution: the gamma shape and the proportion of invariant parameters. Their initial values are set by using the corresponding attributes and attribute values (\x{alpha="0.1"} and \x{pinv="0.4"}). Also, PhyML can optimise these parameters so as to maximise the likelihood of the whole phylogenetic model (\x{optimise.pinv="yes"} and \x{optimise.alpha="yes"}). The following five \x{} components define the rate classes themselves. The \x{id} attribute is here mandatory and must be unique to each class. Note that one of the initial (relative) rate (\x{init.value} attribute) is set to zero. The corresponding rate class (the third in this example) will then correspond to the invariant site category. Having specified the part of the phylogenetic model that describes the variation of rates across sites, we can now move on to build the rest of the model. The component below defines two substitution models: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Rate matrices, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} This \x{} component sets out a list of substitution models (HKY85 and GTR here). Here again, the different elements in this list correspond to the \x{} sub-components. Each instance must have a unique \x{id} attribute for a reason that will become obvious shortly. The remaining attributes and their functions are described in Section \ref{sec:xmlratematrices}. The next ``ingredient'' in our phylogenetic model are vectors of nucleotide frequencies. The \x{} component below specifies two of such vectors: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Equilibrium frequencies, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} Now, we need to assemble these three components (rate variation across sites, rate matrices and vectors of equilibrium frequencies) into a mixture model. The \x{} component below defines one such model: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Mixture model, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} The \x{} component defines a particular partition element. In this example, the partition element corresponds to the sequence file called \x{nucleic.txt}, which is an alignment of nucleotide sequences (see the \x{data.type} attribute value). The \x{} are sub-components of the \x{} component. Each \x{} has a \x{list} atrribute. Each such \x{list} gives the ID of components that have been defined before. For instance, the first \x{} refers to the five classes of the \x{} component. The ordering of the different term in these list matters a lot since it is directly related to the elements in each class of the mixture model. Hence, the first element in the \x{} attribute of the first \x{} added to the first element in the \x{} attribute of the second \x{} plus the the first element in \x{} attribute of the third \x{} defines the first class of the mixture model. Therefore, the mixture model defined above has five classes: $\mathcal{C}_1 = \{R_1,M_1,F_1\}$, $\mathcal{C}_2 = \{R_2,M_1,F_2\}$, $\mathcal{C}_3 = \{R_3,M_1,F_1\}$, $\mathcal{C}_4 = \{R_4,M_2,F_2\}$ and $\mathcal{C}_5 = \{R_5,M_2,F_2\}$. % Going back to the different components of this model, the XML code dealing with the substitution % rates defines five classes with names {\tt R1} to {\tt R5}. The initial values of these rates are % set to 1.0, except for {\tt R5}, which is set to 0 and will therefore correspond to the invariable % site class. The {\tt } tag that follows indicate that these rates define a $\Gamma 4$+Inv % model, with initial gamma shape parameter set to 0.1 and initial proportion of invariants set to % 0.4. These two parameters will be estimated in the analysis ({\tt optimise.alpha} and {\tt % optimise.pinv} attributes set to {\tt yes}). The two rate matrices have names {\tt M1} and {\tt % M2}. {\tt M1} corresponds to a HKY85 model, with transition/transversion ratio set to 4.0 and set % to be optimised in the analysis. {\tt M2} is a GTR model, which parameters are also set to be % optimised. {\tt F1} and {\tt F2} are two vectors of nucleotide frequencies at equilibrium. These two % sets of frequencies will therefore be estimated during the analysis. \subsection{Setting up mixture and partition models in PhyML: the basics}\index{mixture models}\index{partitionned analysis}\index{data partitions} Mixture models are particularly relevant to the analysis of partitionned data. Indeed, some features of evolution are gene-specific (e.g., substitution rates vary across genes). Models that can accomodate for such variation, as mixture models do, are therefore relevant in this context. However, other evolutionary features are shared across loci (e.g., genes located in the same genomic region usually have similar GC contents). As a consequence, some components of mixture models need to be estimated separately for each partition element while others should be shared by different partition elements. Below is a simple example with a partitionned data set made of two elements: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Two sets of branch lengths (one per partition element), samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} Mixture elements with names \x{R1},$\ldots$, \x{R5} refer to the $\Gamma4+$I model defined previsouly (see Section \ref{sec:XML format}). The \x{} XML component defines a mixture element that had not been introduced before. It defined vectors of branch lengths that apply to the estimated phylogeny. Two instances of such vectors are defined: \x{L1} and \x{L2}. When examining the two partition elements (\x{} component), it appears that \x{L1} is associated with \x{Part1} while \x{L2} is associated with \x{Part2}. Hence, branch lengths will be estimated separately for these two partition elements. Note that a given partition element can only have one {\tt branchlengths} instance associated to it. For instance, the example given below is not valid: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Invalid mixture, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} In other words, mixture of branch lengths are forbidden. One reason for this restriction is that mixture of edge lengths sometimes lead to non-identifiable models (i.e., models with distinct sets of branch lengths have the same likelihood) \cite{matsen07}. But mostly, combining mixture of branch lengths with mixture of rates appears like a deadly combination. Consider for instance the following model: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Invalid mixture, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} It is here impossible to tell apart branch lengths and substitution rates. Such model is strongly non-identifiable and therefore not relevant. In the example given above, the same $\Gamma4+$I model (i.e. the same gamma shape parameter and proportion of invariant ) applies to the two partition elements. It is possible to use two distinct $\Gamma4+$I models instead using the following XML code: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Two distinct $\Gamma4+$I models, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \x{SiteRates1} and \x{SiteRates2} here define two distinct $\Gamma4+$I models. Each of these models apply to one of the two partition elements (\x{nucleic1.txt} and \x{nucleic2.txt}), allowing them to display different patterns of rate variation across sites. \subsection{XML options} \subsubsection{{\tt phyml} component}\index{XML options!{\tt phyml} component} Options: \begin{itemize} \item \x{output.file="filename"}. The main output files of PhyML analysis will be named \x{filename\_phyml\_tree} and \x{filename\_phyml\_stats}. \item \x{bootstrap="nreplicates"}. Run \x{nreplicates} replicates for the non-parametric bootstrap analysis. \item \x{run.id="idstring"}. PhyML will append the string \x{idstring} to each output file. \item \x{print.trace="yes|true|no|false"}. PhyML will print the estimated trees (and the corresponding loglikelihoods) at multiple stages of the estimation process. This option is useful for monitoring the progress of the analysis when processing large data sets. \item \x{branch.test="aBayes|aLRT|SH|no"}. Calculate fast branch support using the aBayes method \cite{anisimova11}, aLRT \cite{anisimova06} or SH \cite{shimodaira99} tests. These branch statistics are much faster to estimate than the bootrap proportions and usually provide good estimates of the probabilities that the corresponding edges are correctly inferred (see Anisimova et al. 2011 for more precision). By default and if no bootstrap analysis is performed, branch supports are estimated using the aBayes approach. \item \x{quiet="yes|no"}. Runs PhyML in quiet mode when \x{quiet=yes}. The program will not pause if the memory required to run the analysis exceeds 256MB and will not output the progresssion of the log-likelihood scores on the standard output. \item \x{memory.check="yes|no"}. By default, when processing a large data set, PhyML will pause and ask the user to confirm that she/he wants to continue with the execution of the analysis despite the large amount of memory required. Setting \x{memory.check=no} skips this question. It is especially useful when running PhyML in batch mode. \end{itemize} \subsubsection{{\tt topology} component}\index{XML options!{\tt topology} component} Options: \begin{itemize} \item \x{init.tree="bionj"|"user"|"random"}. Starting tree. Default is \x{bionj}. \item \x{file.name="name\_of\_tree\_file"}. In case \x{init.tree="user"}, this attribute is mandatory. \x{name\_of\_tree\_file} is a text file containing a tree in NEWICK format. \item \x{optimise.tree="yes"|"true"|"no"|"false"}. The starting tree topology as defined by \x{init.tree} is to be optimised (or not) so as to maximise the likelihood function. \item \x{search="nni"|"spr"|"none"}. Tree topology search is conducted using NNI (fast), SPR (a bit slower but more accurate) or no moves. \end{itemize} \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `topology' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsubsection{{\tt ratematrices} component}\index{XML options!{\tt ratematrices} component}\label{sec:xmlratematrices} Options: \begin{itemize} \item \x{model="JC69"|"K80"|"F81"|"F84"|"HKY85"|"TN93"|"GTR"|"custom"} for nucleotide data. The default is \x{"HKY85"}.\\ \x{model="LG"|"WAG"|"JTT"|"MtREV"|"Dayhoff"|"DCMut"|"RtREV"|"CpREV"|"VT"}\\\x{|"Blosum62"|"MtMam"|"MtArt"|"HIVw"|"HIVb"|"customaa"} for amino-acid sequences. The default is \x{"LG"}. \item \x{model.code="012345"}. For \x{custom} model applied to nucleotide sequences: set the string of digits that define a custom substitution model. See Table \ref{tab:modelcode} on page \pageref{tab:modelcode} for more information about the model codes. \item \x{ratematrix.code="filename"}. When used in conjunction with \x{model="customaa"}, \x{filename} is the name of the file that gives the rates of substitution between amino-acids as well as their frequences at equilibrium using PAML rate matrix format. An example of such file is provided in {phyml/examples/X1.mat}. \item \x{optimise.rr="yes"|"true"|"no"|"false"}. For \x{custom} and \x{GTR} nucleotide models only: optimise the substitution rate model parameters. \item \x{optimise.tstv="yes"|"true"|"no"|"false"}. For \x{K80}, \x{F84}, \x{HKY85} and \x{TN93} models only: optimise the transition/transversion rate ratio. \item \x{tstv="value"}. For \x{K80}, \x{HKY85} and \x{TN93} models only: set the transition/transversion to a given value. \end{itemize} The {\tt ratematrices} component has the attribute {\tt optimise.weights=yes/no} (default is {\tt no}). If {\tt optimise.weights=yes}, then the probabilities (or weights) or each matrix in the set of matrices defined by this component (see Equation \ref{equ:weights}), will be estimated from the data. \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `ratematrices' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsubsection{{\tt equfreqs} component}\index{XML options!{\tt equfreqs} component} Options: \begin{itemize} \item \x{base.freqs="a,b,c,d"} where \x{a-d} are nucleotide frequencies. Make sure that these frequencies are separated by comas and no space character is inserted. \item \x{aa.freqs="empirical|model"}. Amino-acid frequencies are derived from counting the number of occurence of each amino-acid in the alignment (\x{aa.freqs="empirical"}) or given by the substitution model (\x{aa.freqs="model"}). \item \x{optimise.freqs="true|yes|false|no"}. Nucleotide frequencies can be optimised so as to maximise the likelihood (\x{optimise.freqs="yes|true"}). \end{itemize} The {\tt equfreqs} component has the attribute {\tt optimise.weights=yes/no} (default is {\tt no}). If {\tt optimise.weights=yes}, then the probabilities (or weights) or each vector of equilibrium frequencies in the set of vectors defined by this component (see Equation \ref{equ:weights}), will be estimated from the data. \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `equfreqs' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsubsection{{\tt branchlengths} component}\index{XML options!{\tt branchlengths} component} Options: \begin{itemize} \item \x{optimise.lens="yes"|"true"|"no"|"false"}: branch lengths are optimised or not. The default is set to \x{"yes"}. \end{itemize} \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `branchlengths' component, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsubsection{{\tt siterates} component}\index{XML options!{\tt siterates} component} Options: \begin{itemize} \item \x{value="val"}, where \x{"val"} is the relative substitution rate for the corresponding class. \end{itemize} A \x{siterate} component generally includes a \x{weights} element that specifies the probabilitic distribution of the relative rates. The available options for such element are: \begin{itemize} \item \x{family="gamma|gamma+inv|freerates"}. \x{gamma} indicates that the distribution of the relative rates is set to be a discrete Gamma density. \x{gamma+inv} indicates that the relative rate model is a mixture of Gamma and invariant sites (this is the common $\Gamma+$I model). FreeRate is a model that does not use any parametric function to describe the distribution of the relative rates (see \cite{soubrier12}). Under this option, relative rates and the corresponding frequencies of these classes are directly estimated from the data. While such approach is slightly more computationally demanding than the $\Gamma$ (or $\Gamma$+I) model, it often provides a significantly better fit to the data. \item \x{alpha="value|optimised"}, where \x{value} is a real positive number. Use this option to set the gamma shape parameter to the selected value. \x{optimised}: the parameter is estimated from the data (see also next option). \item \x{optimise.alpha="yes|true|no|false"}. Optimise the shape of the Gamma distribution of relative rates (or not). \item \x{pinv="value|optimised"}, where \x{value} is in $[0,1]$. Use this option to set the proportion of invariants to the selected value. \x{optimised}: the parameter is estimated from the data (see also next option). \item \x{optimise.pinv="yes|true|no|false"}. Optimise the proportion of invariable sites (or not). \item \x{optimise.freerates="yes|true|no|false"}. Optimise the parameters of the FreeRate model, i.e., the relative rates and the corresponding frequencies. \end{itemize} \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `siterates' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsubsection{{\tt partitionelem} and {\tt mixtureelem} components}\index{XML options!{\tt partitionelem} component}\index{XML options!{\tt mixtureelem} component} Options: \begin{itemize} \item \x{file.name="inputfilename"}, where \x{inputfilename} is the name of the input sequence file (in PHYLIP format) to be analysed. \item \x{data.type="nt|aa"}. Specify the type of sequences to be processed (nucleotide of amino-acid sequences). \item \x{interleaved="yes|true|no|false"}. Interleaved (\x{yes|true}) or sequential format (\x{no|false}) for the sequence alignment. \item \x{optimise.tree.scale="yes|true|no|false"}. The sum of edge length (or tree size) is optimized. This option is relevant when different data partition elements point to the same set of edge lengths so that setting \x{optimise.tree.scale="yes"} will find the optimal ratio of tree sizes considering the two elements. In other words, the different trees all share the same (relative) edge lengths but the corresponding partition elements have different mean rates of substitution. \item \x{tree.scale="val"}. \x{val} is the value of the (relative) substitution rate. By default, its value is set to 1.0. \end{itemize} Each \x{partitionelem} element should include exactly four \x{mixtureelem} elements, corresponding to branch lengths, equilibrium frequencies, substitution rate model and tree topology. The ordering of in which the \x{mixtureelem} elements are given does not matter, though exceptions apply for the $\Gamma+I$ model (see below). The $n$-th element in the \x{list} attribute of each \x{mixtureelem} defines the $n$-th class of the mixture model. In the example given below, the first class of the mixture is made of the following elements: \x{T1}, \x{F1}, \x{R1} and \x{L1}, the second class is made of \x{T1}, \x{F1}, \x{R2} and \x{L1}, etc. \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `partitionelem' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} In general, the ordering of the \x{mixtureelem} elements does not matter. However, when the model has invariable sites, then the corresponding class should be first in the list of classes provided by \x{mixtureelem}. For instance, in the example above, if the rates are defined as follows: \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of `siterates' component, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} then \x{R1} corresponds to the invariable rate class (as \x{init.value="0.0"}). As \x{R1} is first in the \x{mixtureelem} (see line 6 in the example of \x{`partionelem'} given above), PhyML will print out an explicit error message and bail out. One way to avoid this shortcoming is to define \x{mixtureelem} as \x{R4, R2, R3, R1} instead. \subsection{A simple example: GTR + $\Gamma$4 + I} The example below provides all the required options to fit a $\Gamma$4+I model to a single alignment of nucleotide sequences under the GTR model of substitution using a SPR search for the best tree topology. The \x{phyml} component sets the name for the analysis to \x{simple.example}, meaning that each output file will display this particular string of characters. Also, the tree and statistics file names will begin with \x{p1.output}. The tree topology will be estimated so as to maximise the likelihood and the topology search algorithm used here is SPR, as indicated by the value of the corresponding attribute (i.e., \x{search="spr"}). Only one vector of branch lengths will be used here since only one partition element will be processed. Hence, the \x{} component only has one \x{} sub-component. Also, a single GTR model will apply to all the classes for the mixture model -- the \x{} component has only one \x{} sub-component, corresponding to this particular substitution model. The next component, \x{}, indicates that a single vector of equilibrium frequencies will apply here. Next, the \x{} component has five \x{} sub-components. Four of these correspond to the non-zero relative rates of evolution a defined by a discrete Gamma distribution. The last one (\x{}) defines the class of the mixture corresponding to invariable sites. The \x{} component indicates that a $\Gamma+$I model will be fitted here. The shape parameter of the Gamma distribution and the proportion of invariants will be estimated from the data. The \x{} gives information about the sequence alignment (the corresponding file name, the type of data and the alignment format). The \x{} components next define the mixture model. Each class of the fitted model corresponds to one column, with the first column made of the following elements: \x{T1, M1, F1, R1} and \x{L1}. The second class of the mixture is made of \x{T1, M1, F1, R2, L1} and so forth. \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Simple PhyML XML example, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsection{A second example: LG4X}\index{lg4x} The example below shows how to fit the LG4X model \cite{lg4x} to a given alignment of amino-acid sequences (file \x{M587.nex.Phy}). LG4X is a mixture model with four classes. Each class has its own rate and corresponding frequencies (hence the use of the FreeRate model below, see the \x{} component). In the particular example given here, the rate values and frequencies are set by the users. These parameters will then be optimized by PhyML (\x{optimise.freerates="yes"}). Each class also has its own rate matrix and vector of equilibrium frequencies, which need to be provided by the user (Note that these matrices can be downloaded from the following web address: \url{http://www.atgc-montpellier.fr/download/datasets/models/lg4x/LG4X_4M.txt}. They are also provided in the PhyML package \x{example/lg4x/} directory.) \vspace{0.2cm} \begin{Verbatim}[frame=single, label=LG4X, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} In order to fit the LG4X model to the \x{proteic} sequence file provided in the \x{examples/} directory, simply type \x{./phyml --xml=../examples/lg4x/lg4x.xml} (assuming the PhyML binary is installed in the \x{src/} directory). You can of course slightly tweak the file \x{../examples/lg4x/lg4x.xml} and use it as a template to fit this model to another data set. \subsection{An example with multiple partition elements} The example below gives the complete XML file to specify the analysis of three partition elements, corresponding to the nucleotide sequence files \x{small\_p1\_pos1.seq}, \x{small\_p1\_pos2.seq} and \x{small\_p1\_pos3.seq} in interleaved PHYLIP format. \x{small\_p1\_pos1.seq} is fitted with the HKY85 model of substitution (with the transition/transversion ratio being estimated from the data), combined to a $\Gamma4$ model of rate variation across sites (with the gamma shape parameter being estimated from the data). \x{small\_p1\_pos2.seq} is fitted to a custom substitution model with the constraint $A\leftrightarrow G$=$C\leftrightarrow T$. The nucleotide frequencies are set to $\frac{1}{4}$ here. The model does not allow substitution rates to vary across sites. \x{small\_p1\_pos3.seq} is fitted using a GTR model conbined to a $\Gamma4+$I model of rate variation across sites. Note that the equilibrium nucleotide frequencies for the fourth and fifth class of the mixture are set to be equal to that estimated from the first partition element (i.e., \x{F1}) . The initial phylogeny is built using BioNJ and the tree topology is to be estimated using a NNI search algorithm. \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of PhyML XML file, samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \vspace{0.2cm} \begin{Verbatim}[frame=single, label=Example of PhyML XML file (ctnd), samepage=true, baselinestretch=0.5, fontsize=\small, numbers=left] \end{Verbatim} \subsection{Branch lengths with invariants and partionned data} Accommodating for models with invariable sites applying to some elements of a partitioned data, with these elements sharing the same set of edge lengths can lead to inconsistencies. Consider for instance a partitioned data set with two elements. Assume that these two elements share the same set of edge lengths. Also, consider that GTR+I applies to the first element and HKY applies to the second. Now, the expected number of substitutions per site for the first element of the partition is equal to $(1-p)l$, where $p$ is the estimated proportion of invariants and $l$ is the maximum-likelihood estimate for the length of that specific edge. For the second element of the partition, the expected number of substitutions per site is equal to $l$, rather than $(1-p)l$. While $l$ are common to the two elements, matching the specification of the input model, the actual edge lengths do differ across the two partition elements. Please be aware that, due to the programming structure implemented in PhyML, the program will only return one value here, which will be equal to $(1-p)l$. \section{Citing PhyML} The ``default citation'' for PhyML is: \begin{itemize} \item ``New algorithms and methods to estimate maximum-likelihood phylogenies: assessing the performance of PhyML 3.0''. Guindon S., Dufayard J.F., Lefort V., Anisimova M., Hordijk W., Gascuel O. 2010, {\it Systematic Biology}, 59(3):307-321 \end{itemize} The ``historic citation'' for PhyML is: \begin{itemize} \item ``A simple, fast and accurate algorithm to estimate large phylogenies by maximum likelihood'' Guindon S., Gascuel O. 2003, {\it Systematic Biology}, 52(5):696-704 \end{itemize} \section{Other programs in the PhyML package} PhyML is software package that provides tools to tackle problems other than estimating maximum likelihood phylogenies. Installing these tools and processing data sets is explained is the following sections. \subsection{PhyTime}\index{PhyTime} PhyTime is a program that estimates node ages and substitution rates using a Bayesian approach. The performance and main features of this software are described in two article (see Section \ref{sec:citephytime}). It relies on a Gibbs sampler which outperforms the ``standard'' Metropolis-Hastings algorithm implemented in a number of phylogenetic softwares. The details and performance of this approach are described in the following article: \subsubsection{Installing PhyTime} Compiling PhyTime is straightforward on Unix-like machines (i.e., linux and MacOS systems). PhyTime is not readily available for Windows machines but compilation should be easy on this system too. In the `phyml' directory, where the `src/' and `doc/' directories stand, enter the following commands: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure --enable-phytime; make clean; make; \end{verbatim} } This set of commands generates a binary file called \x{phytime} which can be found in the `src/' directory. \subsubsection{Running PhyTime} Passing options and running PhyTime on your data set is quite similar to running PhyML in commmand-line mode. The main differences between the two programs are explained below: \begin{itemize} \item PhyTime takes as mandatory input a {\em rooted} phylogenetic tree. Hence, the `\x{-u}' option must be used. Also, unlike PhyML, PhyTime does not modify the tree topology. Hence, the options that go with the `\x{-s}' command do not alter the input tree topology. \item PhyTime needs an input file giving information about calibration nodes. The command `\x{--calibration=}' followed by the name of the file containing the calibration node information is mandatory. The content of that file should look as follows: \begin{figure}[h] \begin{small} \begin{Verbatim}[frame=single, label=Calibration node file, samepage=true, baselinestretch=0.5, fontsize=\tiny] Dugong_dugon Procavia_capensis Elephantidae | -65 -54 Equus_sp. Ceratomorpha | -58 -54 Cercopithecus_solatus Macaca_mulatta Hylobates_lar Homo_sapiens | -35 -25 Lepus_crawshayi Oryctolagus_cuniculus Ochotona_princeps | -90 -37 Marmota_monax Aplodontia_rufa | -120 -37 Dryomys_nitedula Glis_glis | -120 -28.5 @root@ | -100 -120 \end{Verbatim} \end{small} \end{figure} Every row in this file lists a set of taxa that belong to the same subtree (i.e., a clade). This list of taxa is followed by the character `\x{|}' and two real numbers corresponding to the lower and upper bounds of the calibration interval for the node at the root of the clade. In the example given here, the clade grouping the three taxa ``Dugong\_dugon'', ``Procavia\_capensis'' and ``Elephantida'' has -65 as lower bound and -54 as upper bound. Node ages (or node heights) are relative to the most recent tip node in the phylogeny, which age is set to 0. It is also possible to define a clade using only two taxon names. PhyTime will then search for the most recent common ancestor of these two taxa in the user-defined phylogeny and assign time boundaries to the corresponding node. For serially-sampled data, the calibration nodes correspond to tips in the tree. A calibration file will then look as follows: \begin{figure}[h] \begin{small} \begin{Verbatim}[frame=single, label=Calibration node file (serially-sampled sequences), samepage=true, baselinestretch=0.5] taxaA | -65 -65 taxaB | -65 -65 taxaC | -20 -20 taxaD | -30 -30 taxaE | -30 -30 taxaF | -60 -60 taxaG | -61 -51 @root@ | -100 -120 \end{Verbatim} \end{small} \end{figure} % The maximum value the average substitution rate along a branch of a phylogeny can take is set to % $10^{-2}$ substitution per site per time unit. It is therefore important that the time unit used to % specify the calibration intervals are realistic with respect to this upper bound. For instance, it % one time unit corresponds to one month, one assumes that the maximum (average) substitution rate is % $10^{-3}$/site/month, which is very high (substitution rate in introns is close to 3/site/$10^9$ % years). Consider that in the example give above, one time unit is $10^6$ years. Hence, the maximum % value the substitution rate can take is $10^{-2}$/site/$10^6$ years, i.e., $10$/site/$10^9$ years. % Multiplying the calibration values by 10 amounts to considering that the time unit is $10^5$ years, % implying a maximum substitution rate equal to $10^{-2}$/site/$10^5$ years, i.e., $100$/site/$10^9$ % years. Note that the node corresponding to the root of the whole tree has a specific label: `\x{@root@}'. {\color{red}{It is important to specify upper and lower bounds for the root node in order to ensure convergence of the Gibbs sampler. If the prior interval for the root height is not specified, the upper bound will be set to the upper bound of the oldest calibration node and the lower bound will be set to twice this age.}} As a consequence, leaving the prior on root height interval unspecified may produce inaccurate estimates of node ages, especially if there are only few otherwise calibration nodes available. A notable exception to this rule comes from the analysis of serial sample \index{serial sample} data, i.e., alignments in which sequences were not sampled at the same time point. For such data, the estimated number of substitutions accumulated between successive time points is used to estimate the substitution rate averaged over lineages. Because the time of collection of the sequences is generally known without ambiguity, this extra piece of data is translated into very informative calibration intervals for the tip nodes (i.e., calibration interval of zero width), which in turn results in substitution rate estimates with descreased variances. Posterior distribution of substitution rates with small variances then allows one to get good estimates of the root age. \end{itemize} A typical PhyTime command-line should look like the following\index{command-line options!\x{--calibration}}: \begin{Verbatim}[fontsize=\small] ./phytime -i seqname -u treename --calibration=calibration_file -m GTR -c 8 \end{Verbatim} Assuming the file `\x{seqname}' contains DNA sequences in PHYLIP or NEXUS format, `\x{treename}' is the rooted input tree in Newick format and `\x{calibration\_file}' is a set of calibration nodes, PhyTime will estimate the posterior distribution of node times and substitution rates under the assumption that the substitution process follows a GTR model with 8 classes of rates in the Gamma distribution of rates across sites. The model parameter values are estimated by a Gibbs sampling technique. This algorithm tries diferent values of the model parameters and record the most probable ones. By default, $10^6$ values for each parameter are collected. These values are recorded every $10^3$ sample. These settings can be modified using the appropriate command-line options (see below). \subsubsection{Upper bounds of model parameters} The maximum expected number of substitutions per along a given branch is set to 1.0. Since calibration times provide prior information about the time scale considered, it is possible to use that information to define an upper bound for the substitution rate. This upper bound is equal to the ratio of the maximum value for a branch length (1.0) by the amount of time elapsed since the oldest calibration point (i.e., the minimum of the lower bounds taken over the whole set of calibration points)\footnote{The actual formula involves an extra parameter which does not need to be introduced here}. It is important to keep in mind that the upper bound of the average substitution rate depends on the time unit used in the calibration priors. The value of the upper bound is printed on screen at the start of the execution. PhyTime implements two models that authorize rates to be autocorrelated. The strength of autocorrelation is governed by a parameter which value is estimated from the data. However, it is necessary to set an appropriate upper bound for this parameter prior running the analysis. The maximum value is set such that the correlation between the rate at the beginning and at the end of a branch of length 1.0 calendar time unit is not different from 0. Here again the upper bound for the model parameter depends on the time unit. It is important to choose this unit so that a branch of length 1.0 calendar unit can be considered as short. For this reason, {\color{red}{we recommend to select a time unit so that the calibration times take values between -10 and -1000}}\index{time scale}. \subsubsection{PhyTime specific options} Beside the \x{--calibration} option, there are other command line options that are specific to PhyTime: \begin{itemize} \item \x{--chain\_len=num}\index{command-line options!\x{--chain\_len}} \\ \x{num} is the number of iterations required to estimate the joint posterior density of all the model parameters, i.e., the length of the MCMC chain. Its default is set to 1E+6. % \item \x{--burnin=num} \\ % \x{num} is the number of iterations for the ``burnin'' period, i.e., the number of iterations % required before actually starting to get valid samples from the joint posterior density of all the % model parameters. Its default is set to 1E+5, i.e., 0.1 times the default value of the \x{chain\_len} % parameter (see above). \item \x{--sample\_freq=num}\index{command-line options!\x{--sample\_freq}} \\ \x{num} is the number of generations between successive collection of the model parameter values throughout the MCMC algorithm. For instance, the \x{--sample\_freq=1E+2} option will make PhyTime sample the model parameter every 100th iteration of the MCMC algorithm. Its default is set to 1E+3. \item \x{--fastlk=yes (no)}\index{command-line options!\x{--fastlk}} [Default: no]\\ The option is used to turn on (off) the approximation of the likelihood function using a multivariate normal density. By default, the exact likelihood is used. Using the normal approximation considerably speeds up the calculation. However, it is necessary to ensure that this approximation is appropriate by looking at the correlation between the exact and approximated likelihood values that are sampled. Please read Section \ref{sec:recomphytime} for a description of the appropriate steps to take. \item \x{--no\_sequences}\index{command-line options!\x{--no\_sequences}}\\ Use this option to run the sampler without sequence data. This option can be useful when one wants to compare the marginal posterior density of model parameters to those derived when ignoring the information conveyed by the sequences. Such comparison should be conducted on a systematic basis so as to determine whether the parameters estimates are mostly determined by the prior of driven by the sequence data. \item \x{--rate\_model=gbs/gbd/gamma/clock}\index{command-line options!\x{--rate\_model}}\\ This option is to select the model of evolution of the rate of evolution. \x{gbs} (default) stands for Geometric Brownian + Stochastic. This model considers that rates evolve along the tree according to a geometric Brownian process \cite{kishino01} and the average rate of substitution along a branch is a gamma distributed random variable. This model is described in \cite{guindon13}. The \x{gbd} model (Geometric Browninan with Deterministic calculation of edge lengths) assumes the same Geometric Brownian model of rates. However, as opposed to \x{gbs}, this model uses a deterministic approximation to calculate the average rates of evolution along edges. This model corresponds to the one described in \cite{kishino01} and implemented in the program Multidivtime\index{Multidivtime}. \x{gamma} is a less sophisticated model that assumes that average rates along edges are distributed a priori according to a gamma distribution. It is analogous to the uncorrelated clock model implemented in BEAST\index{BEAST} with a gamma distribution replacing the exponential one. The \x{clock} option corresponds to the strict clock model where all the lineages in the tree evolve at the same pace. \end{itemize} \subsubsection{PhyTime output} The program PhyTime generates two output files. The file called `\x{your\_seqfile\_phytime\_XXXX\_stats}', where XXXX is a randomly generated integer, lists the node times and branch relative rates sampled during the estimation process. It also gives the sampled values for other parameters, such as the autocorrelation of rates (parameter `Nu'), and the rate of evolution (parameter `EvolRate') amongst others. This output file can be analysed with the program Tracer\index{Tracer} from the BEAST\index{BEAST} package (\url{http://beast.bio.ed.ac.uk/Main_Page}). The second file is called `\x{your\_seqfile\_phytime\_XXXX\_trees}'. It is the list of trees that were collected during the estimation process, i.e., phylogenies sampled from the posterior density of trees. This file can be processed using the software TreeAnnotator, also part of the BEAST package (see \url{http://beast.bio.ed.ac.uk/Main_Page}) in order to generate confidence sets for the node time estimates. Important information is also displayed on the standard output of PhyTime (the standard output generally corresponds to the terminal window from which PhyTime was launched). The first column of this output gives the current generation, or run, of the chain. It starts at 1 and goes up to 1E+6 by default (use \x{--chain\_len} to change this value, see above). The second column gives the time elapsed in seconds since the sampling began. The third column gives the log likelihood of the phylogenetic model (i.e., `Felsenstein's likelihood'). The fourth column gives the logarithm of the joint prior probability of substitution rates along the tree and node heights. The fifth column gives the current sampled value of the EvolRate parameter along with the corresponding Effective Sample Size (ESS) (see Section \ref{sec:ess}) for this parameter. The sixth column gives the tree height and the corresponding ESS. The seventh column gives the value of the autocorrelation parameter followed by the corresponding ESS. The eightth column gives the values of the birth rate parameter that governs the birth-rate model of species divergence dates. The last column of the standard output gives the minimum of the ESS values taken over the whole set of node height estimates. It provides useful information when one has to decide whether or not the sample size is large enough to draw valid conclusion, i.e., decide whether the chain was run for long enough (see Section \ref{sec:recomphytime} for more detail about adequate chain length). \subsubsection{ClockRate vs. EvolRate} The average rate of evolution along a branch is broken into two components. One is called ClockRate and is the same throughout the tree. The other is called EvolRate and corresponds to a weighted average of branch-specific rates. The model of rate evolution implemented in PhyTime forces the branch-specific rate values to be greater than one. As a consequence, ClockRate is usually smaller EvolRate. In more mathematical terms, let $\mu$ be the value of ClockRate, $r_i$ be the value of the relative rate along branch $i$ and $\Delta_i$ the time elapsed along branch $i$. The value of EvolRate is then given by: \begin{eqnarray*} \mathrm{EvolRate} = \mu \frac{\sum_{i}^{2n-3} r_i \Delta_i}{\sum_{i}^{2n-3} \Delta_i}. \end{eqnarray*} It is clear from this equation that multiplying each $r_i$ by a constant and dividing $\mu$ by the same constant does not change the value of EvolRate. The $r_i$s and $\mu$ are then confounded, or non-identifiable, and only the value of EvolRate can be estimated from the data. {\color{red}{Please make sure that you use the value of EvolRate rather than that of ClockRate when referring to the estimate of the substitution rate}}. \subsubsection{Effective sample size}\label{sec:ess} The MCMC technique generates samples from a target distribution (in our case, the joint posterior density of parameters). Due to the Markovian nature of the method, these samples are not independent. The ESS is the estimated number of independent measurements obtained from a set of (usually dependent) measurements. It is calculated using the following formula: \begin{eqnarray*} \mathrm{ESS} = N\left(\frac{1-r}{1+r}\right), \end{eqnarray*} where $N$ is the length of the chain (i.e., the `raw' or `correlated' sample size) and $r$ is the autocorrelation value, which is obtained using the following formula: \begin{eqnarray*} r = \frac{1}{(N-k)\sigma_x^2} \sum_{i=1}^{N-k} (X_i - \mu_x)(X_{i+k}-\mu_x), \end{eqnarray*} where $\mu_x$ and $\sigma_x$ are the mean and standard deviation of the $X_i$ values respectively and $k$ is the lag. The value of $r$ that is used in PhyTime corresponds to the case where $k=1$, which therefore gives a first order approximation of the `average' autocorrelation value (i.e., the autocorrelation averaged over the set of possible values of the lag). \subsubsection{Prior distributions of model parameters}\label{sec:prior} Any Bayesian analysis requires specifying a prior distribution of model parameters. The outcome of the data analysis, i.e., the posterior distribution, is influenced by the priors. It is especially true if the signal conveyed by the data is weak. While some have argued that the specification of priors relies more on arbitrary decisions than sound scientific reasoning, choosing relevant prior distributions is in fact fully integrated in the process of building model that generates the observed data. In particular, the problem of estimating divergence times naturally lends itself to hierarchical Bayesian modelling. Based on the hypothesis that rates of evolution are conserved (to some extant) throughout the course of evolution, the hierarchical Bayesian approach provides an adequate framework for inferring substitution rates and divergence dates separately. Hence, in this situation, it makes good sense to use what is known about a relatively well-defined feature of the evolution of genetic sequences (the ``molecular clock'' hypothesis combined to stochastic variations of rates across lineages) to build a prior distribution on rates along edges. \subsubsection{Citing PhyTime}\label{sec:citephytime} The ``default citation'' is: \begin{itemize} \item Guindon S. ``From trajectories to averages: an improved description of the heterogeneity of substitution rates along lineages'', {\it Systematic Biology}, 2013. 62(1): 22-34. \end{itemize} An earlier article also described some of the methods implemented in PhyTime: \begin{itemize} \item Guindon S. ``Bayesian estimation of divergence times from large data sets'', {\it Molecular Biology and Evolution}, 2010, 27(8):1768:81. \end{itemize} \subsection{PhyloGeo}\index{PhyloGeo} PhyloGeo is a program that implements the competition-dispersal phylogeography model described in Ranjard, Welch, Paturel and Guindon ``Modelling competition and dispersal in a statistical phylogeographic framework''. Accepted for publication in {\it Systematic Biology}. It implements a Markov Chain Monte Carlo approach that samples from the posterior distribution of the three parameters of interest in this model, namely the competition intensity $\lambda$, the dispersal bias parameter $\sigma$ and the overal dispersal rate $\tau$. The data consist in a phylogeny with node heights proportional to their ages and geographical locations for evety taxon in this tree. An important assumption of the model is that each node in the phylogeny corresponds to a speciation {\em and} a dispersal event. As a consequence, this model does not authorize a given taxon to occupy more than one locations. Note however that the converse is not true: a given location can be occupied by several different taxa. \subsubsection{Installing PhyloGeo} Compiling PhyloGeo is straightforward on Unix-like machines (i.e., linux and MacOS systems). PhyloGeo is not readily available for Windows machines but compilation should be easy on this system too. In the `phyml' directory, where the `src/' and `doc/' directories stand, enter the following commands: {\setlength{\baselineskip}{0.5\baselineskip} \begin{verbatim} ./configure --enable-geo; make clean; make; \end{verbatim} } This set of commands generates a binary file called \x{phylogeo} which can be found in the `src/' directory. \subsubsection{Running PhyloGeo} PhyloGeo takes as input a rooted tree file in Newick format and a tree with geographical locations for all the tips of the phylogeny. Here is an example of valid tree and the corresponding spatial locations just below: \begin{scriptsize} \begin{Verbatim}[frame=single, label=Valid PhyloGeo input tree, samepage=true, baselinestretch=0.5] (((unicaA:1.30202,unicaB:1.30202):1.34596,(((nitidaC:0.94617,(nitidaA:0.31497, nitidaB:0.31497):0.63120):0.18955,(((mauiensisA:0.00370,mauiensisB:0.00370):0.20068, (pilimauiensisA:0.05151,pilimauiensisB:0.05151):0.15287):0.78769,(brunneaA:0.10582, brunneaB:0.10582):0.88625):0.14365):0.80126,(((molokaiensisA:0.03728, molokaiensisB:0.03728):0.71371,(deplanataA:0.01814,deplanataB:0.01814):0.73285):0.34764, ((parvulaA:0.20487,parvulaB:0.20487):0.40191,(kauaiensisA:0.24276, kauaiensisB:0.24276):0.36401):0.49186):0.83835):0.71099):1.38043, (nihoaA:0.05673,nihoaB:0.05673):3.97168); \end{Verbatim} \begin{Verbatim}[frame=single, label=Valid PhyloGeo spatial location file, samepage=true, baselinestretch=0.5] nihoaA 23.062222 161.926111 nihoaB 23.062222 161.926111 kauaiensisA 22.0644445 159.5455555 kauaiensisB 22.0644445 159.5455555 unicaA 21.436875 158.0524305 unicaB 21.436875 158.0524305 parvulaA 21.436875 158.0524305 parvulaB 21.436875 158.0524305 molokaiensisA 20.90532 156.6499 molokaiensisB 20.90532 156.6499 deplanataA 20.90532 156.6499 deplanataB 20.90532 156.6499 brunneaA 20.90532 156.6499 brunneaB 20.90532 156.6499 mauiensisA 20.90532 156.6499 mauiensisB 20.90532 156.6499 pilimauiensisA 20.90532 156.6499 pilimauiensisB 20.90532 156.6499 nitidaA 19.7362 155.6069 nitidaB 19.7362 155.6069 nitidaC 19.7362 155.6069 \end{Verbatim} \end{scriptsize} In order to run PhyloGeo, enter the following command: \x{./phylogeo ./tree\_file ./spatial\_location\_file > phylogeo\_output}. PhyloGeo will then print out the sampled values of the model parameters in the file \x{phylogeo\_output}. This file can then be used to generate the marginal posterior densities of the model parameters. In particular, evidence for competition corresponds to value of $\lambda$ smaller than 1.0. Please see the original article for more information on how to interpret the model parameters. \subsubsection{Citing PhyloGeo}\label{sec:citephylogeo} Ranjard, L., Welch D., Paturel M. and Guindon S. ``Modelling competition and dispersal in a statistical phylogeographic framework''. 2014. Systematic Biology. \section{Recommendations on program usage}\label{sec:progusage} \subsection{PhyML} The choice of the tree searching algorithm among those provided by PhyML is generally a tough one. The fastest option relies on local and simultaneous modifications of the phylogeny using NNI moves. More thorough explorations of the space of topologies are also available through the SPR options. As these two classes of tree topology moves involve different computational burdens, it is important to determine which option is the most suitable for the type of data set or analysis one wants to perform. Below is a list of recommendations for typical phylogenetic analyses. \begin{enumerate} \item {\em Single data set, unlimited computing time.} The best option here is probably to use a SPR search (i.e., straight SPR of best of SPR and NNI). If the focus is on estimating the relationships between species, it is a good idea to use more than one starting tree to decrease the chance of getting stuck in a local maximum of the likelihood function. Using NNIs is appropriate if the analysis does not mainly focus on estimating the evolutionary relationships between species (e.g. a tree is needed to estimate the parameters of codon-based models later on). Branch supports can be estimated using bootstrap and approximate likelihood ratios. \item {\em Single data set, restricted computing time.} The three tree searching options can be used depending on the computing time available and the size of the data set. For small data sets (i.e., $<$ 50 sequences), NNI will generally perform well provided that the phylogenetic signal is strong. It is relevant to estimate a first tree using NNI moves and examine the reconstructed phylogeny in order to have a rough idea of the strength of the phylogenetic signal (the presence of small internal branch lengths is generally considered as a sign of a weak phylogenetic signal, specially when sequences are short). For larger data sets ($>$ 50 sequences), a SPR search is recommended if there are good evidence of a lack of phylogenetic signal. Bootstrap analysis will generally involve large computational burdens. Estimating branch supports using approximate likelihood ratios therefore provides an interesting alternative here. \item {\em Multiple data sets, unlimited computing time.} Comparative genomic analyses sometimes rely on building phylogenies from the analysis of a large number of gene families. Here again, the NNI option is the most relevant if the focus is not on recovering the most accurate picture of the evolutionary relationships between species. Slower SPR-based heuristics should be used when the topology of the tree is an important parameter of the analysis (e.g., identification of horizontally transferred genes using phylogenetic tree comparisons). Internal branch support is generally not a crucial parameter of the multiple data set analyses. Using approximate likelihood ratio is probably the best choice here. \item {\em Multiple data sets, limited computing time.} The large amount of data to be processed in a limited time generally requires the use of the fastest tree searching and branch support estimation methods Hence, NNI and approximate likelihood ratios rather than SPR and non-parametric bootstrap are generally the most appropriate here. \end{enumerate} Another important point is the choice of the substitution model. While default options generally provide acceptable results, it is often warranted to perform a pre-analysis in order to identify the best-fit substitution model. This pre-analysis can be done using popular software such as Modeltest \cite{posada98} or ProtTest \cite{abascal05} for instance. These programs generally recommend the use of a discrete gamma distribution to model the substitution process as variability of rates among sites is a common feature of molecular evolution. The choice of the number of rate classes to use for this distribution is also an important one. While the default is set to four categories in PhyML, it is recommended to use larger number of classes if possible in order to best approximate the patterns of rate variation across sites \cite{galtier04}. Note however that run times are directly proportional to the number of classes of the discrete gamma distribution. Here again, a pre-analysis with the simplest model should help the user to determine the number of rate classes that represents the best trade-off between computing time and fit of the model to the data. \subsection{PhyTime}\label{sec:recomphytime} Analysing a data set using PhyTime should involve three steps based on the following questions: (1) do the priors seem to be adequate (2) can I use the fast approximation of the likelihood and (3) how long shall I run the program for? I explain below how to provide answers to these questions. \begin{itemize} \item {\em Are the priors adequate?} Bayesian analysis relies on specifiying the joint prior density of model parameters. In the case of node age estimation, these priors essentially describe how rates of substitution vary across lineages and the probabilistic distribution that node ages have when ignoring the information provided by the genetic sequences. These priors vary from tree to tree. It is therefore essential to check the adequacy of priors for each user-defined input tree. In order to do so, PhyTime needs to be run with the \x{--no\_data} option. When this option is required, the sequence data provided as input will be ignored and the rest of the analysis will proceed normally. The prior distribution of model parameters, essentially edge rates and node heights, can then be checked using the program Tracer as one would do for the standard `posterior' analysis. \item {\em Can I use the fast approximation to the likelihood?} The suface of the log-likelihood function can be approximated using a multivariate normal density. This technique is saving very substantial amounts of computation time. However, like most approximations, there are situations where it does not provide a good fit to the actual function. This usually happens when the phylogeny displays a lot of short branches, i.e., the signal conveyed by the sequences is weak. It is therefore important to first check whether using the approximate likelihood is reasonable. In order to do so, it is recommended to first run the program without the approximation, i.e., using the default settings. Once the minimum value of the ESS of node ages (the last column on the right of the standard output) has reached 40-50, open the \x{phytime.XXXX} output file with Tracer and examine the correlation between the exact and approximate likelihood values. If the correlation is deemed to be good enough, PhyTime can be re-run using the \x{--fast\_lk} option, which uses the fast normal approximation to the likelihood function. % Figure \ref{fig:approxbad} gives an example where the correlation is too weak and the approximation % of the likelihood should be avoided. Figure \ref{fig:approxbad} gives an example where the % approximation is good enough. The current execution of PhyTime can be terminated and then % re-launched using the \x{--fast\_lk} option. % \begin{figure} % \begin{center} % \resizebox{14cm}{8cm}{\includegraphics{./fig/approx_bad.eps}} % \caption{{\bf Exact vs. approximate likelihoods.} The correlation between the normally approximated % (Y-axis) and the exact (X-axis) likelihoods is weak here. The exact likelihood should be used (option \x{fastlk=no}).} % \label{fig:approxbad} % \end{center} % \end{figure} % \begin{figure} % \begin{center} % \resizebox{14cm}{8cm}{\includegraphics{./fig/approx_good.eps}} % \caption{{\bf Exact vs. approximate likelihoods.} The correlation between the normally approximated % (Y-axis) and the exact (X-axis) likelihoods is good. The approximation of the likelihood can be used (option \x{fastlk=yes}).} % \label{fig:approxgood} % \end{center} % \end{figure} \item {\em How long shall I run the program for?} PhyTime should be run long enough such that the ESS of each parameter is `large enough'. The last column on the right handside of the standard output gives the minimum ESS across all internal node heights. It is recommended to run the program so that this number reaches at least 100. \end{itemize} \section{Frequently asked questions} \begin{enumerate} \item {\it PhyML crashes before reading the sequences. What's wrong ?}\\ \begin{itemize} \item The format of your sequence file is not recognized by PhyML. See Section \ref{sec:input_output} \item The carriage return characters in your sequence files are not recognized by PhyML. You must make sure that your sequence file is a plain text file, with standard carriage return characters (i.e., corresponding to ``$\backslash$\x{n}'', or ``$\backslash$\x{r}'') \end{itemize} \item {\it The program crashes after reading the sequences. What's wrong ?}\\ \begin{itemize} \item You analyse protein sequences and did not enter the \x{-d aa} option in the command-line. \item The format of your sequence file is not recognized by PhyML. See Section \ref{sec:input_output} \end{itemize} \item {\it Does PhyML handle outgroup sequences ?}\\ \begin{itemize} \item Yes, it does. Outgroup taxa are identified by adding the `*' sign at the end of each corresponding sequence name (see Section \ref{sec:outgroupspecify}) \end{itemize} \item {\it Does PhyML estimate clock-constrained trees ?}\\ \begin{itemize} \item No, the PhyML program does not estimate clock-contrained trees. One can however use the program PhyTime to perform such analysis but the tree topology will not be estimated. \end{itemize} \item {\it Can PhyML analyse partitioned data, such as multiple gene sequences ?}\\ \begin{itemize} \item We are currently working on this topic. Future releases of the program will provide options to estimate trees from phylogenomic data sets, with the opportunity to use different substitution models on the different data partitions (e.g., different genes). PhyML will also include specific algorithms to search the space of tree topologies for this type of data. \end{itemize} \end{enumerate} \section{Acknowledgements} The development of PhyML since 2000 has been supported by the Centre National de la Recherche Scientifique (CNRS) and the Minist\`ere de l'\'Education Nationale. \bibliographystyle{/home/guindon/latex/biblio/nature/naturemag} \bibliography{/home/guindon/latex/biblio/ref} \printindex \end{document} phyml-3.2.0/doc/ref.bib000066400000000000000000005404161263450375500146700ustar00rootroot00000000000000 @article{tilman2011, title={Diversification, biotic interchange, and the universal trade-off hypothesis}, author={D. Tilman}, journal={The American Naturalist}, volume={178}, number={3}, pages={355--371}, year={2011}, publisher={JSTOR} } @article{gernhard08, title={The conditioned reconstructed process}, author={Gernhard, Tanja}, journal={Journal of Theoretical Biology}, volume={253}, number={4}, pages={769--778}, year={2008}, publisher={Elsevier} } @article{ayres12, title={BEAGLE: an application programming interface and high-performance computing library for statistical phylogenetics}, author={Ayres, Daniel L and Darling, Aaron and Zwickl, Derrick J and Beerli, Peter and Holder, Mark T and Lewis, Paul O and Huelsenbeck, John P and Ronquist, Fredrik and Swofford, David L and Cummings, Michael P and others}, journal={Systematic biology}, volume={61}, number={1}, pages={170--173}, year={2012}, publisher={Oxford University Press} } @article{ho11, title={Time-dependent rates of molecular evolution}, author={Ho, Simon YW and Lanfear, Robert and Bromham, Lindell and Phillips, Matthew J and Soubrier, Julien and Rodrigo, Allen G and Cooper, Alan}, journal={Molecular ecology}, volume={20}, number={15}, pages={3087--3101}, year={2011}, publisher={Wiley Online Library} } @article{fletcher10, title={The effect of insertions, deletions, and alignment errors on the branch-site test of positive selection}, author={Fletcher, William and Yang, Ziheng}, journal={Molecular Biology and Evolution}, volume={27}, number={10}, pages={2257--2267}, year={2010}, publisher={SMBE} } @article{degnan09, title={Gene tree discordance, phylogenetic inference and the multispecies coalescent}, author={Degnan, J.H. and Rosenberg, N.A.}, journal={Trends in Ecology \& Evolution}, volume={24}, number={6}, pages={332--340}, year={2009}, publisher={Elsevier} } @article{best, title={BEST: Bayesian estimation of species trees under the coalescent model}, author={Liu, L.}, journal={Bioinformatics}, volume={24}, number={21}, pages={2542--2543}, year={2008}, publisher={Oxford Univ Press} } @article{lg4x, title={Modeling protein evolution with several amino acid replacement matrices depending on site rates}, author={Le, Si Quang and Dang, Cuong Cao and Gascuel, Olivier}, journal={Molecular Biology and Evolution}, volume={29}, number={10}, pages={2921--2936}, year={2012}, publisher={SMBE} } @article{stem, title={STEM: species tree estimation using maximum likelihood for gene trees under coalescence}, author={Kubatko, L.S. and Carstens, B.C. and Knowles, L.L.}, journal={Bioinformatics}, volume={25}, number={7}, pages={971--973}, year={2009}, publisher={Oxford Univ Press} } @article{startbeast, title={Bayesian inference of species trees from multilocus data}, author={Heled, J. and Drummond, A.J.}, journal={Molecular Biology and Evolution}, volume={27}, number={3}, pages={570--580}, year={2010}, publisher={SMBE} } %% Created for guindon at 2009-04-21 13:11:50 +1200 @article{soubrier12, title={The influence of rate heterogeneity among sites on the time dependence of molecular rates}, author={Soubrier, J. and Steel, M. and Lee, M.S.Y. and Sarkissian, C.D. and Guindon, S. and Ho, S.Y.W. and Cooper, A.}, journal={Molecular Biology and Evolution}, year={2012}, publisher={SMBE} } %% Saved with string encoding Unicode (UTF-8) @article{matsen07, title={Phylogenetic mixtures on a single tree can mimic a tree of another topology}, author={Matsen, F.A. and Steel, M.}, journal={Systematic biology}, volume={56}, number={5}, pages={767--775}, year={2007}, publisher={Oxford University Press} } @book{bailey64, title={The elements of stochastic processes with applications to the natural sciences}, author={Bailey, Norman TJ}, publisher={Wiley}, year={1964} } @article{gillespie2011, title={Long-distance dispersal: a framework for hypothesis testing}, author={Gillespie, R.G. and Baldwin, B.G. and Waters, J.M. and Fraser, C.I. and Nikula, R. and Roderick, G.K.}, journal={Trends in ecology \& evolution}, year={2011}, vol=27, pages={47,56} } @article{guindon13, title={From trajectories to averages: an improved description of the heterogeneity of substitution rates along lineages.}, author={Guindon, S.}, journal={Systematic Biology}, year={2013}, volume={62}, pages={22-34}, publisher={Oxford University Press} } @article{arnold01, Author = {Barry C. Arnold and Enrique Castillo and Jose Maria Sarabia}, Title = {Conditionally Specified Distributions: An Introduction}, Journal = {Statistical Science}, Year = 2001, Volume = 16, Pages = {249,265} } @article{arnold07, Author = {Barry C. Arnold and Enrique Castillo and Jose Maria Sarabia}, Date-Added = {2009-04-21 13:08:07 +1200}, Date-Modified = {2009-04-21 13:11:32 +1200}, Journal = {Journal of Statistical Planning and Inference}, Pages = {3249-3260}, Read = {Yes}, Title = {Variations on the classical multivariate normal theme}, Volume = {137}, Year = {2007}, Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGBwpZJGFyY2hpdmVyWCR2ZXJzaW9uVCR0b3BYJG9iamVjdHNfEA9OU0tleWVkQXJjaGl2ZXISAAGGoNEICVRyb290gAGoCwwXGBkaHiVVJG51bGzTDQ4PEBMWWk5TLm9iamVjdHNXTlMua2V5c1YkY2xhc3OiERKABIAFohQVgAKAA4AHXHJlbGF0aXZlUGF0aFlhbGlhc0RhdGFfECcuLi8uLi9teV9saWJyYXJ5L2NvbmRpdGlvbmFsX25vcm1hbC5wZGbSGw8cHVdOUy5kYXRhTxEBmgAAAAABmgACAAAKSGFyZCBEcml2ZQAAAAAAAAAAAAAAAAAAAAAAwttWiEgrAAAALPmGFmNvbmRpdGlvbmFsX25vcm1hbC5wZGYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4bJbF7sAUUERGIAAAAAAAAgACAAAJIAAAAAAAAAAAAAAAAAAAAApteV9saWJyYXJ5ABAACAAAwtqtyAAAABEACAAAxe4JRAAAAAEADAAs+YYAK4iWAABLwwACADpIYXJkIERyaXZlOlVzZXJzOmd1aW5kb246bXlfbGlicmFyeTpjb25kaXRpb25hbF9ub3JtYWwucGRmAA4ALgAWAGMAbwBuAGQAaQB0AGkAbwBuAGEAbABfAG4AbwByAG0AYQBsAC4AcABkAGYADwAWAAoASABhAHIAZAAgAEQAcgBpAHYAZQASAC9Vc2Vycy9ndWluZG9uL215X2xpYnJhcnkvY29uZGl0aW9uYWxfbm9ybWFsLnBkZgAAEwABLwAAFQACAA7//wAAgAbSHyAhIlgkY2xhc3Nlc1okY2xhc3NuYW1loyIjJF1OU011dGFibGVEYXRhVk5TRGF0YVhOU09iamVjdNIfICYnoickXE5TRGljdGlvbmFyeQAIABEAGwAkACkAMgBEAEkATABRAFMAXABiAGkAdAB8AIMAhgCIAIoAjQCPAJEAkwCgAKoA1ADZAOECfwKBAoYCjwKaAp4CrAKzArwCwQLEAAAAAAAAAgEAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAtE=}} @article{boussau06, title={Efficient likelihood computations with nonreversible models of evolution}, author={Boussau, Bastien and Gouy, Manolo}, journal={Systematic biology}, volume={55}, number={5}, pages={756--768}, year={2006}, publisher={Oxford University Press} } @article{boussau08, Abstract = {Fossils of organisms dating from the origin and diversification of cellular life are scant and difficult to interpret, for this reason alternative means to investigate the ecology of the last universal common ancestor (LUCA) and of the ancestors of the three domains of life are of great scientific value. It was recently recognized that the effects of temperature on ancestral organisms left 'genetic footprints' that could be uncovered in extant genomes. Accordingly, analyses of resurrected proteins predicted that the bacterial ancestor was thermophilic and that Bacteria subsequently adapted to lower temperatures. As the archaeal ancestor is also thought to have been thermophilic, the LUCA was parsimoniously inferred as thermophilic too. However, an analysis of ribosomal RNAs supported the hypothesis of a non-hyperthermophilic LUCA. Here we show that both rRNA and protein sequences analysed with advanced, realistic models of molecular evolution provide independent support for two environmental-temperature-related phases during the evolutionary history of the tree of life. In the first period, thermotolerance increased from a mesophilic LUCA to thermophilic ancestors of Bacteria and of Archaea-Eukaryota; in the second period, it decreased. Therefore, the two lineages descending from the LUCA and leading to the ancestors of Bacteria and Archaea-Eukaryota convergently adapted to high temperatures, possibly in response to a climate change of the early Earth, and/or aided by the transition from an RNA genome in the LUCA to organisms with more thermostable DNA genomes. This analysis unifies apparently contradictory results into a coherent depiction of the evolution of an ecological trait over the entire tree of life.}, Address = {Laboratoire de Biometrie et Biologie Evolutive, CNRS, Universite de Lyon, Universite Lyon I, 43 Boulevard du 11 Novembre, 69622 Villeurbanne, France.}, Au = {Boussau, B and Blanquart, S and Necsulea, A and Lartillot, N and Gouy, M}, Author = {Boussau, Bastien and Blanquart, Samuel and Necsulea, Anamaria and Lartillot, Nicolas and Gouy, Manolo}, Crdt = {2008/11/28 09:00}, Da = {20081218}, Date-Added = {2009-01-30 16:18:39 +1300}, Date-Modified = {2009-01-30 16:18:57 +1300}, Dcom = {20090113}, Dep = {20081126}, Doi = {10.1038/nature07393}, Edat = {2008/11/28 09:00}, Issn = {1476-4687 (Electronic)}, Jid = {0410462}, Journal = {Nature}, Jt = {Nature}, Language = {eng}, Mh = {Adaptation, Physiological/genetics/*physiology; Archaea/genetics/*physiology; Evolution, Molecular; Genes, rRNA/genetics; *Hot Temperature; Phylogeny}, Mhda = {2009/01/14 09:00}, Number = {7224}, Own = {NLM}, Pages = {942--945}, Phst = {2008/03/05 {$[$}received{$]$}; 2008/09/01 {$[$}accepted{$]$}; 2008/11/26 {$[$}aheadofprint{$]$}}, Pii = {nature07393}, Pl = {England}, Pmid = {19037246}, Pst = {ppublish}, Pt = {Journal Article; Research Support, Non-U.S. Gov't}, Sb = {IM}, So = {Nature. 2008 Dec 18;456(7224):942-5. Epub 2008 Nov 26. }, Stat = {MEDLINE}, Title = {Parallel adaptations to high temperatures in the Archaean eon.}, Volume = {456}, Year = {2008 Dec 18}, Bdsk-Url-1 = {http://dx.doi.org/10.1038/nature07393}} @article{dereeper08, Abstract = {Phylogenetic analyses are central to many research areas in biology and typically involve the identification of homologous sequences, their multiple alignment, the phylogenetic reconstruction and the graphical representation of the inferred tree. The Phylogeny.fr platform transparently chains programs to automatically perform these tasks. It is primarily designed for biologists with no experience in phylogeny, but can also meet the needs of specialists; the first ones will find up-to-date tools chained in a phylogeny pipeline to analyze their data in a simple and robust way, while the specialists will be able to easily build and run sophisticated analyses. Phylogeny.fr offers three main modes. The 'One Click' mode targets non-specialists and provides a ready-to-use pipeline chaining programs with recognized accuracy and speed: MUSCLE for multiple alignment, PhyML for tree building, and TreeDyn for tree rendering. All parameters are set up to suit most studies, and users only have to provide their input sequences to obtain a ready-to-print tree. The 'Advanced' mode uses the same pipeline but allows the parameters of each program to be customized by users. The 'A la Carte' mode offers more flexibility and sophistication, as users can build their own pipeline by selecting and setting up the required steps from a large choice of tools to suit their specific needs. Prior to phylogenetic analysis, users can also collect neighbors of a query sequence by running BLAST on general or specialized databases. A guide tree then helps to select neighbor sequences to be used as input for the phylogeny pipeline. Phylogeny.fr is available at: http://www.phylogeny.fr/}, Author = {Dereeper A, Guignon V, Blanc G, Audic S, Buffet S, Chevenet F, Dufayard JF, Guindon S, Lefort V, Lescot M, Claverie JM, Gascuel O.}, Date-Added = {2009-01-19 17:02:10 +1300}, Date-Modified = {2009-01-19 17:03:31 +1300}, Journal = { Nucleic Acids Res.}, Title = {Phylogeny.fr: robust phylogenetic analysis for the non-specialist.}, Volume = {36}, Year = {2008}} @article{lartillot06, Author = {Nicolas Lartillot}, Date-Added = {2008-12-18 09:36:03 +1300}, Date-Modified = {2008-12-18 09:39:29 +1300}, Journal = {Journal of Computational Biology}, Pages = {1701-1722}, Rating = {5}, Title = {Conjugate Gibbs Sampling for Bayesian Phylogenetic Models }, Volume = {13}, Year = {2006}, Bdsk-File-1 = {YnBsaXN0MDDUAQIDBAUGBwpZJGFyY2hpdmVyWCR2ZXJzaW9uVCR0b3BYJG9iamVjdHNfEA9OU0tleWVkQXJjaGl2ZXISAAGGoNEICVRyb290gAGoCwwXGBkaHiVVJG51bGzTDQ4PEBMWWk5TLm9iamVjdHNXTlMua2V5c1YkY2xhc3OiERKABIAFohQVgAKAA4AHXHJlbGF0aXZlUGF0aFlhbGlhc0RhdGFfEC4uLi8uLi9teV9saWJyYXJ5L2xhcnRpbGxvdF9jb25qdWdhdGVfZ2liYnMucGRm0hsPHB1XTlMuZGF0YU8RAbYAAAAAAbYAAgAACkhhcmQgRHJpdmUAAAAAAAAAAAAAAAAAAAAAAMLbVohIKwAAACz5hh1sYXJ0aWxsb3RfY29uanVnYXRlX2dpYmJzLnBkZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALPmOxMsHU1BERiAAAAAAAAIAAgAACSAAAAAAAAAAAAAAAAAAAAAKbXlfbGlicmFyeQAQAAgAAMLarcgAAAARAAgAAMTKXpMAAAABAAwALPmGACuIlgAAS8MAAgBBSGFyZCBEcml2ZTpVc2VyczpndWluZG9uOm15X2xpYnJhcnk6bGFydGlsbG90X2Nvbmp1Z2F0ZV9naWJicy5wZGYAAA4APAAdAGwAYQByAHQAaQBsAGwAbwB0AF8AYwBvAG4AagB1AGcAYQB0AGUAXwBnAGkAYgBiAHMALgBwAGQAZgAPABYACgBIAGEAcgBkACAARAByAGkAdgBlABIANlVzZXJzL2d1aW5kb24vbXlfbGlicmFyeS9sYXJ0aWxsb3RfY29uanVnYXRlX2dpYmJzLnBkZgATAAEvAAAVAAIADv//AACABtIfICEiWCRjbGFzc2VzWiRjbGFzc25hbWWjIiMkXU5TTXV0YWJsZURhdGFWTlNEYXRhWE5TT2JqZWN00h8gJieiJyRcTlNEaWN0aW9uYXJ5AAgAEQAbACQAKQAyAEQASQBMAFEAUwBcAGIAaQB0AHwAgwCGAIgAigCNAI8AkQCTAKAAqgDbAOAA6AKiAqQCqQKyAr0CwQLPAtYC3wLkAucAAAAAAAACAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAC9A==}} @book{aarts97, Address = {Chichester}, Author = {E. Aarts and J. K. Lenstra}, Publisher = {Wiley}, Title = {Local search in combinatorial optimization}, Year = 1997} @article{abascal05, Author = {F. Abascal and R. Zardoya and D. Posada}, Journal = {Bioinformatics}, Pages = {2104-2105}, Title = {ProtTest: selection of best-fit models of protein evolution}, Volume = 21, Year = {2005}} @phdthesis{adachi95, Author = {J. Adachi}, School = {The Graduate University for Advanced Studies}, Title = {Modeling of Molecular Evolution and Maximum Likelihood Inference of Molecular Phylogeny}, Year = 1995} @article{akaike74, Author = {H. Akaike}, Journal = {IEEE Transactions on Automatic Control}, Pages = {716-723}, Title = {A new look at the statistical model identification}, Volume = 19, Year = {1974}} @article{amrine03, Author = {H. Amrine-Madsen and K Koepfli and R. Wayne and M. Springer}, Journal = {Molecular Phylogenetics and Evolution}, Pages = {225-240}, Title = {A new phylogenetic marker, apolipoprotein {B}, provides compelling evidence for eutherian relationships}, Volume = 28, Year = {2003}} @article{ane05, Author = {C. An\'e and J. Burleigh and M. McMahon and M. Sanderson}, Journal = {Molecular Biology and Evolution}, Pages = {914-924}, Title = {Covarion structure in plastid genome evolution: a new statistical test}, Volume = 22, Year = {2005}} @article{anisimova01, Author = {M. Anisimova and J. Bielawski and Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {1585-1592}, Title = {The accuracy and power of likelihood ratio tests to detect positive selection at amino acid sites}, Volume = 18, Year = {2001}} @article{anisimova02, Author = {M. Anisimova and J. Bielawski and Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {950-958}, Title = {Accuracy and power of Bayes prediction of amino acid under positive selection}, Volume = 19, Year = {2002}} @article{anisimova03, Author = {M. Anisimova and R. Nielsen and Z. Yang}, Journal = {Genetics}, Pages = {1229-1236}, Title = {Effect of recombination on the accuracy of the likelihood method for detecting positive selection at amino acid sites.}, Volume = 164, Year = {2003}} @article{anisimova06, Author = {M. Anisimova and O. Gascuel}, Journal = {Syst. Biol.}, Pages = {539-552}, Title = {Approximate likelihood-ratio test for branches: a fast, accurate, and powerful alternative}, Volume = 55, Year = {2006}} @article{anisimova07, title={Multiple hypothesis testing to detect lineages under positive selection that affects only a few sites}, author={Anisimova, Maria and Yang, Ziheng}, journal={Molecular Biology and Evolution}, volume={24}, number={5}, pages={1219--1228}, year={2007}, publisher={SMBE} } @article{anisimova11, title={Survey of branch support methods demonstrates accuracy, power, and robustness of fast likelihood-based approximation schemes}, author={Anisimova, M. and Gil, M. and Dufayard, J.F. and Dessimoz, C. and Gascuel, O.}, journal={Systematic biology}, volume={60}, number={5}, pages={685--699}, year={2011}, publisher={Oxford University Press} } @article{atv, Author = {C. Zmasek and S. Eddy}, Journal = {Bioinformatics}, Pages = {383-384}, Title = {{ATV}: display and manipulation of annotated phylogenetic trees}, Volume = 17, Year = 2001} @book{intro-algo, Author = {T. H. Cormen and C. E. Leiserson and R. L. Rivest}, Chapter = { 17 greedy algorithms}, Pages = {329-356}, Publisher = {The massachuset Institute of Technology Press}, Title = {Introduction to algorithms}, Year = 1992} @article{seqgen, Author = {A. Rambaut and N.C. Grassly}, Journal = {Computer Applications in the Biosciences (CABIOS)}, Pages = {235-238}, Title = {{S}eq-{G}en: an application for the {M}onte {C}arlo simulation of {DNA} sequence evolution along phylogenetic trees.}, Volume = 13, Year = 1997} @article{bailey02, Author = {J. Bailey and Z. Gu and R. Clark and K. Reinert and R. Samonte and S. Schwartz and M. Adams and E. Myers and P. Li and E. Eicher}, Journal = {Science}, Pages = {1003-1007}, Title = {Recent segmental duplications in the human genome}, Volume = 297, Year = 2002} @article{baele06, Author = {G. Baele and J. Raes and Y. Van de Peer and S. Vansteelandt}, Journal = {Molecular Biology and Evolution}, Pages = {1397-1405}, Title = {An improved statistical method for detecting heterotachy in nucleotide sequences}, Volume = 23, Year = 2006} @article{berry, Author = {V. Berry and O. Gascuel}, Journal = {Theoretical Computer Science ({\`a} paraitre)}, Title = {Inferring evolutionary trees with strong combinatorial confidence.}, Year = 2000} @article{kumar02, Author = {S. Kumar and S. Subramanian}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {803-808}, Title = {Mutation rates in mammalian genomes}, Volume = {99}, Year = {2002}} @article{kumar96, Author = {Sudhir Kumar}, Journal = {Molecular Biology and Evolution}, Title = {A Stepwise Algorithm for Finding Minimum Evolution Trees}, Year = 1996} @article{nei97, Author = {Masatoshi Nei, Sudhir Kumar, and Kei Takahashi}, Journal = {special series of inaugural articles by members of the national academy of science}, Pages = {584-593}, Title = {The optimization principle in phylogenetic analysis tends to give incorrect topologies when the number of nucleotides or amino acids is small}, Volume = 13, Year = 1997} @article{nei98, Author = {M. Nei and S. Kumar and K. Takahashi}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {12390-12397}, Title = {The optimization principle in phylogenetic analysis tends to give incorrect topologies when the number of nucleotides or amino acids used is small}, Volume = 95, Year = 1998} @inproceedings{abf96, Author = {R. Agarwala and V. Bafna and M. Farach and B. Narayanan and M. Paterson and M. Thorup}, Booktitle = {Proceedings of the 7th Annual ACM-SIAM Symposium on Discrete Algorithms}, Title = {On the approximability of numerical taxonomy: Fitting distances by tree metrics}, Year = 1996} @article{adell94, Author = {J. Adell and J. Dopazo}, Journal = {J. Mol. Evol}, Pages = {305-309}, Title = {{M}onte {C}arlo Simulation in phylogenies : An application to Test the Constancy of Evolutionary Rates}, Volume = 38, Year = 1994} @incollection{adachi96, Address = {Tokyo}, Author = {J. Adachi and M. Hasegawa}, Booktitle = {Computer Science Monographs}, Editor = {M. Ishiguro and G. Kitagawa and Y. Ogata and H. Takagi and Y. Tamura and T. Tsuchiya}, Number = {28}, Publisher = {The Institute of Statistical Mathematics}, Title = {{MOLPHY} Version 2.3. Programs for molecular phylogenetics based on maximum likelihood}, Year = 1996} @article{adachi00, Author = {J. Adachi and Waddell P. and W. Martin and M. Hasegawa}, Journal = {Journal of Molecular Evolution}, Pages = {348-358}, Title = {Plastid genome phylogeny and a model of amino acid substitution for proteins encoded by chloroplast {DNA}}, Volume = 50, Year = 2000} @article{almagor83, Author = {Hagai Almagor}, Journal = {Journal of theorical biology}, Note = {{I}nfluence du {V}oisinage sur l'{E}volution d'une {S{\'e}}quence d'{ADN}}, Pages = {633-645}, Title = { A Markov analysis of {DNA} sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 104, Year = 1983} @book{alon92, Address = {Chichester}, Author = {N. Alon and J.H. Spencer}, Publisher = {Wiley}, Title = {The Probabilistic Method}, Year = 1992} @dea{andrieu92, Address = {Montpellier}, Author = {Guillaume Andrieu}, School = {{E}cole {N}ationale {S}up{\'e}rieure {A}gronomique de {M}ontpellier}, Title = {{M}od{\`e}les {P}robabilistes de {C}onstruction des {A}rbres {P}hylog{\'e}n{\'e}tique}, Utilisateur = {Gilles Caraux}, Year = 1992} @phdthesis{andrieu97, Author = {G. Andrieu}, Month = {d{\'e}cembre}, School = {Univ. Montpellier II}, Title = {Estimation par intervalle d'une distance {\'e}volutive}, Year = 1997} @article{arisbrosou02, Author = {S. Aris-Brosou and Z. Yang}, Journal = {Systematic Biology}, Pages = {703-714}, Title = {Effects of models of rate evolution on estimation of divergence dates with special reference to the metazoan {18S} ribosomal {RNA} phylogeny}, Volume = 51, Year = 2002} @book{atlan, Address = {Petaouchnok}, Author = {Henri Atlan}, Publisher = {Herman}, Title = {L'organisation Biologique et la th{\'e}orie de l'information}, Year = 1992} @misc{atteson96, Author = {K. Atteson}, Howpublished = {DIMACS}, Month = {november}, Title = {Workshop on Mathematical Hierarchies and Biology}, Year = 1996} @incollection{atteson97, Author = {K. Atteson}, Booktitle = {Mathematical Hierarchies and Biology}, Editor = {B. Mirkin and F.R. McMorris and F.S. Roberts and A. Rhzetsky}, Pages = {133-148}, Publisher = {American Mathematical Society}, Title = {The performance of the {NJ} method of phylogeny reconstruction}, Year = 1997} @article{bailly03, Author = { X. Bailly and R. Leroy and S. Carney and O. Collin and F. Zal and A. Toulmond and D. Jollivet}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {5885-5890}, Title = {The loss of the hemoglobin \hbox{H$_2$S}-binding function in annelids from sulfide-free habitats reveals molecular adaptation driven by {D}arwinian positive selection}, Volume = 1000, Year = 2003} @article{bd86, Author = {H-J. Bandelt and A. Dress}, Journal = {Advances in Applied Mathematics}, Pages = {309-343}, Title = {Reconstructing the Shape of a Tree from Observed Dissimilarity Data}, Utilisateur = {Vincent}, Volume = 7, Year = 1986} @misc{bandelt90, Author = {H.-J. Bandelt and A. von Haeseler and A. Bolick and H. Sch{\"u}tte}, Howpublished = {preprint}, Title = {A comparative study of sequence dissimilarities and evolutionnary distances derived from sets of aligned RNA sequences}, Year = 1990} @article{bandelt92, Author = {H.-J. Bandelt and A. Dress}, Journal = {Advances Math}, Pages = {47-105}, Title = {A canonical decomposition theory for metrics on a finite set}, Volume = 92, Year = 1992} @article{bandelt92b, Author = {H.-J. Bandelt and A. Dress}, Journal = {Molecular Biology and Evolution}, Pages = {242-252}, Title = {Split Decomposition: A New and Useful Approach to Phylogenetic Analysis of Distance Data}, Volume = 1, Year = 1992} @article{barry87, Author = {Daniel Barry and J. A. Hartigan}, Journal = {Biometrics}, Pages = {261-276}, Title = {Asynchronous Distance Between Homologous {DNA} Sequences}, Volume = 43, Year = 1987} @article{barry872, Author = {Daniel Barry and J. A. Hartigan}, Journal = {Statistical Science}, Pages = {191-210}, Title = {Statistical Analysis of Homimoid Molecular Evolution}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 2, Year = 1987} @inproceedings{barthelemy84, Address = {La Grande-Motte}, Author = {J.-P. Barth{\'e}lemy and N.X. Luong}, Booktitle = {Colloque ASSU.}, Title = {Repr{\'e}sentations arbor{\'e}es de mesures de dissimilarit{\'e}}, Year = 1984} @book{barthelemy88, Author = {J.-P. Barth{\'e}lemy and Alain Gu{\'e}noche}, Publisher = {Masson}, Series = {{M}{\'e}thodes + {P}rogrammes}, Title = {Les arbres et les repr{\'e}sentations des proximit{\'e}s}, Year = 1988} @article{barth88, Author = {J. P. Barth{\'e}lemy}, Journal = {Journal of Classification}, Pages = {229-236}, Title = {Thresholded consensus for n-trees}, Utilisateur = {Gilles Caraux and Olivier Gascuel}, Volume = 5, Year = 1988} @article{bazykin04, Author = {G. Bazykin and F. Kondrashov and A. Ogurtsov and S. Sunyaev and A. Kondrashov}, Journal = {Nature}, Pages = {558-562}, Title = {Positive selection at sites of multiple amino acid replacements since rat-mouse divergence.}, Volume = 3, Year = 2004} @book{barthelemy91, Author = {J.P. Barth{\'e}lemy and A. Gu{\'e}noche}, Editor = {Chichester}, Publisher = {Wiley}, Title = {Trees and proximities representations}, Year = 1991} @article{benjamini95, Author = {Y. Benjamini and Y. Hochberg}, Journal = {Journal of the Royal Statistics Society: Series B (Statistical Methodology)}, Pages = {289-300}, Title = {Controlling the false discovery rate -- a practical and powerful approach to multiple testing}, Volume = {57}, Year = {1995}} @article{benjamini00, Author = {Y. Benjamini and Y. Hochberg}, Journal = {Journal of Educational and Behavioral Statistics}, Pages = {60-83}, Title = {The adaptive control of the false discovery rate in multiple hypothesis testing with independent statistics}, Volume = {25}, Year = {2000}} @article{benjamini01, Author = {Y. Benjamini and D. Yekutieli}, Journal = {Annals of Statistics}, Pages = {1165-1188}, Title = {The control of the false discovery rate in multiple testing under dependency}, Volume = {29}, Year = {2001}} @inbook{benzecri, Address = {Paris}, Author = {J. P. Benzecri}, Chapter = {TIB No 3}, Pages = {119-152}, Publisher = {Dunod}, Series = {L'analyse des donn{\'e}es}, Title = {Description math{\'e}matique des classifications}, Utilisateur = {Gilles Caraux}, Volume = {I~: La Taxinomie}, Year = 1973} @article{benzer61, Author = {S. Benzer}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {403-415}, Title = {On the topography of genetic fine structure}, Volume = 47, Year = 1961} @phdthesis{berrythese, Author = {V. Berry}, Month = {d{\'e}cembre}, School = {Univ. Montpellier II}, Title = {M{\'e}thodes et algorithmes pour reconstruire les arbres de l'{\'e}volution}, Year = 1997} @book{berge70, Author = {C. Berge}, Publisher = {Dunod}, Title = {Graphes et hypergraphes}, Year = 1970} @article{bertrand04, Author = {D. Bertrand and O. Gascuel}, Journal = {WABI}, Title = {Topological rearrangements and local search method for tandem duplication trees}, Year = 2004} @article{bertrand05, Author = {D. Bertrand and O. Gascuel}, Journal = {{IEEE} Transactions on computational biology and bioinformatics}, Title = {Topological rearrangements and local search method for tandem duplication trees}, Volume = {In press}, Year = 2005} @article{bg96_boot, Author = {V. Berry and O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {999-1011}, Title = {On the interpretation of Bootstrap trees: appropriate threshold of clade selection and induced gain}, Volume = 13, Year = 1996} @techreport{bg96_quad, Author = {V. Berry and O. Gascuel}, Institution = {LIRMM}, Month = {july}, Number = {96-044}, Title = {A quartet-based heuristics for phylogeny reconstruction}, Year = 1996} @inbook{bhattacharya, Address = {New York}, Author = {Rabi N. Bhattacharya and Edwards C. Waymire}, Chapter = { No IV Continuous-Parameter {M}arkov chains}, Pages = {261-366}, Publisher = {Wiley}, Title = {Stochastic processes with applications}, Utilisateur = {Guillaume Andrieu}, Year = 1990} @article{bielawski01, Author = {J. Bielawski and Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {523-529}, Title = {Positive and negative selection in the {\uppercase{\it{DAZ}}} gene family}, Volume = {18}, Year = 2001} @article{bielawski03, Author = {J. Bielawski and Z. Yang}, Journal = {Journal of Structural and Functional Genomics}, Pages = {201-212}, Title = {Maximum likelihood methods for detecting adaptive evolution after gene duplication}, Volume = {3}, Year = 2003} @article{bielawski04, Author = {J. Bielawski and Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {121-132}, Title = {A maximum likelihood method for detecting functional divergence at individual codon sites, with application to gene family evolution}, Volume = {59}, Year = 2004} @article{bishop85, Author = {M. J. Bishop and A. E. Friday}, Journal = {Proceeding of the Royal Society of London}, Pages = {271-302}, Title = {{E}volutionary trees from nucleic acid and protein sequences}, Utilisateur = {Guillaume Andrieu}, Volume = {B 226}, Year = 1985} @article{blaisdell85, Author = {B. Edwin Blaisdell}, Journal = {Journal of Molecular Evolution}, Note = {{I}nfluence du {V}oisinage sur l'{E}volution d'une {S{\'e}}quence d'{ADN}}, Pages = {278-288}, Title = {Markov chain analysis find a significant influence of neighboring bases on the occurence of a base in eucaryotic nuclear {DNA} sequences both protein-coding and noncoding}, Utilisateur = {Guillaume Andrieu}, Volume = 21, Year = 1985} @article{blaisdell91, Author = {Edwin Blaisdell}, Journal = {Journal of Molecular Evolution}, Pages = {521-528}, Title = {average values of a dissimilarity measure not requiring sequence alignment are twice the average of conventional mismatch counts requiring sequence alignment for a variety of computer-Generated model systems}, Utilisateur = {G. Andrieu}, Volume = 32, Year = 1991} @article{blake92, Author = {R.D. Blake and Samuel T. Hess and Janice Nicholson-Tuell}, Journal = {Journal of Molecular Evolution}, Note = {{I}nfluence du {V}oisinage sur l'{E}volution d'une {S{\'e}}quence d'{ADN}}, Pages = {189-200}, Title = {The Influence of Nearest Neighbors on the Rate and Pattern of Spontaneous Point Mutations}, Utilisateur = {Guillaume Andrieu}, Volume = 34, Year = 1992} @article{blanken82, Author = {Roger L. Blanken and Lynn C. Klotz and Alan G. Hinnebusch}, Journal = {Journal of Molecular Evolution}, Pages = {9-19}, Title = {Computer comparison of new and existing criteria for constructing evolutionary trees from sequence data}, Utilisateur = {Gilles Caraux}, Volume = 19, Year = 1982} @article{blast, Author = {S. Altschul and W. Gish and W. Miller and E. Myers and D. Lipman}, Journal = {Journal of Molecular Biology}, Pages = {403-410}, Title = {Basic local alignment search tool}, Volume = {215}, Year = {1990}} @article{bledsoe90, Author = {Anthony H. Bledsoe and Robert J. Raikow }, Journal = {Journal of Molecular Evolution}, Pages = {247-259}, Title = {A quantitative assessment of congruence between molecular and nonmolecular estimates of phylogeny}, Utilisateur = {G. Andrieu}, Volume = 30, Year = 1990} @article{brauer02, Author = { M.J. Brauer and M.T. Holder and L.A. Dries and D.J. Zwickl and P.O. Lewis and D.M. Hillis}, Journal = {Molecular Biology and Evolution}, Pages = {1717-1726}, Title = {Genetic algorithms and parallel processing in maximum-likelihood phylogeny inference}, Volume = 19, Year = 2002} @book{breiman84, Author = {L. Breiman and J.H. Friedman and A. Olshen and Stone C.J.}, Editor = {Belmont}, Publisher = {Wadsworth}, Title = {Classification and regression trees}, Year = 1984} @article{bremer88, Author = {K. Bremer}, Journal = {Evolution}, Note = {Donne une bonne facon de tester la robustesse d'un arbre infere par une meth de parcimonie : faire un arbre de consensus strict pr les arbres de valeur opt, puis un avec aussi ceux de val opt+1,... et noter a quelle etape disparait chq noeud}, Pages = {795-803}, Title = {The limits of amino acid sequence data in angiosperm phylogenetic reconstruction}, Utilisateur = {Vincent}, Volume = 42, Year = 1988} @book{brent73, Author = {R. Brent}, Chapter = {5}, Publisher = {Prentice-Hall}, Title = {Algorithms for minimization without derivatives}, Year = 1973} @article{brossier85, Author = {Gildas Brossier}, Journal = {Math. Sci. hum.}, Pages = {5-21}, Title = {Approximation des dissimilarit{\'e}s par des arbres additifs}, Utilisateur = {Gilles Caraux}, Volume = 91, Year = 1985} @article{brown99, Author = {K. S. Brown}, Journal = {Science}, Pages = {990-991}, Title = {Deep Green Rewrites Evolutionary History of Plants}, Volume = 285, Year = 1999} @article{bruno00, Author = {W. Bruno and N. Socci and A. Halpern}, Journal = {Molecular Biology and Evolution}, Pages = {189-197}, Title = {Weighted neighbor joining: a likelihood-based approach to distance-based phylogeny reconstruction}, Volume = 17, Year = 2000} @incollection{bryant05, Address = {Oxford}, Author = {D. Bryant and N. Galtier and M.-A. Poursat}, Booktitle = {Mathematics of Evolution \& Phylogenetics}, Editor = {O. Gascuel}, Pages = {33-62}, Publisher = {Oxford University Press}, Title = {Likelihood Calculations in Phylogenetics}, Year = 2005} @article{weighbor, Author = {W. Bruno and N. D. Socci and A. L. Halpern}, Journal = {Molecular Biology and Evolution}, Pages = {189-197}, Title = {Weighted Neighbor Joining: A Likelihood-based Approach to Distance-Based Phylogeny Reconstruction}, Volume = 17, Year = 2000} @article{buckley01, Author = {Thomas R. Buckley and Chris Simon and Geoffrey K. Chambers}, Journal = {Systematic Biology}, Pages = {67-86}, Title = {Exploring Among-Site Rate Variation Models in a Maximum Likelihood Framework Using Empirical Data: Effects of Model Assumptions on Estimates of Topology, Branch Lengths, and Bootstrap Support}, Volume = 50, Year = 2001} @article{buckley01b, Author = {Thomas R. Buckley and Chris Simon and Hidetoshi Shimodaira and Geoffrey K. Chambers}, Journal = {Molecular Biology and Evolution}, Pages = {223-234}, Title = {Evaluating Hypotheses on the Origin and Evolution of the New Zealand Alpine Cicadas (Maoricicada) Using Multiple-Comparison Tests of Tree Topology}, Volume = 18, Year = 2001} @article{bulmer91, Author = {Michael Bulmer}, Journal = {Molecular Biology and Evolution}, Pages = {868-883}, Title = {Use of the method of generalized least squares in reconstructing phylogenies from sequence data}, Volume = 8, Year = 1991} @inbook{buneman71, Author = {P. Buneman}, Chapter = {The recovery of trees from measures of dissimilarity}, Pages = {387-395}, Publisher = {Edhinburgh University Press}, Title = {Mathematics in Archeological and Historical Sciences}, Year = 1971} @article{buneman74, Author = {P. Buneman}, Journal = {J. of Comb. Theory}, Pages = {48-50}, Title = {A note on metric properties of trees}, Volume = 17, Year = 1974} @article{cao98, Author = {Y. Cao and A. Janke and P. Waddell and M. Westerman and O. Takenaka and S. Murata and N. Okada and S. Paabo and M. Hasegawa}, Journal = {Journal of Molecular Evolution}, Pages = {307-322}, Title = {Conflict among individual mitochondrial proteins in resolving the phylogeny of eutherian orders}, Volume = 47, Year = 1998} @article{carroll76, Author = {J. Douglas Carroll}, Journal = {Psychometrika}, Pages = {439-463}, Title = {Spatial, non-spatial and hybrid models for scaling}, Utilisateur = {Gilles Caraux}, Volume = 41, Year = 1976} @article{cavalli67, Author = {L. L. Cavalli-Sforza and A. W. F. Edwards}, Journal = {The American Journal of Human Genetics}, Pages = {233-257}, Title = {Phylogenetic analysis models and estimation procedures}, Volume = 19, Year = 1967} @article{cavender78, Author = {J. A. Cavender}, Journal = {Mathematical Biosciences}, Pages = {271-280}, Title = {Taxonomy with Confidence}, Utilisateur = {Guillaume Andrieu}, Volume = 40, Year = 1978} @article{cavender81, Author = {James A. Cavender}, Journal = {Mathematical Biosciences}, Pages = {217-229}, Title = {Tests of Phylogenetic Hypotheses under Generalized Models}, Utilisateur = {Guillaume Andrieu}, Volume = 54, Year = 1981} @article{chandon80, Author = {Jean Louis Chandon and J. Lemaire and J. Pouget}, Journal = {R.A.I.R.O. Recherche op{\'e}rationnelle}, Pages = {157-170}, Title = {Construction de l'ultram{\'e}trique la plus proche d'une dissimilarit{\'e} au sens des moindres carr{\'e}s}, Utilisateur = {Gilles Caraux}, Volume = 14, Year = 1980} @article{chor00, Author = {B. Chor and M. Hendy and B. Holland and D. Penny}, Journal = {Molecular Biology and Evolution}, Pages = {1529-1541}, Title = {Multiple maxima of likelihood in phylogenetic trees: an analytic approach}, Volume = 17, Year = 2000} @article{churchill92, Author = {Gary A. Churchill and Arndt von Haesler and William C. Navidi}, Journal = {Molecular Biology and Evolution}, Pages = {753-769}, Title = {Sample size for a phylogenetic inference }, Utilisateur = {Guillaume Andrieu}, Volume = 9, Year = 1992} @article{clark92, Author = {Andrew G. Clark and Thomas S. Whittam}, Journal = {Molecular Biology and Evolution}, Pages = {744-752}, Title = { Sequencing errors and molecular evolutionary analysis}, Utilisateur = {Guillaume Andrieu}, Volume = 9, Year = 1992} @article{clark03, Author = { A. Clark and S. Glanowski and R. Nielsen and P. Thomas and A. Kejariwal and M. Todd and D. Tanenbaum and D. Civello and F. Lu and B. Murphy and S. Ferriera and G. Wang and X. Zheng and T. White and J. Sninsky and M. Adams and M. Cargill}, Journal = {Science}, Pages = {1960-1963}, Title = {Inferring nonneutral evolution from human-chimp-mouse orthologous gene trios}, Volume = 302, Year = 2003} @inproceedings{cohen97, Author = {J. Cohen and M. Farach}, Booktitle = {Proceedings of the 8th Annual ACM-SIAM Symposium On Discrete Algorithms}, Title = {Numerical Taxonomy on Data: Experimental Results}, Year = 1997} @article{colless67, Author = {Donald H. Colless}, Journal = {Systematic Zoology}, Pages = {289-295}, Title = {The phylogenetic fallacy}, Utilisateur = {Gilles Caraux}, Volume = 16, Year = 1967} @article{colonius81, Author = {H. Colonius and H.H. Schulze}, Journal = {British Journal of Math. and Stat. Psychology}, Pages = {167-180}, Title = {Tree structures for proximity data}, Utilisateur = {Vincent}, Volume = 34, Year = 1981} @article{crandall99, Author = {K. Crandall and C. Kelsey and H. Imamichi and H. Lane and N. Salzman}, Journal = {Molecular Biology and Evolution}, Pages = {372-382}, Title = {Parallel evolution of drug resistance in {HIV} : failure of nonsynonymous/synonymous rate ratio to detect selection}, Volume = 16, Year = 1999} @article{curnow89, Author = {R. N. Curnow and T. B. L. Kirkwood}, Journal = {J. of the Royal Statistical Society}, Pages = {199-220}, Title = {Statistical analysis of Desoxyribonucleic Acid Sequence Data-A review}, Utilisateur = {Guillaume Andrieu}, Volume = 152, Year = 1989} @incollection{czelusniak90, Address = {New York}, Author = {John Czelusniak and Morris Goodman and Nancy D. Moncrieff and Suzanne M. Kehoe}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 37, Editor = {Russsell F. Doolittle}, Note = {{P}resente les meths de branch-swapping sur un arbre}, Pages = {601-615}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Maximum Parsimony Approach to Construction of Evolutionary Trees from Aligned Homologous Sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @book{darwin, Author = {C. Darwin}, Publisher = {John Murray}, Title = {On the origin of species}, Year = 1859} @article{daubin03, Author = {V. Daubin and G. Perri{\`e}re}, Journal = {Molecular Biology and Evolution}, Pages = {471-483}, Title = {{G+C3} structuring along the genome : a common feature in prokaryotes}, Volume = 20, Year = 2003} @article{day85, Author = {W.H. Day and F.R. McMorris}, Journal = {Bulletin of Math. Biol.}, Pages = {215-229}, Title = {A formalization of consensus index methods}, Volume = 47, Year = 1985} @incollection{day87, Author = {W. H. E. Day}, Booktitle = {Bulletin of Mathematical Biology}, Pages = {461-467}, Title = {Computational Complexity of Inferring Phylogenies from Dissimilarity Matrices}, Volume = 49, Year = 1987} @incollection{dayhoff78, Address = {Washington, D. C.}, Author = {M. Dayhoff and R. Schwartz and B. Orcutt}, Booktitle = {Atlas of Protein Sequence and Structure}, Editor = {M. Dayhoff}, Pages = {345-352}, Publisher = {National Biomedical Research Foundation}, Title = {A model of evolutionary change in proteins}, Volume = 5, Year = 1978} @incollection{debry92, Author = {R. W. DeBry}, Booktitle = {Molecular Biology and Evolution}, Pages = {537-551}, Title = {The Consistency of Several Phylogeny-Inference Methods under Varying Evolutionary Rates}, Volume = 9, Year = 1992} @incollection{degens83, Address = {Berlin Heidelberg}, Author = {Paul O. Degens}, Booktitle = {Numerical Taxonomy}, Editor = {Joseph Felsenstein}, Pages = {249-253}, Publisher = {Springer-Verlag}, Series = {NATO ASI}, Title = {Hierarchical cluster methods as maximum likelihood estimators}, Utilisateur = {Gilles Caraux}, Volume = {G1}, Year = 1983} @article{delsuc02, Author = {F. Delsuc and M. Scally and O. Madsen and M. Stanhope and W. de Jong and F. Catzeflis and M. Springer and E. Douzery}, Journal = {Molecular Biology and Evolution}, Pages = {1656-1671}, Title = {Molecular phylogeny of living xenarthrans and the impact of character and taxon sampling on the placental tree rooting}, Volume = {19}, Year = {2002}} @article{delsuc05, Author = {F. Delsuc and H. Brinkmann and H. Philippe}, Journal = {Nature Review Genetics}, Pages = {361-375}, Title = {Phylogenomics and the reconstruction of the tree of life}, Volume = {6}, Year = {2005}} @article{dempster77, Author = {A. P. Dempster and N. M. Laird and D. B. Rubin}, Journal = {J. R. Statist. Soc. B}, Pages = {1-22}, Title = {Maximum Likelihood from incomplete data via the \hbox{\it EM} algorithm}, Utilisateur = {Gilles Caraux et Guillaume Andrieu}, Volume = 39, Year = 1977} @article{denis02, Author = {F. Denis and O. Gascuel}, Journal = {Discrete Applied Mathematics}, Title = {On the consistency of the minimum evolution principle of phylogenetic inference}, Year = 2002} @article{derchia96, Author = {A.M. D'Erchia and C. Gissi and G. Pesole and C. Saccone and U. Arnason}, Journal = {Nature}, Pages = {597-600}, Title = {The guinea-pig is not a rodent}, Volume = 381, Year = 1996} @article{desoete83, Author = {Geert de Soete}, Commentaire = {Ceci est mon commentaire}, Journal = {Psychometrika}, Pages = {621-626}, Title = {A least squares algorithm for fitting additive trees to proximity data}, Utilisateur = {Gilles Caraux}, Volume = 48, Year = 1983} @article{desper02, Author = {R. Desper and O. Gascuel}, Journal = {Journal of Computational Biology}, Pages = {687-705}, Title = {Fast and accurate phylogeny reconstruction algorithms based on the minimum-evolution principle}, Volume = 9, Year = 2002} @article{dickerson71, Author = {Richard Dickerson}, Journal = {Journal of Molecular Evolution}, Pages = {26-45}, Title = {The structure of cytochrome $c$ and the rates of molecular evolution}, Utilisateur = {Gilles Caraux}, Volume = 1, Year = 1971} @article{dimmic02, Author = {M. Dimmic and J. Rest and D. Mindell and D. Goldstein}, Journal = {Journal of Molecular Evolution}, Pages = {65-73}, Title = {{rtREV}: an amino acid substitution matrix for inference of retrovirus and reverse transcriptase phylogeny}, Volume = 55, Year = 2002} @incollection{dobson75, Address = {Berlin}, Author = {Annette J. Dobson}, Booktitle = {Combinatorial Mathematics III}, Editor = {A. Dold and B. Eckmann}, Pages = {95-100}, Publisher = {Springer}, Series = {Lecture Notes in Mathematics}, Title = {Comparing the shapes of trees}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 452, Year = 1975} @incollection{doolittle90, Author = {Russel F. Doolittle and Da-Fei Feng}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 41, Editor = {Russsell F. Doolittle}, Pages = {659-669}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Nearset Neighbor Procedure for relating Progressively Amino Acid Sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{dopazo94, Author = {Joaquin Dopazo}, Journal = {Journal of Molecular Evolution}, Pages = {300-304}, Title = {Estimating Errors and Confidence Intervals for Branch Lengths in Phylogenetic Trees by a Bootstrap Approach}, Utilisateur = {Guillaume Andrieu}, Volume = 38, Year = 1994} @article{douady03, Author = {C. J. Douady and F. Delsuc and Y. Boucher and W. F. Doolittle and E. J. P. Douzery }, Journal = {Molecular Biology and Evolution}, Pages = {248-254}, Title = {Comparison of Bayesian and Maximum Likelihood Bootstrap Measures of Phylogenetic Reliability}, Volume = 20, Year = 2003} @article{douzery03, Author = {E. Douzery and F. Delsuc and M. Stanhope and D. Huchon}, Journal = {Journal of Molecular Evolution}, Pages = {S201-13}, Title = {Local molecular clocks in three nuclear genes: divergence times for rodents and other mammals and incompatibility among fossil calibrations}, Volume = {57 Suppl 1}, Year = 2003} @Article{douzery04, Author="Douzery, E. J. and Snell, E. A. and Bapteste, E. and Delsuc, F. and Philippe, H. ", Title="{{T}he timing of eukaryotic evolution: does a relaxed molecular clock reconcile proteins and fossils?}", Journal="Proc. Natl. Acad. Sci. U.S.A.", Year="2004", Volume="101", Pages="15386--15391", Month="Oct" } @article{dress86, Author = {A. Dress and A. von Haeseler and M. Krueger}, Journal = {Studien zur Klassifikation}, Pages = {299-305}, Title = {Reconstructing phylogenetic trees using variants of the "four-point condition"}, Year = 1986} @article{drummond03, Author = {A. Drummond and O. Pybus and A. Rambaut and R. Forsberg and A. Rodrigo}, Journal = {Trends in Ecology and Evolution}, Pages = {481-488}, Title = {Measurably evolving populations}, Volume = 18, Year = 2003} @article{drummond06, Author = {A. Drummond and S. Ho and M. Phillips and A. Rambaut}, Journal = {PLoS Biology}, Pages = {e88}, Title = {Relaxed phylogenetics and dating with confidence}, Volume = 4, Year = 2006} @Article{drummond07, Author="Drummond, A. J. and Rambaut, A. ", Title="{{B}{E}{A}{S}{T}: {B}ayesian evolutionary analysis by sampling trees}", Journal="BMC Evol. Biol.", Year="2007", Volume="7", Pages="214" } @article{dudoit02, Author = {S. Dudoit and J. Popper Shaffer and J. Boldrick}, Journal = {U.C. Berkeley Division of Biostatistics Working Paper Series}, Pages = {http://www.bepress.com/ucbbiostat/paper110}, Title = {Multiple Hypothesis Testing in Microarray Experiments}, Year = 2002} @article{edgar04, author={R. Edgar}, title={{MUSCLE}: multiple sequence alignment with high accuracy and high throughput}, journal={Nucleic Acids Research}, year={2004}, volume={32}, pages={1792-1797} } @article{edwards63, Author = {A. W. F. Edwards and L. L. Cavalli-Sforza}, Journal = {Ann. Hum. Genet.}, Pages = {104-105}, Title = {The reconstruction of evolution}, Volume = 27, Year = 1963} @article{edwards64, Author = {A. W. F. Edwards and L. L. Cavalli-Sforza}, Journal = {Systematics Association Publication.}, Pages = {67-76}, Title = {Reconstruction of evolutionary trees}, Volume = 6, Year = 1964} @book{edwards72, Address = {Cambridge, England}, Author = {A. W. F. Edwards}, Publisher = {University Press}, Title = {Likelihood}, Year = 1972} @article{efron79, Author = {B. Efron}, Journal = {Ann. Statistics}, Pages = {1-26}, Title = {Bootstrap methods: another look at the jackknife}, Volume = 7, Year = 1979} @article{efron85, Author = {B. Efron}, Journal = {Biometrika}, Pages = {45-58}, Title = {Bootstrap confidence intervals for a class of parametric problems}, Volume = 72, Year = 1985} @article{efron87, Author = {Bradley Efron}, Journal = {Journal of the american statistical association}, Month = {March}, Number = 397, Pages = {171-185}, Title = {Better bootstrap confidence intervals}, Volume = 82, Year = 1987} @book{efron93, Author = {Bradley Efron and Robert J. Tibshirani}, Publisher = {Chapman et Hall}, Title = {An {I}ntroduction to the {B}ootstrap}, Utilisateur = {Susan Holmes}, Year = 1993} @techreport{efron95, Author = {B. Efron and E. Halloran and S. Holmes}, Institution = {Standford University}, Number = {Tech. Rep. 179}, Title = {Bootstrap confidence levels for phylogenetic trees}, Year = 1995} @article{efron96, Author = {B. Efron and E. Halloran and S. Holmes}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {7085-7090}, Title = {Bootstrap confidence levels for phylogenetic trees}, Volume = 93, Year = 1996} @article{eigen81, Author = {M. Eigen and R. Winkler-Oswatitsch}, Journal = {Die Naturwissenschaften}, Pages = {217-228}, Title = {Transfer-{\sc RNA} : The Early Adaptor}, Utilisateur = {Guillaume Andrieu}, Volume = 68, Year = 1981} @article{eigen88, Author = {M. Eigen and R. Winkler-Oswatitsch and A. Dress}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {5913-5917}, Title = {Statistical Geometry in Sequence Space : A Method of Quantitative Comparative Sequence Analysis }, Volume = 85, Year = 1988} @incollection{eigen90a, Author = {Manfred Eigen and Ruthild Winkler-Oswatitsch}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 32, Editor = {Russsell F. Doolittle}, Pages = {505-530}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Statistical Geometry on Sequence Space}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{eigen90b, Author = {Manfred Eigen and Katja Nieselt-Struwe}, Journal = {AIDS}, Pages = {585-593}, Title = {How old is the Immunodeficiency Virus~?}, Utilisateur = {Guillaume Andrieu}, Volume = {4(suppl1)}, Year = 1990} @article{elemento02, Author = {O. Elemento and O. Gascuel and M.-P. Lefranc }, Journal = {Molecular Biology and Evolution}, Pages = {278-288}, Title = {Reconstructing the duplication history of tandemly repeated genes}, Volume = {19}, Year = 2002} @article{erchia96, Author = {A.M. d'Erchia and C. Gissi and G. Pesole and C. Saccone and U. Arnason}, Journal = {Nature}, Pages = {597-600}, Title = {The guinea-pig is not a rodent}, Volume = 381, Year = 1996} @article{estabrook72, Author = {G.F. Estabrook}, Journal = {Ann. Rev. Ecol. Syst.}, Pages = {427-456}, Title = {Cladistic methodology: a discussion of the theoretical basis for the induction of evolutionary history}, Volume = 3, Year = 1972} @article{estabrook76, Author = {G.F. Estabrook and C.S. Johnson and F.R. McMorris}, Journal = {Mathematical Biosciences}, Pages = {181-187}, Title = {A mathematical foundation for the analysis of cladistic character compatibility}, Volume = 29, Year = 1976} @inproceedings{fk96, Author = {M. Farach and S. Kannan}, Booktitle = {Proceedings of the 28th Annual ACM Symposium on the Theory of Computing}, Pages = {230-235}, Title = {Efficient algorithms for inverting evolution}, Year = 1996} @article{farris71, Author = {James S. Farris}, Journal = {Annual Review of Ecology and Systematics}, Pages = {277-302}, Title = {The hypothesis of nonspecificity and taxonomic congruence}, Utilisateur = {Gilles Caraux}, Volume = 22, Year = 1971} @article{farris73a, Author = {James S. Farris}, Journal = {Systematic Zoology}, Pages = {250-256}, Title = {A Probability Model for Inferring Evolutionary Trees}, Utilisateur = {Guillaume Andrieu}, Volume = 22, Year = 1973} @article{farris73b, Author = {James S. Farris}, Journal = {American Naturalist}, Pages = {531-534}, Title = {Estimation of Amino-Acid Substitution when Back Mutation can occur}, Utilisateur = {Guillaume Andrieu}, Volume = 107, Year = 1973} @article{felsenstein73a, Author = {J. Felsenstein}, Journal = {The American Journal of Human Genetics}, Pages = {471-492}, Title = {Maximum-likelihood estimation of evolutionary trees from continuous characters}, Utilisateur = {Gilles Caraux}, Volume = 25, Year = 1973} @article{felsenstein73b, Author = {J. Felsenstein}, Journal = {Systematic Zoology}, Pages = {240-249}, Title = {Maximum Likelihood and Minimum Steps Methods for Estimating Evolutionnary Trees from Data on Discrete Characters}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 23, Year = 1973} @article{felsenstein78, Author = {J. Felsenstein}, Journal = {Systematic Zoology}, Pages = {401-410}, Title = {Cases in which parsimony and compatibility methods will be positively misleading}, Volume = 27, Year = 1978} @article{felsenstein81a, Author = {J. Felsenstein}, Journal = {Journal of Molecular Evolution}, Pages = {368-376}, Title = {Evolutionary Trees from {DNA} Sequences: a Maximum Likelihood Approach}, Volume = 17, Year = 1981} @article{felsenstein81b, Author = {J. Felsenstein}, Journal = {Evolution}, Note = {({\it construction d'arbrtes par le maximum de vraisemblance})}, Number = 6, Pages = {1229-1242}, Title = {Evolutionary Trees from gene frequencies and quantitative characteres : finding maximum likelihood estimates}, Volume = 35, Year = 1981} @article{felsenstein83, Author = {J. Felsenstein}, Journal = {J. R. Statist. Soc. A}, Number = {Part 3}, Pages = {246-272}, Title = {Statistical Inference of Phylogenies}, Volume = 146, Year = 1983} @article{felsenstein84, Author = {J. Felsenstein}, Journal = {Evolution}, Number = 1, Pages = {16-24}, Title = {Distance methods for inferring phylogenies : a justification}, Utilisateur = {Gilles Caraux}, Volume = 38, Year = 1984} @article{felsenstein85a, Author = {J. Felsenstein}, Journal = {Evolution}, Pages = {783-791}, Title = {Confidence limits on phylogenies: an approach using the bootstrap}, Volume = 39, Year = 1985} @article{felsenstein85b, Author = {J. Felsenstein}, Journal = {Systematic Zoology}, Pages = {27-33}, Title = {The number of evolutionary trees}, Utilisateur = {Gilles Caraux}, Volume = 34, Year = 1985} @article{felsenstein85c, Author = {J. Felsenstein}, Journal = {Systematic Zoology}, Number = 2, Pages = {152-161}, Title = {Confidence limits on phylogenies with a molecular clock}, Utilisateur = {Gilles Caraux}, Volume = 34, Year = 1985} @article{felsenstein87, Author = {J. Felsenstein}, Journal = {Journal of Molecular Evolution}, Pages = {123-131}, Title = { Estimation of Hominoid Phylogeny from a {DNA} Hybridation Data Set}, Utilisateur = {Guillaume Andrieu}, Volume = 26, Year = 1987} @article{felsenstein88, Author = {J. Felsenstein}, Journal = {Annual Review of Genetics}, Pages = {521-565}, Title = {Phylogenies from molecular sequences: inference and reliability}, Volume = 22, Year = 1988} @book{felsensteinbook, Address = {Sunderland, MA}, Author = {J. Felsenstein}, Publisher = {Sinauer Associates, Inc.}, Title = {Inferring phylogenies}, Year = 2003} @article{phylip1, Author = {J. Felsenstein}, Journal = {Cladistics}, Pages = {164-166}, Title = {Phylogeny Inference Package (Version 3.2)}, Volume = {5}, Year = {1989}} @book{phylip2, Address = {Department of Genetics, University of Washington, Seattle}, Author = {J. Felsenstein}, Publisher = {Distributed by the author}, Title = {PHYLIP ({PHYL}ogeny {I}nference {P}ackage) version 3.6a2}, Year = {1993}} @article{gaucher01, Author = {E. Gaucher and M. Miyamoto and S. Benner}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {548-552}, Title = {Function-structure analysis of proteins using covarion-based evolutionary approaches: {E}longation factors}, Volume = 98, Year = 2001} @ARTICLE{gouy09, author = { Manolo Gouy and Stephane Guindon and Olivier Gascuel}, title = {Sea{V}iew version 4: {A} multiplatform graphical user interface for sequence alignment and phylogenetic tree building.}, journal = {Mol Biol Evol}, year = {2010}, volume = {27}, number = {2}, pages = {221-4} } @article{haydon01, Author = {D. Haydon and A. Bastos and N. Knowles and A. Samuel}, Journal = {Genetics}, Pages = {7-15}, Title = {Evidence for Positive Selection in Foot-and-Mouth Disease Virus Capsid Genes From Field Isolates}, Volume = 157, Year = 2001} @article{henikoff92, Author = {S. Henikoff and J. Henikoff}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {10915-10919}, Title = {Amino acid substitution matrices from protein blocks.}, Volume = 89, Year = 1992} @article{hordijk05, Author = {W. Hordijk and O. Gascuel}, Journal = {Bioinformatics}, Pages = {4338-4347}, Title = {Improving the efficiency of {SPR} moves in phylogenetic tree search methods based on maximum likelihood.}, Volume = 21, Year = 2005} @article{huelsenbeck00, Author = {J. Huelsenbeck and B. Larget and D. Swofford}, Journal = {Genetics}, Pages = {1879-1892}, Title = {A compound {P}oisson process for relaxing the molecular clock}, Volume = 154, Year = 2000} @article{kuhner94, Author = {M. Kuhner and J. Felsenstein}, Journal = {Molecular Biology and Evolution}, Pages = {459-468}, Title = {A Simulation Comparison of Phylogeny Algorithms under Equal and Unequal Evolutionary Rates}, Volume = 11, Year = 1994} @article{felsenstein96, Author = {J. Felsenstein and G.A. Churchill}, Journal = {Molecular Biology and Evolution}, Pages = {93-104}, Title = {A Hidden {M}arkov Model approach to variation among sites in rate of evolution}, Volume = 13, Year = 1996} @incollection{feng90, Address = {New-York}, Author = {Da-Fei Feng and Russel F. Doolittle}, Booktitle = {Progressive alignement and phylogenetic tree construction of protein sequences}, Chapter = 23, Editor = {Russsell F. Doolittle}, Pages = {375-387}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Nearset Neighbor Procedure for relating Progressively Amino Acid Sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{fitch67, Author = {W. M. Fitch and E. Margoliash}, Journal = {Science}, Pages = {279-284}, Title = {Construction of phylogenetic trees}, Volume = 155, Year = 1967} @article{fitch71, Author = {Walter M. Fitch}, Journal = {Systematic Zoology}, Title = {Toward defining the course of evolution : minimum change for a specific tree topology}, Year = 1971} @inproceedings{fitch75, Author = {W.M. Fitch}, Booktitle = {Proceedings of the 8th International Conference on Numerical Taxonomy}, Pages = {189-230}, Title = {Towards finding the tree of Maximum Parsimony}, Year = 1975} @article{fitch81, Author = {W. M. Fitch}, Journal = {Journal of Molecular Evolution}, Pages = {30-37}, Title = {A non-sequential method for constructing trees and hierarchical classifications}, Volume = 18, Year = 1981} @article{fitchfarris74, Author = {Walter M. Fitch and James S. Farris}, Journal = {Journal of Molecular Evolution}, Note = {etendent la meth de Fitch71 pr les acides amines, car il y a pr ce type de data qq ambiguites.}, Pages = {263-278}, Title = {Evolutionary trees with minimum nucleotide replacements form amino acid sequences}, Utilisateur = {Vincent}, Volume = 3, Year = 1974} @article{forsberg03, Author = {R. Forsberg and F. Christiansen}, Journal = {Molecular Biology and Evolution}, Pages = {1252-1259}, Title = {A codon-based model of host-specific selection in parasites with an application to the {I}nfluenza {A} virus}, Volume = 20, Year = 2003} @article{foulds84, Author = {L.R. Foulds}, Journal = {Journal of Theoretical Biology}, Pages = {471-474}, Title = {Maximum Savings in the Steiner Problem in Phylogeny}, Volume = 107, Year = 1984} @article{frommel85, Author = {C. Fr\H{o}mmel and H. G. Holzh\H{u}tter}, Journal = {Journal of Molecular Evolution}, Pages = {233-257}, Title = {an estimate on the effect of point mutation and natural selection on the rate of amino acid replacement in proteins }, Utilisateur = {Guillaume Andrieu}, Volume = 21, Year = 1985} @article{fukami89, Author = {K. Fukami and Y. Tateno}, Journal = {Journal of Molecular Evolution}, Pages = {460-464}, Title = {On the maximum likelihood method for estimating molecular trees : uniquesness of the likelihood point}, Utilisateur = {Gilles Caraux}, Volume = 28, Year = 1989} @phdthesis{galtierthese, Author = {N. Galtier}, Month = {novembre}, School = {Universit{\'e} Claude Bernard - Lyon I}, Title = {L'approche statistique en phylog{\'e}nie mol{\'e}culaire~: influence des composition en bases variables}, Year = 1997} @article{galtier01, Author = {N. Galtier}, Journal = {Molecular Biology and Evolution}, Pages = {866-873}, Title = {Maximum-likelihood phylogenetic analysis under a covarion-like model}, Volume = 18, Year = 2001} @article{galtier99, Author = {N. Galtier and N. Tourasse and M. Gouy}, Journal = {Science}, Pages = {220-221}, Title = {A nonhyperthermophilic common ancestor to extant life forms}, Volume = 283, Year = 1999} @article{galtier98, Author = {N. Galtier and M. Gouy}, Journal = {Molecular Biology and Evolution}, Pages = {871-879}, Title = {Inferring pattern and process: maximum-likelihood implementation of a nonhomogeneous model of {DNA} sequence evolution for phylogenetic analysis}, Volume = 15, Year = 1998} @article{galtier95, Author = {N. Galtier and M. Gouy}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {11317-11321}, Title = {Inferring phylogenies from {DNA} sequences of unequal base compositions}, Volume = 92, Year = 1995} @article{galtier04, Author = {N. Galtier and A. Jean-Marie}, Journal = {Journal of Computational Biology}, Pages = {727-733}, Title = {Markov-modulated {M}arkov chains and the covarion process of molecular evolution}, Volume = 11, Year = 2004} @book{gamerman06, Author = {Dani Gamerman and Hedibert F. Lopes }, Isbn = {1584885874}, Publisher = {Chapman and Hall/CRC}, Title = {Markov Chain Monte Carlo: Stochastic Simulation for Bayesian Inference}, Year = {2006}} @book{gareyjohnson, Address = {San Fransisco}, Author = {M. Garey and D. Johnson}, Publisher = {Freeman}, Title = {{C}omputers and {I}ntractability - {A} guide to the {T}heory of {NP}-{C}ompleteness}, Year = 1979} @article{gascuel92, Author = {O. Gascuel and G. Caraux}, Journal = {Pattern Recognition letters}, Note = {({\it Estimation d'une probab {\`a} partir d'une fr{\'e}quence}) }, Pages = {757-764}, Title = {{D}istribution-free performance bounds with the resubstitution error estimate}, Volume = {13}, Year = {1992}} @article{gascuel94, Author = {O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {961-963}, Title = {A Note on {S}attah and {T}versky's, {S}aitou and {N}ei's, and {S}tudier and {K}eppler's Algorithms for Inferring Phylogenies from Evolutionary Distances}, Volume = {11}, Year = {1994}} @article{gascuel96, Author = {O. Gascuel and D. Levy}, Journal = {J. of Classification}, Title = {A reduction for approximating a (non-metric) dissimilarity by a tree distance}, Year = 1996} @article{gascuelNJ, Author = {O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {685-695}, Title = {{B}IO{NJ}: an Improved Version of the {NJ} Algorithm Based on a Simple Model of Sequence Data}, Volume = {14}, Year = 1997} @article{gascuel00, Author = {O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {401-405}, Title = {On the optimization principle in phylogenetic analysis and the minimum-evolution criterion}, Volume = 17, Year = 2000} @article{gascuel01, Author = {O. Gascuel and D. Bryant and F. Denis}, Journal = {Systematic Biology}, Pages = {621-627}, Title = {Strengths and limitations of the minimum evolution principle}, Volume = {50}, Year = 2001} @article{gascuel03, Author = {O. Gascuel and M. Hendy and A. Jean-Marie and R. McLachlan}, Journal = {Systematic Biology}, Pages = {110-118}, Title = {The combinatorics of tandem duplication trees}, Volume = {52}, Year = {2003}} @incollection{gascuel97, Address = {Providence, USA}, Author = {O. Gascuel}, Booktitle = {Mathematical Hierarchies and Biology}, Editor = {B. Mirkin and F.R. McMorris and F.S. Roberts and A. Rzhetsky}, Pages = {149-170}, Publisher = {Am. Math. Society}, Title = {Concerning the {NJ} algorithm and its unweighted version {UNJ}}, Year = 1997} @incollection{gascuel05, Address = {Oxford}, Author = {O. Gascuel and D. Bertrand and O. Elemento}, Booktitle = {Mathematics of evolution and phylogeny}, Editor = {O. Gascuel}, Pages = {205-235}, Publisher = {Clarendon press}, Title = {Reconstructing the duplication history of tandemly repeated sequences}, Year = 2005} @Article{gaut92, Author="Gaut, B. S. and Muse, S. V. and Clark, W. D. and Clegg, M. T. ", Title="{{R}elative rates of nucleotide substitution at the rbc{L} locus of monocotyledonous plants}", Journal="J. Mol. Evol.", Year="1992", Volume="35", Pages="292--303", Month="Oct" } @article{gaut95, Author = {B.S. Gaut and P.O. Lewis}, Journal = {Molecular Biology and Evolution}, Pages = {152-162}, Title = {Success of maximum likelihood phylogeny inference in the four-taxon case}, Volume = 12, Year = 1995} @book{gill81, Address = {London}, Author = {P. Gill and W. Murray and M. Wright}, Publisher = {Academic Press}, Title = {Practical optimization}, Year = 1981} @article{geman84, author = {Geman, Stuart and Geman, Donald}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, keywords = {annealing, mrf, simulated}, month = {November}, number = {6}, pages = {721--741}, posted-at = {2008-05-07 06:09:28}, priority = {2}, publisher = {Routledge}, title = {Stochastic relaxation, Gibbs distributions and the Bayesian restoration of images}, volume = {6}, year = {1984} } @dea{giordano91, Address = {Montpellier}, Author = {Jean-Yves Giordano}, School = {Universit{\'e} Montpellier II}, Title = {{R}epr{\'e}sentation arbor{\'e}e des {P}roximit{\'e}s et {A}rbres {P}hyllog{\'e}n{\'e}tique}, Utilisateur = {Guillaume Andrieu}, Year = 1991} @article{gojobori82, Author = {Takashi Gojobori and Kazushige Ishii and Masatoshi Nei}, Journal = {Journal of Molecular Evolution}, Pages = {414-423}, Title = {Estimation of Average Number of Nucleotide Substitutions when the Rate of Substitution varies with Nucleotide}, Utilisateur = {Guillaume Andrieu}, Volume = 18, Year = 1982} @incollection{gojobori90, Author = {Takashi Gojobori and Etsuko N. Moriyama and M. Kimura}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 33, Editor = {Russsell F. Doolittle}, Pages = {531-550}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Statistical Methods for Estimating Sequence Divergence}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{golding83, Author = {G. B. Golding}, Journal = {Molecular Biology and Evolution}, Pages = {125-142}, Title = {Estimates of {DNA} and protein sequence divergence: an examination of some assumptions}, Volume = 1, Year = 1983} @article{goldman93, Author = {N. Goldman }, Journal = {Journal of Molecular Evolution}, Pages = {182-198}, Title = {Statistical tests of models of {DNA} substitution}, Volume = 36, Year = 1993} @article{goldman94, Author = {N. Goldman and Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {725-736}, Title = {A Codon-based model of nucleotide substitution for protein-coding {DNA} sequences}, Volume = 11, Year = 1994} @article{goldman98a, Author = {N. Goldman}, Journal = {Proceedings of the Royal Society B: Biological Sciences}, Pages = {1779-1786}, Title = {Phylogenetic information and experimental design in molecular systematics }, Volume = 265, Year = 1998} @article{goldman98b, Author = {N. Goldman and J. Thorne and D. Jones}, Journal = {Genetics}, Pages = {445-458}, Title = {Assessing the impact of secondary structure and solvent accessibility on protein evolution}, Volume = 149, Year = 1998} @article{goldman00, Author = {N. Goldman and S. Whelan}, Journal = {Molecular Biology and Evolution}, Pages = {975-978}, Title = {Statistical tests of {G}amma-distributed rate heterogeneity in models of sequence evolution in phylogenetics}, Volume = 17, Year = 2000} @article{goodman65, Author = {Leo A. Goodman}, Journal = {Technometrics}, Month = {MAY}, Number = 2, Pages = {247-253}, Title = {On Simultaneous Confidence Intervals for Multinomial Proportions }, Volume = 7, Year = 1965} @article{gouy84, Author = {M. Gouy and F. Milleret and C. Mugnier and M. Jacobzone and C. Gautier}, Journal = {Nucleic Acids Research}, Number = 2, Pages = {121-127}, Title = {{ACNUC}: a nucleic acid sequence data base and analysis system}, Volume = 12, Year = 1984} @article{graur91, Author = {D. Graur and W.A. Hide and W.-H. Li}, Journal = {Nature}, Pages = {649-652}, Title = {Is the guinea-pig a rodent?}, Volume = 351, Year = 1991} @article{gu95, Author = {X. Gu and Y.X. Fu and W.H. Li}, Journal = {Molecular Biology and Evolution}, Pages = {546-557}, Title = {Maximum likelihood estimation of the heterogeneity of substitution rate among nucleotide sites}, Volume = 12, Year = 1995} @article{gu97, Author = {X. Gu and J.D. Zhang}, Journal = {Molecular Biology and Evolution}, Pages = {1106-13}, Title = {A simple method for estimating the parameter of substitution rate variation among sites}, Volume = 14, Year = 1997} @article{gu98, Author = {X. Gu and W.H. Li}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {5899-5905}, Title = {Estimation of evolutionary distances under stationary and nonstationary models of nucleotide substitution}, Volume = 95, Year = 1998} @inproceedings{guenoche00, Author = {Alain Gu{\'e}noche}, Booktitle = {Recueil des Actes JOBIM 2000}, Editor = {O. Gascuel and M.-F Sagot}, Pages = {181-191}, Title = {Quelle confiance accorder {\`a} une repr{\'e}sentation arbor{\'e}e ?}, Year = 2000} @article{guenoche87, Author = {Alain Guenoche}, Journal = {Math. Sci. hum.}, Pages = {21-40}, Title = {Cinq algorithmes d'approximation d'une dissimilarit{\'e} par des arbres {\`a} distances additives}, Utilisateur = {Gilles Caraux and Denise Levy}, Volume = 98, Year = 1987} @inproceedings{guenoche00b, Author = {A. Gu{\'e}noche and H. Garreta}, Booktitle = {Computational biology, LNCS 2066}, Pages = {45-46}, Title = {Can we have confidence in a tree representation ?}, Year = 2000} @book{gilks95, author = {W. R. Gilks and S. Richardson and D. Spiegelhalter}, publisher = {{Chapman \& Hall/CRC}}, title = {Markov Chain Monte Carlo in Practice}, year = {1995} } @article{gray09, author="R. Gray and A. Drummond and Greenhill S.", title="Language phylogenies reveal expansion pulses and pauses in {P}acific settlement", journal="Science", year="2009", pages={479-483} } @article{guindon01, Author = {S. Guindon and G. Perri{\`e}re}, Journal = {Molecular Biology and Evolution}, Pages = {1838-40}, Title = {Intragenomic base content variation is a potential source of biases when searching for horizontally transferred genes}, Volume = 18, Year = 2001} @article{guindon02, Author = {S. Guindon and O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {534-543}, Title = {Efficient biased estimation of evolutionary distances when substitution rates vary across sites}, Volume = 19, Year = 2002} @article{guindon03, Author = {S. Guindon and O. Gascuel}, Journal = {Systematic Biology}, Pages = {696-704}, Title = {A simple, fast and accurate algorithm to estimate large phylogenies by maximum likelihood}, Volume = 52, Year = 2003} @article{guindon04, Author = {S. Guindon and A. Rodrigo and K. Dyer and J. Huelsenbeck}, Journal = {Proceedings of the National Academy of Sciences}, Pages = {12957-12962}, Title = {Modeling the site-specific variation of selection patterns along lineages}, Volume = {101}, Year = 2004} @article{guindon05, Author = {S. Guindon and F. Lethiec and P. Duroux and O. Gascuel}, Journal = {Nucleic Acids Research}, Pages = {557-559}, Title = {{PHYML} {O}nline -- a web server for fast maximum likelihood-based phylogenetic inference}, Volume = {33(Web Server issue)}, Year = 2005} @article{guindon06, Author = {S. Guindon and M. Black and A. Rodrigo}, Journal = {Molecular Biology and Evolution}, Pages = {919-926}, Title = {Control of the False Discovery Rate Applied to the Detection of Positively Selected Amino Acid Sites.}, Volume = {23}, Year = 2006} @article{gusfield91, Author = {D. Gusfield}, Journal = {Networks}, Pages = {19-28}, Title = {Efficient Algorithms for inferring evolutionnary trees}, Volume = 21, Year = 1991} @article{hamming, Author = {R. W. Hamming}, Journal = {The Bell System Technical Journal}, Number = 2, Pages = {147-160}, Title = {Error Detecting and Error Correcting Codes}, Utilisateur = {Gilles Caraux and Guillaume Andrieu }, Volume = 26, Year = 1950} @article{harshman94, Author = {J. Harshman}, Journal = {Systematic Biology}, Number = 3, Pages = {419-424}, Title = {The effect of irrelevant characters on bootstrap values}, Utilisateur = {Vincent}, Volume = 43, Year = 1994} @article{hartigan72, Author = {J. Hartigan}, Journal = {Biometrics}, Pages = {53-65}, Title = {Minimum mutation fits to a given tree}, Volume = 29, Year = 1972} @article{hasegawa85, Author = {M. Hasegawa and H. Kishino and T. Yano}, Journal = {Journal of Molecular Evolution}, Pages = {160-174}, Title = {Dating of the {H}uman-{A}pe Splitting by a Molecular Clock of Mitochondrial-{DNA}}, Utilisateur = {Guillaume Andrieu}, Volume = 22, Year = 1985} @article{hasegawa87, Author = {M. Hasegawa and H. Kishino and T. Yano}, Journal = {Journal of Molecular Evolution}, Pages = {132-147}, Title = {Man's Place in Hominoidea as Inferred from Molecular Clocks of {DNA}}, Utilisateur = {Guillaume Andrieu}, Volume = 26, Year = 1987} @article{hasegawa89, Author = {H. Kishino and M. Hasegawa}, Journal = {Journal of Molecular Evolution}, Pages = {170-179}, Title = {Evaluation of the maximum likelihood estimate of the evolutionnary tree topology from {DNA} sequence data, and the branching order in Homonoidea}, Volume = 29, Year = 1989} @article{hasegawa94, Author = {M. Hasegawa and H. Kishino}, Journal = {Molecular Biology and Evolution}, Pages = {142-145}, Title = {Accuracies of the Simple Methods for Estimating the Bootstrap Probability of a Maximum-Likelihood Tree}, Volume = 11, Year = 1994} @article{hein89, Author = {J. Hein}, Journal = {Molecular Biology and Evolution}, Pages = {669-684}, Title = {A tree reconstruction method that is economical in the number of pairwise comparisons used.}, Utilisateur = {Vincent}, Volume = 6, Year = 1989} @incollection{hein90, Author = {J. Hein}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 39, Editor = {Russsell F. Doolittle}, Pages = {626-644}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Unified Approach to Alignement and Phylogenies}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{hein93, Author = {Jotun Hein }, Journal = {Journal of Molecular Evolution}, Pages = {396-405}, Title = {a heuristic method to reconstruct the history of sequences subject to recombinaison}, Utilisateur = {G. Andrieu}, Volume = 36, Year = 1993} @incollection{hendy82, Author = {M.D. Hendy and D. Penny}, Booktitle = {Mathematical Biosciences}, Pages = {277-290}, Publisher = {Elsevier Science Publishing}, Title = {Branch and bound Algorithms to Determine Minimal Evolutionary Trees}, Utilisateur = {Vincent}, Volume = 59, Year = 1982} @article{hendy89, Author = {M.D. Hendy and D. Penny}, Journal = {Syst Zool}, Number = 4, Pages = {297-309}, Title = {A framework for the quantitative study of evolutionary trees}, Utilisateur = {Vincent}, Volume = 38, Year = 1989} @article{hendy93, Author = {M.D. Hendy and D. Penny}, Journal = {Journal of Classification}, Pages = {297-309}, Title = {Spectral analysis of phylogenetic data}, Volume = 10, Year = 1993} @article{hendy94, Author = {M. Hendy and D. Penny and M. A. Steel}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {3339-3343}, Title = {A discrete {F}ourier analysis for evolutionary trees}, Volume = 91, Year = 1994} @article{hg01, Author = {{International Human Genome Sequencing Consortium}}, Journal = {Nature}, Pages = {860-921}, Title = {Initial sequencing and analysis of the human genome}, Volume = 409, Year = 2001} @incollection{higgins96, Address = {San Diego}, Author = {D. G. Higgins and J. D. Thompson and J. T. Gibbson}, Booktitle = {Methods in enzymology}, Editor = {R. F. Doolittle}, Pages = {383-401}, Publisher = {Academic Press}, Title = {Using {CLUSTAL} for multiple sequence alignments}, Year = 1996} @inbook{hiv_epitope, Address = {Los Alamos, New Mexico}, Author = {B. Korber and C. Brander and B. Haynes and R. Koup and C. Kuiken and J. Moore and B. Walker and D. Watkins}, Publisher = {Los Alamos National Laboratory, Theoretical Biology and Biophysics}, Title = {{HIV} molecular immunology database 2002}, Year = 2002} @inbook{karlin, Address = {New York}, Author = {Samuel Karlin}, Chapter = { No VII Examples of continuous Time {M}arkov Chains }, Pages = {189-209}, Publisher = {Academic Press}, Title = {A first course in Stochastic processes}, Utilisateur = {Guillaume Andrieu}, Year = 19} @article{koshi96, Author = {J. Koshi and R. Goldstein}, Journal = {Journal of Molecular Evolution}, Pages = {313-320}, Title = {Probabilistic reconstruction of ancestral protein sequences}, Volume = 42, Year = 1996} @article{koshi98, Author = {J. Koshi and R. Goldstein}, Journal = {Proteins}, Pages = {289-295}, Title = {Models of natural mutations including site heterogeneity}, Volume = 32, Year = 1998} @article{kirkpatrick83, Author = {S. Kirkpatrick and C. D. Gelatt and M. P. Vecchi}, Journal = {Science}, Pages = {671-680}, Title = {Optimization by simulated annealing}, Volume = 220, Year = 1983} @inbook{hillis91, Author = {D.M. Hillis}, Chapter = 13, Note = {Preliminsaire a l'article hilhuels92}, Pages = {278-294}, Title = {Discriminating Between Phylogenetic Signal and Random Noise in {DNA} Sequences}, Utilisateur = {Vincent}} @article{hillishuels92, Author = {D.M. Hillis and J.P. Huelsenbeck}, Journal = {Journal of Heredity}, Note = {Examine la distribution des arbres les plus parcimonieux : gaussienne applatie}, Pages = {189-195}, Title = {Signal, Noise, and Reliability in Molecular Phylogenetic Analyses}, Volume = 83, Year = 1992} @article{ho05, Author = {S. Ho and M. Phillips and A. Drummond and A. Cooper}, Journal = {Molecular Biology and Evolution}, Pages = {1355-1363}, Title = {Accuracy of rate estimation using relaxed-clock models with a critical focus on the early {M}etazoan radiation}, Volume = 22, Year = 2005} @article{holm79, Author = {S. Holm}, Journal = {Scandinavian Journal of Statistics}, Pages = {65-70}, Title = {A simple sequentially rejective multiple test procedure}, Volume = 6, Year = 1979} @article{holmquist72a, Author = {Richard Holmquist}, Journal = {Journal of Molecular Evolution}, Pages = {115-133}, Title = {Theoretical foundations for a quantitative approach to paleogenetics {Part I : DNA}}, Utilisateur = {Gilles Caraux et Guillaume Andrieu}, Volume = 1, Year = 1972} @article{holmquist72b, Author = {Richard Holmquist}, Journal = {Journal of Molecular Evolution}, Pages = {211-222}, Title = {Empirical support for stochastic model of evolution}, Utilisateur = {Gilles Caraux et Guillaume Andrieu}, Volume = 1, Year = 1972} @article{holmquist83, Author = {R. Holmquist and M. Goodman and T. Conroy and J. Czelusniak}, Journal = {Journal of Molecular Evolution}, Pages = {437-448}, Title = {The spatial distribution of fixed mutations within genes coding for proteins}, Volume = 19, Year = 1983} @article{huelsenbeck93, Author = {J. P. Huelsenbeck and D. Hillis}, Journal = {Systematic Biology}, Pages = {247-264}, Title = {Success of phylogenetic methods in the four-taxon case}, Volume = 42, Year = 1993} @article{huelsenbeck95a, Author = {J. P. Huelsenbeck}, Journal = {Systematic Biology}, Pages = {17-48}, Title = {Performance of phylogenetic methods in simulation}, Volume = 44, Year = 1995} @article{huelsenbeck95b, Author = {J. P. Huelsenbeck}, Journal = {Molecular Biology and Evolution}, Pages = {843-849}, Title = {The robustness of two phylogenetic methods: four-taxon simulations reveal a slight superiority of maximum likelihood over neighbor joining}, Volume = 12, Year = 1995} @article{huelsenbeck97a, Author = {J. P. Huelsenbeck and K. A. Crandall}, Journal = {Annual Review of Ecology and Systematics}, Pages = {437-466}, Title = {Phylogeny estimation and hypothesis testing using maximum likelihood}, Volume = 28, Year = 1997} @article{huelsenbeck97b, Author = {J. Huelsenbeck and B. Rannala}, Journal = {Science}, Pages = {218-219}, Title = {Phylogenetic methods come of age: testing hypotheses in an evolutionary context}, Volume = 276, Year = 1997} @article{huelsenbeck99, Author = {J. Huelsenbeck and R. Nielsen}, Journal = {Journal of Molecular Evolution}, Pages = {86-93}, Title = {Variation in the pattern of nucleotide substitution across sites}, Volume = 48, Year = 1999} @article{huelsenbeck01, Author = {J. Huelsenbeck and F. Ronquist}, Journal = {Bioinformatics}, Pages = {754-755}, Title = {{MRBAYES} : Bayesian inference of phylogenetic trees}, Volume = 17, Year = 2001} @article{huelsenbeck01a, Author = {J. P. Huelsenbeck and F. Ronquist and R. Nielsen and J. P. Bollack}, Journal = {Science}, Pages = {2310-2314}, Title = {Bayesian Inference of Phylogeny and Its Impact on Evolutionary Biology}, Volume = 294, Year = 2001} @article{huelsenbeck01c, Author = {J. P. Huelsenbeck and J. P. Bollback}, Journal = {Systematic Biology}, Pages = {351-366}, Title = {Empirical and hierarchical bayesian estimation of ancestral states}, Volume = 50, Year = 2001} @article{huelsenbeck02, Author = {J. P. Huelsenbeck}, Journal = {Molecular Biology and Evolution}, Pages = {698-707}, Title = {Testing a Covariotide Model of {DNA} Substitution}, Volume = 19, Year = 2002} @article{huelsenbeck04, Author = {J. Huelsenbeck and B. Larget and M. Alfaro}, Journal = {Molecular Biology and Evolution}, Pages = {1123-1133}, Title = {Bayesian phylogenetic model selection using reversible jump markov chain monte carlo.}, Volume = 21, Year = 2004} @article{huelsenbeck04b, Author = {J. Huelsenbeck and K. Dyer}, Journal = {Journal of Molecular Evolution}, Pages = {661-672}, Title = {Bayesian estimation of positively selected sites}, Volume = 58, Year = 2004} @article{huelsenbeck06, Author = {J. Huelsenbeck and S. Jain and S. Frost and S. Pond}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {6263-6268}, Title = {A Dirichlet process model for detecting positive selection in protein-coding {DNA} sequences}, Volume = 103, Year = 2006} @article{hughes88, Author = {A. Hughes and M. Nei}, Journal = {Nature}, Pages = {167-170}, Title = {Pattern of nucleotide substitution at major histocompatibility complex class {I} loci reveals overdominant selection}, Volume = 335, Year = 1988} @article{hughes90, Author = {A. Hughes and T. Ota and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {515-524}, Title = {Positive darwinian selection promotes charge profile diversity in the antigen-binding cleft of class {I} major-histocompatibility-complex molecules}, Volume = 7, Year = 1990} @article{mrbayes, Author = {J. P. Huelsenbeck and F. Ronquist}, Journal = {Bioinformatics}, Pages = {754-755}, Title = {{M}r{B}ayes: {B}ayesian inference of phylogeny}, Volume = 17, Year = 2001} @article{irwin91, Author = {David M. Irwin and Thomas D. Kocher and Allan C. Wilson}, Journal = {Journal of Molecular Evolution}, Pages = {128-144}, Title = {{E}volution of the {C}ytochrome {\em b} {G}ene of {M}amals}, Utilisateur = {F.Catzeflis et G. Andrieu}, Volume = 32, Year = 1991} @techreport{jiang92, Author = {T. Jiang and Ming Li}, Institution = {Mc Master Univ. and University of Waterloo}, Title = {Some optimizations problems related to molecular biology}, Year = 1992} @article{jiang94, Author = {Tao Jiang, Eugene L. Lawler, Lusheng Wang}, Title = {Aligning Sequences via an Evolutionary Tree: Complexity and Approximation}, Year = 1994} @article{jin90, Author = {L. Jin and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {82-102}, Title = {Limitations of the evolutionary parsimony method of phylogenetic analysis}, Volume = 7, Year = 1990} @article{jin94, Author = {Li Jin and Ranajit Chakraborty}, Journal = {Molecular Biology and Evolution}, Pages = {120-127}, Title = {Estimation of genetic distance and coefficient of gene diversity from single-probe multilocus {DNA} fingerprinting data}, Utilisateur = {Gilles Caraux}, Volume = 11, Year = 1994} @incollection{johnson90, Address = {New York}, Author = {Mark S. Johnson and Andrej Sali and Tom L. Blundell}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 42, Editor = {Russsell F. Doolittle}, Pages = {670-690}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Phylogenetic Relationships from Three-Dimensional Protein Structures}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{jones92, Author = {D. Jones and W. Taylor and J. Thornton}, Journal = {Computer Applications in the Biosciences (CABIOS)}, Pages = {275-282}, Title = {The rapid generation of mutation data matrices from protein sequences}, Volume = 8, Year = 1992} @incollection{jukes69, Address = {New York}, Author = {T. Jukes and C. Cantor}, Booktitle = {Mammalian Protein Metabolism}, Chapter = {24}, Editor = {H. Munro}, Pages = {21-132}, Publisher = {Academic Press}, Title = {Evolution of protein molecules}, Utilisateur = {Gilles Caraux}, Volume = {III}, Year = 1969} @Manual{R, title = {R: A Language and Environment for Statistical Computing}, author = {{R Core Team}}, organization = {R Foundation for Statistical Computing}, address = {Vienna, Austria}, year = {2013}, url = {http://www.R-project.org/}, } @article{kaj03, title={The coalescent process in a population with stochastically varying size}, author={Kaj, Ingemar and Krone, Stephen M}, journal={Journal of Applied Probability}, Volume = 40, pages={33--48}, year={2003}, publisher={JSTOR} } @article{kannan95, Author = {S. Kannan and T. Warnow}, Journal = {SIAM J. Comp.}, Number = 3, Pages = {511-519}, Title = {Tree reconstruction from partial orders}, Volume = 24, Year = 1995} @article{kannan97, Author = {S. Kannan}, Journal = {Journal of the indian institute of science}, Number = 4, Pages = {353-364}, Title = {consensus of trees : desirable properties and computationnal methods}, Volume = 77, Year = 1997} @article{kaplan79, Author = {N. Kaplan and C.H. Langley}, Journal = {Journal of Molecular Evolution}, Pages = {295-304}, Title = {A new estimate of sequence divergence of mitochondrial {\sc DNA} Using restriction endonuclease mappings}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 13, Year = 1979} @inbook{karlin, Address = {New York}, Author = {Samuel Karlin}, Chapter = { No VII Examples of continuous Time {M}arkov Chains }, Pages = {189-209}, Publisher = {Academic Press}, Title = {A first course in Stochastic processes}, Utilisateur = {Guillaume Andrieu}, Year = 19} @article{karlin93, Author = {Samuel Karlin and Stephen F. Altschul}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {5873-5877}, Title = {Applications and Statistics for multiple hight-scoring segments in molecular Sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 90, Year = 1993} @article{kashyap74, Author = {R. L. Kashyap and S. Subas}, Journal = {Journal of Theoretical Biology}, Pages = {75-101}, Title = {Statistical estimation of parameters in a phylogenetic tree using a dynamic model of the substitutional process}, Utilisateur = {Gilles Caraux}, Volume = 47, Year = 1974} @article{kaslow87, Author = {R. Kaslow and D. Ostrow and R. Detel and J. Phair and B. Polk and C. Rinaldo}, Journal = {American Journal of Epidemiology}, Pages = {310-318}, Title = {The {M}ulticenter {AIDS} {C}ohort {S}tudy : rationale, organization, and selected characteristics of the participants}, Volume = 126, Year = 1987} @book{kendall73, Address = {London}, Author = {M. G. Kendall and A. Stuart}, Publisher = {Griffin}, Title = {The Advanced Theory of Statistics}, Volume = {II~: Inference and relationship}, Year = 1973} @article{kidd71, Author = {K.K. Kidd and L.A. Sgaramella-Zonta}, Journal = {The American Journal of Human Genetics}, Pages = {235-252}, Title = {Phylogenetic analysis: concepts and methods}, Volume = 23, Year = 1971} @article{kimura72, Author = {M. Kimura and Tomoko Otha}, Journal = {Journal of Molecular Evolution}, Pages = {87-90}, Title = { On the stochastic model for estimation of mutational distance between homologous proteins}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 2, Year = 1972} @article{kimura80, Author = {M. Kimura}, Journal = {Journal of Molecular Evolution}, Pages = {111-120}, Title = {A simple method for estimating evolutionary rates of base substitutions through comparative studies of nucleotide sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 16, Year = 1980} @article{kimura81, Author = {M. Kimura}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {454-458}, Title = {Estimation of evolutionary distances between homologous nucleotide sequences}, Volume = 78, Year = 1981} @article{kimura87, Author = {M. Kimura}, Journal = {Journal of Molecular Evolution}, Pages = {24-33}, Title = {Molecular Evolutionnary Clock and the Neutral Theory}, Utilisateur = {Guillaume Andrieu}, Volume = 26, Year = 1987} @article{kingman82, Author = {Kingman, J. F. C. }, Citeulike-Article-Id = {3431666}, Journal = {Stochastic Processes and their Applications}, Keywords = {coalescent, ebsp-paper}, Pages = {235--248}, Posted-At = {2008-10-20 21:06:45}, Priority = {0}, Title = {The coalescent}, Volume = {13}, Year = {1982}} @article{kishino89, Author = {H. Kishino and M. Hasegawa}, Journal = {Journal of Molecular Evolution}, Pages = {170-179}, Title = {Evaluation of the Maximum Likelihood Estimate of the Evolutionnary Tree Topology from {DNA} Sequence Data, and the Branching Order in Hominoidea}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 29, Year = 1989} @incollection{kishino90, Address = {New York}, Author = {H. Kishino and M. Hasegawa }, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 34, Editor = {Russsell F. Doolittle}, Pages = {550-570}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Converting Distance to Time : Application to Human Evolution}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{kishino90b, Author = {H. Kishino and T. Miyata and M. Hasegawa}, Journal = {Journal of Molecular Evolution}, Pages = {151-160}, Title = {Maximum likelihood inference of protein phylogeny and the origin of chloroplasts}, Volume = 31, Year = 1990} @Article{kishino01, Author="Kishino, H. and Thorne, J. and Bruno, W.", Title="{{P}erformance of a divergence time estimation method under a probabilistic model of rate evolution}", Journal="Mol. Biol. Evol.", Year="2001", Volume="18", Pages="352--361", Month="Mar" } @Article{kitazoe07, Author="Kitazoe, Y. and Kishino, H. and Waddell, P. J. and Nakajima, N. and Okabayashi, T. and Watabe, T. and Okuhara, Y. ", Title="{{R}obust time estimation reconciles views of the antiquity of placental mammals}", Journal="PLoS ONE", Year="2007", Volume="2", Pages="e384" } @article{klotz79, Author = {Lynn C. Klotz and Ned Komar and Roger L. Blanken and Ralph M. Mitchell}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {4516-4520}, Title = {Calculation of evolutionary trees from sequence data}, Utilisateur = {Gilles Caraux}, Volume = 76, Year = 1979} @article{klotz81, Author = {Lynn C. Klotz and Roger L. Blanken}, Journal = {Journal of Theoretical Biology}, Pages = {261-272}, Title = {A practical method for calculating evolutionary trees from sequence data}, Utilisateur = {Gilles Caraux}, Volume = 91, Year = 1981} @article{kolaczkowski04, Author = {B. Kolaczkowski and J. Thornton}, Journal = {Nature}, Pages = {980-984}, Title = {Performance of maximum parsimony and likelihood phylogenetics when evolution is heterogeneous}, Volume = 431, Year = 2004} @article{kondo93, Author = {Rumi Kondo and Satoshi Horai and Yoko Satta and Naoyuki Takahata}, Journal = {Journal of Molecular Evolution}, Pages = {517-531}, Title = {Evolution of Hominoid Mitochondrial {DNA} with special Reference to the \\ Silent Substitution Rate over the Genome }, Utilisateur = {Guillaume Andrieu}, Volume = 36, Year = 1993} @article{kondrashov02, Author = {A.S. Kondrashov and S. Sunyaev and F.A. Kondrashov}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {14878-14883}, Title = {Dobzhansky-{M}uller incompatibilities in protein evolution}, Volume = 99, Year = 2002} @article{kosiol04, Author = {C. Kosiol and N. Goldman}, Journal = {Molecular Biology and Evolution}, Pages = {193-199}, Title = {Different versions of the {D}ayhoff rate matrix}, Volume = {22}, Year = 2004} @incollection{kruskal71, Author = {J. B. Kruskal and Isidor Dyen and Paul Black}, Booktitle = {Mathematics in the archeological and histor. sciences}, Editor = {F. R. Hodson and D. G. Kendall and P. Tautu}, Pages = {361-380}, Publisher = {Edinburgh University Press}, Title = {The vocabulary method of reconstructing language trees: innovations and large-scale applications}, Utilisateur = {Gilles Caraux}, Year = 1971} @article{kufels94, Author = {M. Kuhner and J. Felsenstein}, Journal = {Molecular Biology and Evolution}, Pages = {459-468}, Title = {A simulation comparison of phylogeny algorithms under equal and unequal evolutionary rates}, Utilisateur = {Vincent}, Volume = 11, Year = 1994} @article{lanave84, Author = {C. Lanave and G. Preparata and C. Saccone and G. Serio}, Journal = {Journal of Molecular Evolution}, Pages = {86-93}, Title = {A new method for calculating evolutionary substitution rates}, Volume = 20, Year = 1984} @article{lake87, Author = {James A. Lake}, Journal = {Molecular Biology and Evolution}, Pages = {167-191}, Title = {A rate-independent technique for analysis of nucleic acid sequences : Evolutionary parsimony}, Utilisateur = {Gilles Caraux}, Volume = 4, Year = 1987} @article{langley74, Author = {C. H. Langley and Walter M. Fitch}, Journal = {Journal of Molecular Evolution}, Pages = {161-177}, Title = {An examination of the constancy of the rate of molecular evolution}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 3, Year = 1974} @article{lanyon85, Author = {S. M. Lanyon}, Journal = {Systematic Zoology}, Number = 4, Pages = {397-403}, Title = {Detecting internal inconsistencies in distance data}, Utilisateur = {Vincent}, Volume = 34, Year = 1985} @article{larget99, Author = {B. Larget and D. L. Simon}, Journal = {Molecular Biology and Evolution}, Pages = {750-759}, Title = {Markov Chain {M}onte {C}arlo algorithms for the bayesian analysis of phylogenetic trees}, Volume = 16, Year = 1999} @article{lartillot04, Author = {N. Lartillot and H. Philippe}, Journal = {Molecular Biology and Evolution}, Pages = {1095-1109}, Title = {A Bayesian mixture model for across-site heterogeneities in the amino-acid replacement process}, Volume = 21, Year = 2004} @incollection{lausen86, Author = {Berthold Lausen and Paul O. Degens}, Booktitle = {Die klassifikation und ihr umfeld}, Editor = {Paul O. Degens and H. J. Hermes and O. Opitz}, Pages = {306-314}, Publisher = {Indeks Verlag}, Series = {Studien zur Klassification}, Title = {Variance estimation and the reconstruction of phylogenies}, Utilisateur = {Gilles Caraux}, Volume = 17, Year = 1986} @incollection{lausen88, Author = {Berthold Lausen and Paul O. Degens}, Booktitle = {Classification and related methods of data analysis}, Editor = {H. H. Bock}, Pages = {367-374}, Publisher = {Elsevier}, Title = {Evaluation of the reconstruction of phylogenies with {DNA-DNA}-Hybridization data}, Utilisateur = {Gilles Caraux}, Year = 1988} @incollection{lausen89, Author = {Berthold Lausen}, Booktitle = {Conceptual and numerical analysis of data}, Editor = {O. Opitz}, Pages = {481-488}, Publisher = {Springer Verlag}, Title = {Exploring homologous t{\sc rna} sequence data: positional mutation rates and genetic}, Utilisateur = {Gilles Caraux}, Year = 1989} @article{lawrence97, Author = {J. Lawrence and H. Ochman}, Journal = {Journal of Molecular Evolution}, Pages = {383-397}, Title = {Amelioration of bacterial genomes: rates of change and exchange}, Volume = 44, Year = 1997} @article{lawrence98, Author = {J. Lawrence and H. Ochman}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {9413-9417}, Title = {Molecular archaeology of the {\it \hbox{E}scherichia coli} genome}, Volume = 95, Year = 1998} @article{le08, Author = {SQ. Le and O. Gascuel}, Journal = {Mol. Biol. Evol.}, Title = {An Improved General Amino-Acid Replacement Matrix}, Volume = {25}, Pages = {1307-1320}, Year = 2008} @article{le_calve85, Author = {Georges {Le Calve}}, Journal = {Statistiques et Analyse de Donn{\'e}es}, Number = 2, Pages = {29-44}, Title = {Distance {\`a} centre}, Utilisateur = {Gilles Caraux}, Volume = 10, Year = 1985} @article{leclerc85a, Author = {Bruno Leclerc}, Journal = {Math. Sci. hum.}, Pages = {5-40}, Title = {La comparaison des hierarchies : Indices et metriques}, Utilisateur = {Gilles Caraux}, Volume = 92, Year = 1985} @article{leclerc85b, Author = {Bruno Leclerc}, Journal = {Math. Sci. hum.}, Pages = {5-34}, Title = {La hi{\'e}rarchies de parties et leur demi-treillis}, Utilisateur = {Gilles Caraux}, Volume = 89, Year = 1985} @article{leclerc94, Author = {Bruno Leclerc}, Journal = {To appear in Journal of Classification}, Title = {Minimum spanning trees for tree metrics : abridgements and adjustements}, Utilisateur = {Vincent}, Year = 1994} @article{lecointre93, Author = {G. Lecointre and H. Philippe and H.L.V. L{\^e} and H. Le Guyader}, Journal = {Mol. Phylogenet. Evol.}, Pages = {205-224}, Title = {Species sampling has a major impact on phylogenetic inference}, Volume = 2, Year = 1993} @article{lemmon02, Author = {A. Lemmon and M. Milinkovitch}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {10516-10521}, Title = {The metapopulation genetic algorithm: an efficient solution for the problem of large phylogeny estimation}, Volume = 99, Year = 2002} @article{metapiga, Author = {A.R. Lemmon and Milinkovitch M.C.}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {10516-10521}, Title = {The metapopulation genetic algorithm: An efficient solution for the problem of large phylogeny estimation}, Volume = 99, Year = 2002} @article{lee95, Author = {Y. Lee and T. Ota and V. Vaquier}, Journal = {Molecular Biology and Evolution}, Pages = {231-238}, Title = {Positive selection is a general phenomenon in the evolution of abalone sperm lysin}, Volume = 12, Year = 1995} @Article{lepage06, Author="Lepage, T. and Lawi, S. and Tupper, P. and Bryant, D. ", Title="{{C}ontinuous and tractable models for the variation of evolutionary rates}", Journal="Math Biosci", Year="2006", Volume="199", Pages="216--233", Month="Feb" } @article{lepage07, Author = {T. Lepage and D. Bryant and H. Philippe and N. Lartillot}, Journal = {Molecular Biology and Evolution}, Pages = {2669-2680}, Title = {A general comparison of relaxed molecular clock models}, Volume = 24, Year = 2007} @article{lewis98, Author = {P. Lewis}, Journal = {Molecular Biology and Evolution}, Pages = {277-283}, Title = {A genetic algorithm for maximum likelihood phylogeny inference using nucleotide sequence data}, Volume = 15, Year = 1998} @article{lewontin89, Author = {R. C. Lewontin}, Journal = {Molecular Biology and Evolution}, Pages = {15-32}, Title = {Inferring the number of evolutionary events from {DNA} coding sequence differences}, Utilisateur = {Gilles Caraux}, Volume = 6, Year = 1989} @inproceedings{li87, Author = {W.-H. Li and K.-H. Wolfe and J. Sourdis and P.M. Sharp}, Booktitle = {Cold Spring Harbor Symposia on Quantitative Biology}, Editor = {Cold Spring Harbore Laboratory}, Pages = {847-856}, Title = {Reconstruction of phylogenetic trees and estimation of divergence times under nonconstant rates of evolution}, Volume = {LII}, Year = 1987} @article{li89, Author = {Wen-Hsiung Li}, Journal = {Molecular Biology and Evolution}, Pages = {424-435}, Title = {A statistical test of phylogenies estimated from sequence data}, Utilisateur = {Gilles Caraux}, Volume = 6, Year = 1989} @incollection{li90, Address = {New York}, Author = {Wen-Hsiung Li and Manolo Gouy}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 40, Editor = {Russsell F. Doolittle}, Pages = {645-659}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Statistical Tests of Molecular Phylogenies}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @incollection{li91, Author = {Wen-Hsiung Li and Manolo Gouy}, Booktitle = {Phylogenetic analysis of {DNA} sequences}, Chapter = 12, Editor = {Michael M. Miyamoto and Joel Cracraft}, Pages = {249-277}, Publisher = {Oxford university press}, Title = {Statistical methods for testing molecular phylogenies}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Year = 1991} @article{li92, Author = {Wen-Hsiung Li and Bousquet, J}, Journal = {Molecular Biology and Evolution}, Pages = {1185-1189}, Title = {Relative-Rate test for nucleotide substitutions between two lineages}, Utilisateur = {G. Andrieu}, Volume = 9, Year = 1992} @article{li93, Author = {Wen-Hsiung Li}, Journal = {Journal of Molecular Evolution}, Pages = {96-99}, Title = { Unbiased estimation of the rates of synonimous and nonsynonimous substitution}, Utilisateur = {Guillaume Andrieu}, Volume = 36, Year = 1993} @article{li94, Author = {W.-H. Li and A. Zharkikh}, Journal = {Systematic Biology}, Pages = {424-430}, Title = {What is the bootstrap technique?}, Utilisateur = {Vincent}, Volume = 43, Year = 1994} @article{li95, Author = {W.-H. Li and A. Zharkikh}, Journal = {Systematic Biology}, Pages = {49-63}, Title = {Statistical tests of {DNA} phylogenies}, Volume = 44, Year = 1995} @phdthesis{li96, Author = {S. Li}, School = {Ohio State University}, Title = {Phylogenetic tree construction using {M}arkov chain {M}onte {C}arlo}, Year = 1996} @article{lin02, Author = {Y.-H. Lin and P. McLenachan and A. Gore and M. Phillips and R. Ota and M. Hendy and D. Penny}, Journal = {Molecular Biology and Evolution}, Pages = {2060-2070}, Title = {Four new mitochondrial genomes, and the stability of evolutionary trees of mammals}, Volume = 19, Year = 2002} @article{lockhart94, Author = {P. Lockhart and M. Steel and M. Hendy and D Penny}, Journal = {Molecular Biology and Evolution}, Pages = {605-612}, Title = {Recovering Evolutionary Trees under a More Realistic Model of Sequence}, Volume = 11, Year = 1994} @article{lockhart98, Author = {P. Lockhart and M. Steel and A. Barbrook and D. Huson and M. Charleston and C. Howe}, Journal = {Molecular Biology and Evolution}, Pages = {1183-1188}, Title = {A covariotide model explains apparent phylogenetic structure of oxygenic photosynthetic lineages}, Volume = 15, Year = 1998} @article{lockhart00, Author = {P. Lockhart and D. Huson and U. Maier and M. Fraunholz and Y. Van de Peer and A. Barbrook and C. Howe and M. Steel.}, Journal = {Molecular Biology and Evolution}, Pages = {835-838}, Title = {How molecules evolve in eubacteria}, Volume = 17, Year = 2000} @article{lockhart05, Author = {P. Lockhart and M. Steel}, Journal = {Systematic Biology}, Pages = {948-951}, Title = {A tale of two processes}, Volume = 54, Year = 2005} @article{lopez99, Author = {P. Lopez and P. Forterre and H. Philippe}, Journal = {Journal of Molecular Evolution}, Pages = {496-508}, Title = {The root of the tree of life in the light of the covarion model}, Volume = 49, Year = 1999} @article{lopez02, Author = {P. Lopez and D. Casane and H. Philippe}, Journal = {Molecular Biology and Evolution}, Pages = {1-7}, Title = {Heterotachy, an important process of protein evolution}, Volume = 19, Year = 2002} @article{lundy, Author = {M. Lundy}, Journal = {Biometrika}, Number = 1, Pages = {191-198}, Title = {Applications of the annealing algorithm to combinatorial problems in statistics}, Utilisateur = {Gilles Caraux and Fernando Carvalho}, Volume = 72, Year = 1985} @article{lundy, Author = {M. Lundy}, Journal = {Biometrika}, Number = 1, Pages = {191-198}, Title = {Applications of the annealing algorithm to combinatorial problems in statistics}, Utilisateur = {Gilles Caraux and Fernando Carvalho}, Volume = 72, Year = 1985} @article{lynch00, Author = {M. Lynch and J. Conery}, Journal = {Science}, Pages = {1151-1155}, Title = {The evolutionary fate and consequences of duplicated genes}, Volume = 290, Year = 2000} @article{lynch03, Author = {M. Lynch and J. Conery}, Journal = {Journal of Structural and Functional Genomics}, Pages = {35-44}, Title = {The evolutionary demography of duplicate genes}, Volume = 3, Year = 2003} @article{lynch03b, Author = {M. Lynch and J. Conery}, Journal = {Science}, Pages = {1401-1404}, Title = {The origins of genome complexity}, Volume = 302, Year = 2003} @article{lynch04, Author = {M. Lynch and J. Conery}, Journal = {Science}, Pages = {978b}, Title = {Reponse to Comment on \"The origins of genome complexity\"}, Volume = 306, Year = 2004} @article{maddison91, Author = {D. R. Maddison}, Journal = {Syst Zool}, Note = {interessant, grpes d'arbres relies entre eux}, Number = 3, Pages = {315-328}, Title = {The discovery and importance of multiple islands of most parsimonious trees}, Utilisateur = {Vincent}, Volume = 40, Year = 1991} @article{maddison97, Author = {D. Maddison and D. Swofford and W. Maddison}, Journal = {Systematic Biology}, Volume = 46, Number = 4, Pages = {590-621}, Title = {{NEXUS}: an extensible file format for systematic information}, Year = 1997} @article{maidak94, Author = {B.L. Maidak and N. Larsen and M.J. McCaughey and R. Overbeek and G.J. Olsen and K. Fogel and J. Blandy and C.R. Woese}, Journal = { Nucl. Acids. Res}, Pages = {3485-3487}, Title = {The {R}ibosomal {D}atabase {P}roject}, Volume = 22, Year = 1994} @article{maidak96, Author = {B.L. Maidak and G.J. Olsen and N. Larsen and R. Overbeek and M.J. McCaughey and C.R. Woese}, Journal = { Nucl. Acids. Res}, Pages = {82-85}, Title = {The {R}ibosomal {D}atabase {P}roject ({RDP})}, Volume = 24, Year = 1996} @article{maidak97, Author = {B.L. Maidak and G.J. Olsen and N. Larsen and R. Overbeek and M.J. McCaughey and C.R. Woese}, Journal = { Nucl. Acids. Res}, Pages = {109-111}, Title = {The {RDP} ({R}ibosomal {D}atabase {P}roject)}, Volume = 25, Year = 1997} @article{maidak99, Author = {B.L. Maidak and J.R. Cole and C.T. Parker and G.M. Garrity and N. Larsen and B. Li and T.G. Lilburn and M.J. McCaughey and G.J. Olsen and R. Overbeek and S. Pramanik and T.M. Schmidt and J.M. Tiedje and CR Woese}, Journal = { Nucl. Acids. Res}, Pages = {171-173}, Title = {A new version of the {RDP} ({R}ibosomal {D}atabase {P}roject)}, Volume = 27, Year = 1999} @article{maidak00, Author = {B. L. Maidak and J. R. Cole and T. G. Lilburn and C. T. Parker and P. R. Saxman and J. M. Stredwick and G. M. Garrity and B. Li and G. J. Olsen and S. Pramanik and T. M. Schmidt and J. M. Tiedje}, Journal = {Nucl. Acids. Res}, Pages = {173-174}, Title = {The {RDP} ({R}ibosomal {D}atabase {P}roject) continues}, Volume = 28, Year = 2000} @article{maidak01, Author = {B. L. Maidak and J. R. Cole and T. G. Lilburn and C. T. Parker and P. R. Saxman and R. J. Farris and G. M. Garrity and G. J. Olsen and T. M. Schmidt and J. M. Tiedje}, Journal = {Nucl. Acids. Res}, Pages = {173-174}, Title = {The {RDP}-II ({R}ibosomal {D}atabase {P}roject)}, Volume = 29, Year = 2001} @article{manske87, Author = { Charles L. Manske and David J. Chapman}, Journal = {Journal of Molecular Evolution}, Pages = {226-251}, Title = {Nonuniformity of Nucleotide Substitution Rates in Molecular Evolution: Computer Simulation and Analysis of 5S Ribosomal Sequences}, Utilisateur = {Guillaume Andrieu}, Volume = 26, Year = 1987} @article{margush81, Author = {T. Margush and F.R. McMorris}, Journal = {Bulletin of Math. Biol.}, Number = 2, Pages = {239-244}, Title = {Consensus n-trees}, Volume = 43, Year = 1981} @article{massingham05, title={Detecting amino acid sites under positive selection and purifying selection}, author={Massingham, Tim and Goldman, Nick}, journal={Genetics}, volume={169}, number={3}, pages={1753--1762}, year={2005}, publisher={Genetics Soc America} } @phdthesis{mau96, Author = {B. Mau}, School = {Wiscontin University}, Title = {Bayesian phylogenetic inference via Markov Chain {M}onte {C}arlo methods}, Year = 1996} @article{meacham81, Author = {C. Meacham}, Journal = {Taxon}, Pages = {591-600}, Title = {A manual method for character compatibility}, Volume = 30, Year = 1981} @article{metropolis53, Author = {N. Metropolis and A.W. Rosenbluth and M.N. Rosenbluth and A.H. Teller and E. Teller}, Journal = {J. of Chem. Phys.}, Pages = {1087-1092}, Title = {Equation of State Calculations by Fast Computing Machines}, Volume = 21, Year = 1953} @article{messier97, Author = {W. Messier and C.-B. Stewart}, Journal = {Nature}, Pages = {151-154}, Title = {Episodic adaptative evolution of primate lysozymes}, Volume = 385, Year = 1997} @article{misof02, Author = {B. Misof and C. Anderson and T. Buckley and D. Erpenbeck and A. Rickert and K. Misof}, Journal = {Journal of Molecular Evolution}, Pages = {330-340}, Title = {An empirical analysis of mt 16S r{RNA} covarion-like evolution in insects: site-specific rate variation is clustered and frequently detected}, Volume = 56, Year = 2002} @article{mitchison95, Author = {G. Mitchison and R. Durbin}, Journal = {Journal of Molecular Evolution}, Pages = {1139-1151}, Title = {Tree-based maximum likelihood substitution matrices and hidden Markov model}, Volume = 41, Year = 1995} @book{miyamoto91, Address = {New York - Oxford}, Editor = {Michael M. Miyamoto and Joel Cracraft}, Publisher = {Oxford University Press}, Title = {{P}hylogenic {A}nalysis of {DNA} {S}equences}, Utilisateur = {Guillaume Andrieu}, Year = 1991} @article{miyata81, Author = { Takashi Miyata and Teruo Yasunaga}, Journal = {Genetics}, Pages = {641-657}, Title = {Molecular Evolution of m{RNA} : A Method for estimating Evolutionary Rates of Synonymous and Amino Acid Substitutions from Homologous Nucleotide Sequences and its Application }, Utilisateur = {Guillaume Andrieu}, Volume = 98, Year = 1981} @book{mood, Address = {Paris}, Author = {Alexander Mood et Franklin A. Graybill}, Publisher = {Dunod}, Title = {Introduction a la {S}tatistique {T}heorique}, Year = 1973} @article{moore73, Author = {G. W. Moore, J. Barnabas, M. Goodman}, Journal = {Journal of Theoretical Biology}, Pages = {459-485}, Title = {A Method For Constructing Maximum Parsimony Ancestral Amino Acid Sequences on a Given Network}, Volume = 38, Year = 1973} @techreport{moulton96, Author = {V. Moulton and M.A. Steel}, Institution = {Univ. of Canterbury}, Number = 148, Title = {Retractions of finite distance functions onto tree metrics}, Year = 1996} @article{muller00, Author = {T. Muller and M. Vingron}, Journal = {Journal of Computational Biology}, Pages = {761-776}, Title = {Modeling amino acid replacement.}, Volume = 7, Year = 2000} @article{mullis87, Author = {K.B. Mullis and F.A. Faloona}, Journal = {Methods. in Enzym.}, Pages = {335-350}, Title = {Specific synthesis of {DNA} in vitro via polymerase catalyzed chained reaction}, Volume = 155, Year = 1987} @article{murphy01, Author = {W. J. Murphy and E. Eizirik and W. E. Johnson and Zhang Y.P. and O.A. Ryder and S.J. O'Brien}, Journal = {Nature}, Pages = {614-618}, Title = {Molecular phylogenetics and the origins of placental mammals}, Volume = 409, Year = 2001} @article{murphy01b, Author = {M. Murphy and E. Eizirik and S. O'Brien and O. Madsen and M. Scally and C. Douady and E. Teeling and O. Ryder and M. Stanhope and W. de Jong and M. Springer}, Journal = {Science}, Pages = {2348-2351}, Title = {Resolution of the early placental mammal radiation using Bayesian phylogenetics}, Volume = 294, Year = 2001} @article{muse94, Author = {S. Muse and B. Gaut}, Journal = {Molecular Biology and Evolution}, Pages = {715-724}, Title = {A likelihood approach for comparing synonymous and nonsynonymous nucleotide substitution rates, with application to the chloroplast genome}, Volume = 11, Year = 1994} @incollection{muse95, Address = {Penn. State Univ.}, Author = {S. V. Muse}, Booktitle = {Current Topics on Molecular Evolution}, Editor = {M. Nei and N. Takahata}, Pages = {115-124}, Publisher = {University Park}, Title = {Evolutionary analyses when nucleotides do not evolve independently}, Year = 1995} @article{muse95b, Author = {S. Muse}, Journal = {Genetics}, Pages = {1429-1439}, Title = {Evolutionary analyses of {DNA} sequences subject to constraints on secondary structure}, Volume = 139, Year = 1995} @article{otha93, Author = {T. Ohta}, Journal = {Genetics}, Pages = {1271-1276}, Title = {Pattern of nucleotide substitutions in growth hormone-prolactin gene family: a paradigm for evolution by gene duplication}, Volume = 134, Year = 1993} @article{navidi91, Author = {W. C. Navidi and G. A. Churchill and A. von Haeseler}, Journal = {Molecular Biology and Evolution}, Pages = {128-143}, Title = {Methods for infering phylogenies from nucleic acid sequence data by using maximum likelihood and linear invariants}, Utilisateur = {Gilles Caraux}, Volume = 8, Year = 1991} @article{navidi92, Author = {W. C. Navidi and L. Beckett-Lemus}, Journal = {Molecular Biology and Evolution}, Pages = {1163-1175}, Title = {The effect of unequal transversion rates on the accuracy of evolutionary parsimony}, Utilisateur = {Gilles Caraux}, Volume = 9, Year = 1992} @article{needleman70, Author = {S. G. Needleman and C. D. Wunsch}, Journal = {Journal of Molecular Biology}, Pages = {443-453}, Title = {A general method applicable to the search for similarities in the amino acid sequence of two proteins}, Volume = 48, Year = 1970} @article{nei79, Author = {Masatoshi Nei and Wen Hsiung Li}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Number = 10, Pages = {5269-5273}, Title = {Mathematical model for studying genetic variation in terms of restriction endonucleases}, Utilisateur = {Gilles Caraux}, Volume = 76, Year = 1979} @article{nei81, Author = {Masatoshi Nei and Fumo Tajima}, Journal = {Genetics}, Pages = {145-163}, Title = {{DNA} polymorphism detectable by restriction endonucleases}, Utilisateur = {Gilles Caraux}, Volume = 97, Year = 1981} @article{nei85, Author = {M. Nei and J. C. Stephens and N. Saitou}, Journal = {Molecular Biology and Evolution}, Pages = {66-85}, Title = {Methods for computing the standard errors of branching points in an evolutionary tree and their application to molecular data from humans and apes}, Volume = 2, Year = 1985} @article{nei86, Author = {M. Nei and T. Gojobori}, Journal = {Molecular Biology and Evolution}, Pages = {418-426}, Title = {Simple methods for estimating the number of synonymous and nonsynonymous nucleotide substitutions}, Volume = 3, Year = 1986} @article{nei89, Author = {Masatoshi Nei and L. Jin}, Journal = {Molecular Biology and Evolution}, Pages = {290-300}, Title = {Variance of the averages numbers of substitutions within and between populations}, Utilisateur = {Ne Obt}, Volume = 6, Year = 1989} @incollection{nei91, Author = {M. Nei}, Booktitle = {Phylogenetic analysis of {DNA} sequences}, Editor = {M.M. Miyamoto and J. Cracraft}, Publisher = {Oxford Univ. Press}, Title = {Relative efficiencies of different tree-making methods for molecular data}, Year = 1991} @article{nei92, Author = {Masatoshi Nei}, Journal = {Molecular Biology and Evolution}, Number = 6, Pages = {1176-1178}, Title = {Age of the common ancestor of Human Mitochondrial {DNA}}, Utilisateur = {Gilles Caraux}, Volume = 9, Year = 1992} @article{newton04, Author = {M. Newton and A. Noueiry and D. Sarkar and P. Ahlquist}, Journal = {Biostatistics}, Pages = {155-176}, Title = {Detecting differential expression with a semiparametric hierarchical mixture method}, Volume = 5, Year = 2004} @article{nielsen98, Author = {R. Nielsen and Z. Yang}, Journal = {Genetics}, Pages = {929-936}, Title = {Likelihood models for detecting positively selected amino acid sites and application to the {HIV}-1 envelope gene}, Volume = 148, Year = 1998} @book{nutall04, Address = {Cambridge}, Author = {G.H.F. Nutall}, Publisher = {Cambridge Univ. Press}, Title = {Blood immunity and blood relationship}, Year = 1904} @book{nr, Address = {Cambridge}, Author = {W. Press and B. Flannery and S. Teukolsky and W. Vetterling}, Publisher = {Press Syndicate of the University of Cambridge}, Title = {Numerical Recipes in C.}, Year = 1988} @article{olsen94, Author = {G. Olsen and H. Matsuda and R. Hagstrom and R. Overbeek}, Journal = {Computer Applications in the Biosciences (CABIOS)}, Pages = {41-48}, Title = {{fastDNAml}: a tool for construction of phylogenetic trees of {DNA} sequences using maximum likelihood}, Volume = 10, Year = 1994} @article{fastdnaml, Author = {G. J. Olsen and H. Matsuda and R. Hagstrom and R. Overbeek}, Journal = {Computer Applications in the Biosciences (CABIOS)}, Pages = {41-48}, Title = {{fastDNAml}: a tool for construction of phylogenetic trees of {DNA} sequences using maximum likelihood}, Volume = 10, Year = 1994} @incollection{neyman71, Address = {New York}, Author = {J. Neyman}, Booktitle = {Statistical decision theory and related topics}, Editor = {S. Gupta and J. Yackel}, Pages = {1-27}, Publisher = {Academic Press}, Title = {Molecular studies of evolution: a source of novel statistical problems}, Year = 1971} @article{ota00, Author = {S. Ota and W.-H. Li}, Journal = {Molecular Biology and Evolution}, Pages = {1401-1409}, Title = {{NJML}: a Hybrid Algorithm for the Neighbor-Joining and Maximum-Likelihood Methods}, Volume = 17, Year = 2000} @article{ota01, Author = {S. Ota and W.-H. Li}, Journal = {Molecular Biology and Evolution}, Pages = {1983-1992}, Title = {{NJML+}: an extension of the {NJML} method to handle protein sequence data and computer software implementation}, Volume = 18, Year = 2001} @article{ota00b, Author = {R. Ota and P. Waddell and M. Hasegawa and H. Shimodaira and H. Kishino}, Journal = {Molecular Biology and Evolution}, Pages = {798-803}, Title = {Appropriate likelihood ratio tests and marginal distribution for evolutionary tree models with constraints on parameters}, Volume = 17, Year = 2000} @article{otto00, Author = {S. Otto and J. Whitton}, Journal = {Annual Review of Genetics}, Pages = {401-437}, Title = {Polyploid incidence and evolution}, Volume = 34, Year = 2000} @book{page98, Address = {Osney Mead, Oxford}, Author = {Roderick Page and Eward Holmes}, Publisher = {Blackwell Science Ltd}, Title = {Molecular Evolution: a phylogenetic approach}, Year = 1998} @article{pauplin00, Author = {Y. Pauplin}, Journal = {Journal of Molecular Evolution}, Pages = {41-47}, Title = {Direct calculation of a tree length using a distance matrix}, Volume = 51, Year = 2000} @article{penny87, Author = {David Penny and Michael D. Hendy and I. M. Henderson}, Journal = {Cold Spring Harbor Symposia on Quantitative Biology}, Pages = {857-862}, Title = {Reliability of Evolutionary Trees}, Utilisateur = {Gilles Caraux}, Volume = 52, Year = 1987} @incollection{penny91, Author = {D. Penny and M.D. Hendy and M.A. Steel}, Booktitle = {Phylogenetic analysis of {DNA} sequences}, Editor = {M. M. Miyamoto and J. Cracraft}, Pages = {155-183}, Title = {Testing the theory of descent}, Year = 1991} @article{penny92, Author = {David Penny and Michael D. Hendy and Michael A. Steel}, Journal = {Tree}, Pages = {73-78}, Title = {Progress with Methods for Constructing Evolutionary Trees}, Utilisateur = {Gilles Caraux and Guillaume Andrieu or Vincent}, Volume = 7, Year = 1992} @article{penny01, Author = {D. Penny and B. McComish and M. Charleston and M. Hendy}, Journal = {Journal of Molecular Evolution}, Pages = {711-723}, Title = {Mathematical elegance with biochemical realism: the covarion model of molecular evolution}, Volume = 53, Year = 2001} @article{hobacgen, Author = {G. Perri{\`e}re and L. Duret and M. Gouy}, Journal = {Genome Research}, Pages = {379-385}, Title = {{HOBACGEN}: database system for comparative genomics in bacteria}, Volume = 10, Year = 2000} @article{hovergen, Author = {L. Duret and D. Mouchiroud and M. Gouy}, Journal = {Nucleic Acids Research}, Pages = {2360-2365}, Title = {{HOVERGEN}, a database of homologous vertebrate genes}, Volume = 22, Year = 1994} @article{li85, Author = {W.-H. Li and C.-I Wu and C.-C Luo}, Journal = {Molecular Biology and Evolution}, Pages = {150-174}, Title = {A new method for estimating synonymous and non-synonymous rates of nucleotide substitutions considering the relative likelihood of nucleotide and codon changes}, Volume = 2, Year = 1985} @article{pagel04, Author = {M. Pagel and A. Meade}, Journal = {Systematic Biology}, Pages = {571-581}, Title = {A phylogenetic mixture model for detecting pattern-heterogeneity in gene sequence or character-state data}, Volume = 53, Year = 2004} @article{phillips02, Author = {M. Phillips and D. Penny}, Journal = {Molecular Phylogenetics and Evolution}, Pages = {171-185}, Title = {The root of the mammalian tree inferred from whole mitochondrial genomes}, Volume = 28, Year = 2002} @article{philippe97, Author = {H. Philippe}, Journal = {Journal of Molecular Evolution}, Pages = {712-715}, Title = {Rodent monophyly: pitfalls of molecular phylogenies}, Volume = 45, Year = 1997} @article{philippe00, Author = {H. Philippe and P. Lopez and H. Brinkman and K. Budin and A. Germot and J. Laurent and D. Moreira and M. Muller and H. Le Guyader}, Journal = {Proceeding of the Royal Society B: Biological Sciences}, Pages = {1213-1221}, Title = {Early branching or fast evolving eukaryotes ? An answer based on slowly evolving positions}, Volume = 267, Year = 2000} @article{philippe00b, Author = {H. Philippe}, Journal = {Protist}, Pages = {307-316}, Title = {Opinion : long branch attraction and protist phylogeny}, Volume = 151, Year = 2000} @article{philippe05, Author = {H. Philippe and Y. Zhou and H. Brinkmann and N. Rodrigue and F. Delsuc}, Journal = {BMC Evolutionary Biology}, Pages = {http://www.biomedcentral.com/1471-2148/5/50}, Title = {Heterotachy and long-branch attraction in phylogenetics}, Year = 2005} @article{pollock99, Author = {D. Pollock and W. Taylor and N. Goldman}, Journal = {Journal of Molecular Biology}, Pages = {187-198}, Title = {Co-evolving protein residues: maximum likelihood analysis and relationship to structure}, Volume = 287, Year = 1999} @article{posada98, Author = {D. Posada and K. Crandall}, Journal = {Bioinformatics}, Pages = {817-918}, Title = {Modeltest: testing the model of {DNA} substitution}, Volume = 14, Year = 1998} @article{posada01, title={Selecting models of nucleotide substitution: an application to human immunodeficiency virus 1 (HIV-1)}, author={Posada, D. and Crandall, K.A.}, journal={Molecular Biology and Evolution}, volume={18}, number={6}, pages={897--906}, year={2001}, publisher={SMBE} } @Article{poux06, Author="Poux, C. and Chevret, P. and Huchon, D. and de Jong, W. W. and Douzery, E. J. ", Title="{{A}rrival and diversification of caviomorph rodents and platyrrhine primates in {S}outh {A}merica}", Journal="Syst. Biol.", Year="2006", Volume="55", Pages="228--244", Month="Apr" } @techreport{prum92, Author = {Bernard Prum and Fran{{\c C}}ois Rodolphe and Elisabeth de Turckheim}, Institution = {INRA}, Month = {October}, Note = {{I}nfluence du {V}oisinage sur l'{E}volution d'une {S{\'e}}quence d'{ADN}}, Title = {{F}inding words with unexpected frequencies in {DNA} sequences}, Year = {1992}} @article{pupko02, Author = {T. Pupko and N. Galtier}, Journal = {Proceedings of The Royal Society B: Biological Sciences}, Pages = {1313-1316}, Title = {A covarion-based method for detecting molecular adaptation: application to the evolution of primate mitochondrial genomes}, Volume = 269, Year = 2002} @article{purvis97, Author = {A. Purvis and D. L. J. Quicke}, Journal = {Trends in Ecology and Evolution}, Number = 2, Pages = {49-50}, Title = {Building phylogenies: are the big easy ?}, Volume = 12, Year = 1997} @article{qu83, Author = {L.H. Qu and B. Michot and J.P. Bachellerie}, Journal = {Nucleic Acids Research}, Pages = {5903-5920}, Title = {Improved methods for structure probing in large RNAs: a rapid heterologous sequencing approach is coupled to the direct mapping of nuclease accessible sites. Application to the 5' terminal domain of eukaryotic}, Volume = 11, Year = 1983} @article{quesenberry64, Author = {C. P. Quesenberry and D. C. Hurst}, Journal = {Technometrics}, Month = {MAY}, Number = 2, Pages = {191-195}, Title = {Large Sample Simultaneous Confidence Intervals for Multinomial Proportions }, Volume = 6, Year = 1964} @article{rannala96, Author = {B. Rannala and Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {304-311}, Title = {Probability distribution of molecular evolutionary trees: a new method of phylogenetic inference}, Volume = {43}, Year = 1996} @Article{rannala07, Author="Rannala, B. and Yang, Z. ", Title="{{I}nferring speciation times under an episodic molecular clock}", Journal="Syst. Biol.", Year="2007", Volume="56", Pages="453--466", Month="Jun" } @article{ranwez01, Author = {V. Ranwez and O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {1103-11016}, Title = {Quartet-based phylogenetic inference: improvements and limits.}, Volume = {18}, Year = 2001} @article{ranwez02, Author = {V. Ranwez and O. Gascuel}, Journal = {Molecular Biology and Evolution}, Pages = {1952-1963}, Title = {Improvement of Distance-Based Phylogenetic Methods by a Local Maximum Likelihood Approach Using Triplets}, Volume = {19}, Year = 2002} @article{rasmol, Author = {R. Sayle and J. Milner-White}, Journal = {Trends in Biochemical Sciences}, Pages = {374}, Title = {{R}as{M}ol: Biomolecular graphics for all}, Volume = {20}, Year = 1995} @phdthesis{ranwezthese, Author = {V. Ranwez}, School = {Universit{\'e} Montpellier II}, Title = {M{\'e}thodes efficaces pour reconstruire des phylog{\'e}nies suivant le principe du maximum de vraisemblance}, Year = 2002} @article{rdp, Author = {B. L. Maidak and J.R. Cole and T.G. Lilburn and C.T. Parker Jr. and P.R. Saxman and R.J. Farris and G.M. Garrity and G.J. Olsen and T.M. Schmidt and J.M. Tiedje}, Journal = {Nucleic Acids Research}, Pages = {173-174}, Title = {The {RDP}-II ({R}ibosomal {D}atabase {P}roject)}, Volume = {29}, Year = 2001} @article{ren05, Author = {F. Ren and H. Tanaka and Z. Yang}, Journal = {Systematic Biology}, Pages = {808-818}, Title = {An empirical examination of the utility of codon-substitution models in phylogeny reconstruction}, Volume = 54, Year = 2005} @book{renyi66, Address = {Paris}, Author = {A. Renyi}, Publisher = {Dunod}, Title = {{C}alcul des {P}robabilites}, Year = 1966} @article{reyes98, Author = {A. Reyes and G. Pesole and C. Saccone}, Journal = {Molecular Biology and Evolution}, Pages = {499-505}, Title = {Complete mitochondrial {DNA} sequence of the fat dormouse, {G}lis glis: further evidence of rodent paraphyly}, Volume = {15}, Year = {1998}} @article{reyes00, Author = {A. Reyes and G. Pesole and C. Saccone}, Journal = {Gene}, Pages = {177-187}, Title = {Long-branch attraction phenomenon and the impact of among-site rate variation on rodent phylogeny}, Volume = {259}, Year = {2000}} @article{reyes04, Author = {A. Reyes and C. Gissi and F. Catzeflis and E. Nevo and G. Pesole and C. Saccone}, Journal = {Molecular Biology and Evolution}, Pages = {397-403}, Title = {Congruent mammalian trees from mitochondrial and nuclear genes using Bayesian methods}, Volume = {21}, Year = {2004}} @article{rice97, Author = {K. Rice and M. J. Donoghue and R. G. Olmstead}, Journal = {Systematic Biology}, Pages = {554-563}, Title = {Analyzing large data sets: {\it rbcL} 500 revisited}, Volume = {46}, Year = {1997}} @article{robinson71, Author = {D. Robinson}, Journal = {J. Combinatorial Theory Ser B}, Pages = {105-119}, Title = {Comparison of labeled trees with valency three}, Utilisateur = {Gilles Caraux}, Volume = 11, Year = 1971} @incollection{robinson79, Address = {Berlin}, Author = {D. Robinson and L. Foulds}, Booktitle = {Lectures Notes in Mathematics}, Pages = {119-126}, Publisher = {Springer}, Title = {Comparison of weighted labeled trees}, Utilisateur = {Gilles Caraux}, Volume = 748, Year = 1979} @article{robinson81, Author = {D. F. Robinson and L. R. Foulds}, Journal = {Mathematical Biosciences}, Pages = {131-147}, Title = {Comparison of phylogenetic trees}, Utilisateur = {Gilles Caraux et Vincent}, Volume = 53, Year = 1981} @Article{robinson98, Author="Robinson, M. and Gouy, M. and Gautier, C. and Mouchiroud, D. ", Title="{{S}ensitivity of the relative-rate test to taxonomic sampling}", Journal="Mol. Biol. Evol.", Year="1998", Volume="15", Pages="1091--1098", Month="Sep" } @article{gharib13, title={The branch-site test of positive selection is surprisingly robust but lacks power under synonymous substitution saturation and variation in {GC}}, author={Gharib, Walid H and Robinson-Rechavi, Marc}, journal={Molecular Biology and Evolution}, volume={30}, number={7}, pages={1675--1686}, year={2013}, publisher={SMBE} } @article{zhang05, title={Evaluation of an improved branch-site likelihood method for detecting positive selection at the molecular level}, author={Zhang, J. and Nielsen, R. and Yang, Z.}, journal={Molecular Biology and Evolution}, volume={22}, number={12}, pages={2472--2479}, year={2005}, publisher={SMBE} } @incollection{rodrigo01, Address = {Boston, Mass.}, Author = {A. Rodrigo and E. Hanley and P. Goracke and G. Learn}, Booktitle = {Computational and evolutionary analysis of HIV molecular sequences}, Editor = {A. Rodrigo and G. Learn}, Pages = {1-17}, Publisher = {Kluwer Academic Publishers}, Title = {Sampling and processing {HIV} molecular sequences : a computatinal evolutionary biologist's perspective}, Year = 2001} @article{rodriguez90, Author = {F. Rodriguez and J. L. Olivier and A. Marin and J. R. Medina}, Journal = {Journal of Theoretical Biology}, Pages = {485-501}, Title = {The general stochastic model of nucleotide substitution}, Volume = 142, Year = 1990} @article{rodriguez03, Author = {F. Rodriguez-Trelles and R. Tarrio and F. Ayala}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {13413-13417}, Title = {Convergent neofunctionalization by positive Darwinian selection after ancient recurrent duplications of the xanthine dehydrogenase gene}, Volume = {100}, Year = {2003}} @article{rogers99, Author = {J. Rogers and D. Swofford}, Journal = {Molecular Biology and Evolution}, Pages = {1079-1085}, Title = {Multiple local maxima for likelihoods of phylogenetic trees: a simulation study}, Volume = {16}, Year = {1999}} @article{rohlf74, Author = {F. James Rohlf}, Journal = {Annual Review of Ecology and Systematics}, Pages = {101-113}, Title = {Methods of comparing classifications}, Utilisateur = {Gilles Caraux}, Volume = 5, Year = 1974} @article{rosenberg01, Author = {M. Rosenberg and S. Kumar}, Journal = {Molecular Biology and Evolution}, Pages = {1823-1827}, Title = {Traditional phylogenetic reconstruction methods reconstruct shallow and deep evolutionary relationship equally well}, Volume = 19, Year = 2001} @article{ross02, Author = {H. Ross and A. Rodrigo}, Journal = {Journal of Virology}, Pages = {11715-11720}, Title = {Immune-mediated positive selection drives human immunodeficiency virus type 1 molecular variation and predicts disease duration}, Volume = 76, Year = 2002} @book{ruegg, Address = {Lausanne}, Author = {Alan Ruegg}, Publisher = {Presses polytechniques romandes}, Series = {Methodes mathematiques pour l'ingenieur}, Title = {Processus Stochastiques}, Year = 1989} @Article{rutschmann07, Author="Rutschmann, F. and Eriksson, T. and Salim, K. A. and Conti, E. ", Title="{{A}ssessing calibration uncertainty in molecular dating: the assignment of fossils to alternative calibration points}", Journal="Syst. Biol.", Year="2007", Volume="56", Pages="591--608", Month="Aug" } @incollection{gascuel07, Title={Modelling the variability of evolutionary processes}, Author={Gascuel, O. and Guindon, S.}, Editor={Olivier Gascuel and Mike Steel}, Booktitle={Reconstructing Evolution: new mathematical and computational advances}, Pages={65--99}, Publisher={Oxford University Press}, Year={2007} } @article{slatkin91, title={Pairwise comparisons of mitochondrial DNA sequences in stable and exponentially growing populations.}, author={M. Slatkin and R. R. Hudson}, journal={Genetics}, volume={129}, number={2}, pages={555--562}, year={1991}, publisher={Genetics Soc America} } @article{rzhetsky92a, Author = {Andrey Rzhetsky and Masatoshi Nei}, Journal = {Molecular Biology and Evolution}, Pages = {945-967}, Title = {A simple method for estimating and testing minimum-evolution trees}, Utilisateur = {Olivier Gascuel et Guillaume Andrieu}, Volume = 9, Year = 1992} @article{rzhetsky92b, Author = {Andrey Rzhetsky and Masatoshi Nei }, Journal = {Journal of Molecular Evolution}, Pages = {367-375}, Title = {Statistical Properties of the Ordinary Least-Squares, Generalized Least-Squares, and Minimum-Evolution Methods of Phylogenetic Inference}, Utilisateur = {Guillaume Andrieu}, Volume = 35, Year = 1992} @article{rzhetsky93, Author = {A. Rzhetsky and M. Nei }, Journal = {Molecular Biology and Evolution}, Pages = {1073-1095}, Title = {Theoretical foundation of the minimum-evolution method of phylogenetic inference}, Volume = 10, Year = 1993} @article{rzhetsky94, Author = {A. Rzhetsky and M. Nei}, Journal = {Journal of Molecular Evolution}, Pages = {295-299}, Title = {Unbiaised estimates of the number of nucleotide substitutions when substitution rate varies among different sites}, Volume = 38, Year = 1994} @article{rzhetsky95, Author = {A. Rzhetsky and S. Kumar and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {163-167}, Title = {Four-cluster analysis: a simple method to test phylogenetic hypotheses}, Volume = 12, Year = 1995} @article{rzhetsky95b, Author = {A. Rzhetsky}, Journal = {Genetics.}, Number = 2, Pages = {771-83}, Title = {Estimating substitution rates in ribosomal RNA genes}, Volume = 141, Year = 1995} @article{rzhetsky96, Author = {A. Rzhetsky and T. Sitnikova}, Journal = {Molecular Biology and Evolution}, Pages = {1255-1265}, Title = {When is it Safe to use an Oversimplified Substitution Model in Tree-Making?}, Volume = 13, Year = 1996} @incollection{saccone90, Address = {New York}, Author = {Cecilia Saccone and Cecilia Lanave and Graziano Pesole and Giuliano Preperata }, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 35, Editor = {Russsell F. Doolittle}, Pages = {570-583}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Influence of Base Composition on Quantitative Estimates of Gene Evolution}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @article{saccone91, Author = {Cecilia Saccone and Graziano Pesole and Elisabetta Sbis\'{a} }, Journal = {Journal of Molecular Evolution}, Pages = {88-91}, Title = {the main regulatory region of mammalian mitochondria {DNA} : Stucture -function model and evilutionary pattern}, Utilisateur = {G. Andrieu}, Volume = 33, Year = 1991} @article{saitou87, Author = {N. Saitou and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {406-425}, Title = {The neighbor-joining method: a new method for reconstructing phylogenetic trees}, Volume = 4, Year = 1987} @article{nj, Author = {N. Saitou and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {406-425}, Title = {The neighbor-joining method: A new method for reconstruction phylogenetic trees}, Utilisateur = {Gilles Caraux}, Volume = 4, Year = 1987} @article{saitou88, Author = {N. Saitou}, Journal = {Journal of Molecular Evolution}, Pages = {261-273}, Title = {Property and efficiency of the maximum likelihood method for molecular phylogeny}, Utilisateur = {Gilles Caraux}, Volume = 27, Year = 1988} @article{saitou89, Author = {N. Saitou and T. Imanishi}, Journal = {Molecular Biology and Evolution}, Pages = {514-525}, Title = {Relative efficiencies of the {F}itch-{M}argoliash, {M}aximum-{P}arsimony, {M}aximum-{L}ikelihood, {M}inimum-{E}volution, and {N}eighbor-{J}oining methods of phylogenetic tree construction in obtaining the correct tree}, Volume = 6, Year = 1989} @incollection{saitou90, Address = {New York}, Author = {N. Saitou}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acid sequences}, Chapter = 36, Editor = {Russsell F. Doolittle}, Pages = {584-598}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Maximum Likelihood Methods}, Utilisateur = {Guillaume Andrieu}, Volume = 183, Year = 1990} @incollection{saitou91, Author = {N. Saitou}, Booktitle = {Statistical Methods in Biological and Medical Sciences}, Editor = {R. C. Rao and R. Chakraborty}, Pages = {317-346}, Publisher = {North-Holland}, Series = {Handbook of Statistics}, Title = {Statistical Methods for Phylogenetic Tree Reconstruction}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 8, Year = 1991} @article{salter01, Author = {L. Salter and D. Pearl}, Journal = {Systematic Biology}, Pages = {7-17}, Title = {Stochastic search strategy for estimation of maximum likelihood phylogenetic trees}, Volume = 50, Year = 2001} @article{sanderson94, Author = {M. Sanderson and M. Donoghue and W. Piel and T. Eriksson}, Title = {Tree{BASE}: a prototype database of phylogenetic analyses and an interactive tool for browsing the phylogeny of life}, Journal = {American Journal of Botany}, Volume = 81, Pages = {183}, Year = {1994} } @article{sanderson97, Author = {M. Sanderson}, Journal = {Molecular Biology and Evolution}, Pages = {1218-1231}, Title = {A nonparametric approach to estimating divergence times in the absence of rate constancy}, Volume = 14, Year = 1997} @article{sanderson02, Author = {M. Sanderson}, Journal = {Molecular Biology and Evolution}, Pages = {101-109}, Title = {Estimating absolute rates of molecular evolution and divergence times: a penalized likelihood approach}, Volume = 19, Year = 2002} @article{sanger77, Author = {F. Sanger and S. Nicklen and A.R. Coulson}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {5463-5467}, Title = {DNA sequencing with chain-terminating inhibitors}, Volume = 74, Year = 1977} @article{sankoff94, Author = {D. Sankoff and Y. Abel and J. Hein}, Journal = {Journal of Classification}, Pages = {209-232}, Title = {A tree - a hill; generalization of nearest-neighbor in phylogenetic optimization}, Utilisateur = {Vincent}, Volume = 11, Year = 1994} @inbook{saporta, Author = {G. Saporta}, Chapter = { No 5 Notions {\'e}l{\'e}mentaires sur les processus al{\'e}atoires}, Pages = {103-113}, Publisher = {Technip}, Title = {Probabilit{\'e}s analyse des donn{\'e}es et statistique}, Utilisateur = {Guillaume Andrieu}, Year = 1990} @article{sharp97, Author = {P. Sharp}, Journal = {Nature}, Pages = {111-112}, Title = {In search of molecular Darwinism}, Volume = 385, Year = 1997} @article{sharp87, Author = {P. Sharp and W.-H. Li}, Journal = {Journal of Molecular Evolution}, Pages = {1281-1295}, Title = {The codon adaptation index--a measure of directional synonymous codon usage bias, and its potential applications}, Volume = 15, Year = 1987} @article{scherer89, Author = {Siegfried Scherer}, Journal = {Molecular Biology and Evolution}, Pages = {436-441}, Title = {The relative-rate test of the molecular clock hypothesis : a note of caution}, Utilisateur = {Gilles Caraux}, Volume = 6, Year = 1989} @article{shankarappa99, Author = {R. Shankarappa and J. Margolick and S. Gange and A. Rodrigo and D. Upchurch and H. Farzadegan and P. Gupta and C. Rinaldo and G. Learn and X. He and X.-L Huang and J. Mullins }, Journal = {Journal of Virology}, Pages = {10489-10502}, Title = {Consistent viral evolutionary changes associated with the progression of human immunodeficiency virus type 1 infection}, Volume = 73, Year = 1999} @article{schoniger93, Author = {Michael Sch{\"o}niger and Arndt von Haesler }, Journal = {Molecular Biology and Evolution}, Pages = {471-483}, Title = {A simple method to improve the reliability of tree reconstruction}, Utilisateur = {G. Andrieu}, Volume = 10, Year = 1993} @article{schoniger94, Author = {M. Sch{\"o}niger and A. von Haesler }, Journal = {Molecular Phylogeny and Evolution}, Pages = {240-247}, Title = {A stochastic model for the evolution of autocorrelated {DNA} sequences}, Volume = 3, Year = 1994} @article{schoniger95, Author = {M. Sch{\"o}niger and A. von Haesler }, Journal = {Systematic Biology}, Pages = {533-547}, Title = {Performance of the maximum likelihood, neighbor joining, and maximum parsimony methods when sequence sites are not independent}, Volume = 44, Year = 1995} @article{schwarz78, Author = {G. Schwarz}, Journal = {The annals of statistics}, Pages = {461-464}, Title = {Estimating the dimension of a model}, Volume = 6, Year = 1978} @article{sibley84, Author = {Charles G. Sibley and Jon E. Ahlquist}, Journal = {Journal of Molecular Evolution}, Pages = {2-15}, Title = {the phylogeny of the hominoid primates, as indicated by {DNA-DNA} hybridization}, Utilisateur = {Gilles Caraux}, Volume = 20, Year = 1984} @article{sibley87, Author = {Charles G. Sibley and Jon E. Ahlquist}, Journal = {Journal of Molecular Evolution}, Pages = {99-121}, Title = {{DNA} hybridization evidence of hominoid phylogeny : results from expanded set}, Utilisateur = {Gilles Caraux}, Volume = 26, Year = 1987} @book{paup, Address = {Sunderland, MA}, Author = {D. Swofford}, Publisher = {Sinauer}, Title = {{PAUP$^*$}: Phylogenetic Analysis by Parsimony$^*$ and other methods}, Year = 1999} @book{bambe, Address = {Duquesne University}, Author = {D. Simon and B. Larget}, Publisher = {Department of Mathematics and Computer Science}, Title = {Bayesian analysis in molecular biology and evolution (BAMBE), version 2.03 beta}, Year = 2000} @article{sarich67, Author = {V. Sarich and A. Wilson}, Journal = {Science}, Pages = {1200-1203}, Title = {Immunological time scale for hominid evolution}, Volume = 158, Year = 1967} @article{self87, Author = {S. Self and K. Liang}, Journal = {Journal of the American Statistical Association}, Pages = {605--610}, Title = {Asymptotic properties of maximum likelihood estimators and likelihood ratio tests under nonstandard conditions}, Volume = 82, Year = 1987} @article{shan09, title={Evolution of plant {MADS} box transcription factors: evidence for shifts in selection associated with early angiosperm diversification and concerted gene duplications}, author={Shan, H. and Zahn, L. and Guindon, S. and Wall, P.K. and Kong, H. and Ma, H. and DePamphilis, C.W. and Leebens-Mack, J. and others}, journal={Molecular Biology and Evolution}, volume={26}, number={10}, pages={2229--2244}, year={2009}, publisher={SMBE} } @article{murrell12, title={Detecting individual sites subject to episodic diversifying selection}, author={Murrell, Ben and Wertheim, Joel O and Moola, Sasha and Weighill, Thomas and Scheffler, Konrad and Pond, Sergei L Kosakovsky}, journal={PLoS Genetics}, volume={8}, number={7}, pages={e1002764}, year={2012}, publisher={Public Library of Science} } @article{pond05, title={Not so different after all: a comparison of methods for detecting amino acid sites under selection}, author={Kosakovsky Pond, Sergei and Frost, Simon}, journal={Molecular Biology and Evolution}, volume={22}, number={5}, pages={1208--1222}, year={2005}, publisher={SMBE} } @article{shimodaira99, Author = {H. Shimodaira and M. Hasegawa}, Journal = {Molecular Biology and Evolution}, Pages = {1114-1116}, Title = {Multiple comparisons of log-likelihoods with applications to phylogenetic inference}, Volume = 16, Year = 1999} @article{shriner04, Author = {D. Shrinner and A. Rodrigo and D. Nickle and J. Mullins}, Journal = {Genetics}, Pages = {1573-1583}, Title = {Pervasive genomic recombination of {HIV-1} \mbox{\it in vivo}}, Volume = {167}, Year = 2004} @article{sokal58, Author = {R. R. Sokal and C. D. Michener}, Journal = {University of Kansas Science Bulletin}, Pages = {1409-1438}, Title = {A statistical method for evaluating systematic relationships}, Volume = {38}, Year = {1958}} @article{sourdis87, Author = {J. Sourdis and C. Krimbas}, Journal = {Molecular Biology and Evolution}, Pages = {159-166}, Title = {Accuracy of phylogenetic trees estimated from {DNA} sequence data}, Volume = {4}, Year = {1987}} @article{springer01, Author = {M. Springer and R. De Bry and C. Douady and H. Amrine and O. Madsen and W. de Jong and M. Stanhope.}, Journal = {Molecular Biology and Evolution}, Pages = {132-143}, Title = {Mitochondrial versus nuclear gene sequences in deep-level mammalian phylogeny reconstruction}, Volume = {18}, Year = {2001}} @article{sourdis88, Author = {J. Sourdis and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {298-311}, Title = {Relative efficiencies of the maximum parsimony and distance-based methods in obtaining the correct phylogenetic tree}, Volume = {5}, Year = {1988}} @article{srs, Author = {T. Etzold and P. Argos}, Journal = {CABIOS}, Pages = {49-57}, Title = {{SRS}-an indexing and retrieval tool for flat file data libraries}, Volume = {9}, Year = {1993}} @article{spencer05, Author = {M. Spencer and E. Susko and A. Roger}, Journal = {Molecular Biology and Evolution}, Pages = {1161-1164}, Title = {Likelihood, parsimony, and heterogeneous evolution}, Volume = {22}, Year = {2005}} @article{squires07, author = {B. Squires and C. Macken and A. Garcia-Sastre and S. Godbole and J. Noronha and V. Hunt and R. Chang and C. Larsen and E. Klem and K. Biersack and R. Scheuermann}, title = {{B}io{H}ealth{B}ase: informatics support in the elucidation of influenza virus host-pathogen interactions and virulence}, journal = {Nucleic Acids Research}, volume = {Database issue}, year = {2007} } @article{raxml, Author = {A. Stamatakis}, Journal = {Bioinformatics}, Pages = {2688-2690}, Title = {{RAxML-VI-HPC}: Maximum Likelihood-based Phylogenetic Analyses with Thousands of Taxa and Mixed Models}, Volume = 22, Year = 2006} @article{stamatakis06, Author = {A. Stamatakis}, Journal = {Bioinformatics}, Pages = {2688-2690}, Title = {{RAxML-VI-HPC}: Maximum Likelihood-based Phylogenetic Analyses with Thousands of Taxa and Mixed Models}, Volume = 22, Year = 2006} @article{st77, Author = {S. Sattah and A. Tversky}, Journal = {Psychometrika}, Pages = {319-345}, Title = {Additive similarity trees}, Volume = 42, Year = 1977} @article{steel92, Author = {M. Steel}, Journal = {J. of Classification}, Pages = {91-116}, Title = {The complexity of reconstructing trees from qualitative characters and subtrees}, Utilisateur = {Vincent}, Volume = 9, Year = 1992} @article{steel93, Author = {M.A. Steel and D. Penny}, Journal = {Systematic Biology}, Number = 2, Pages = {126-141}, Title = {Distributions of tree comparison metrics - some new results}, Volume = 42, Year = 1993} @article{steel94, Author = {M. Steel}, Journal = {Systematic Biology}, Pages = {560-564}, Title = {The maximum likelihood point for a phylogenetic tree is not unique}, Volume = 43, Year = 1994} @article{steel00a, Author = {M. Steel and D. Penny}, Journal = {Molecular Biology and Evolution}, Pages = {839-50}, Title = {Parsimony, likelihood, and the role of models in molecular phylogenetics}, Volume = 17, Year = 2000} @article{steel00b, Author = {M. Steel and D. Huson and P. Lockhart}, Journal = {Systematic Biology}, Pages = {225-232}, Title = {Invariable site models and their use in phylogeny reconstruction}, Volume = 49, Year = 2000} @article{steel05, Author = {M. Steel}, Journal = {Trends in Genetics}, Pages = {307-309}, Title = {Should phylogenetic models be trying to ``fit an elephant''?}, Volume = 21, Year = 2005} @incollection{stewart93, Author = {Caro-Beth Stewart}, Booktitle = {Nature}, Month = {february}, Pages = {603-607}, Title = {The Powers and pitfalls of parsimony}, Utilisateur = {Vincent}, Volume = 361, Year = 1993} @article{stoffberg10, author = {S. Stoffberg and D. Jacobs and I. Mackie and C. Matthee}, title = {Molecular phylogenetics and historical biogeography of Rhinolophus bats}, journal = {Molecular Phylogenetics and Evolution}, Volume = 54, Pages = {1-9}, Year = 2010} @article{strimmer96, Author = {K. Strimmer and A. von Haeseler}, Journal = {Molecular Biology and Evolution}, Pages = {964-969}, Title = {Quartet puzzling: a quartet maximum-likelihood method for reconstructing tree topologies}, Volume = 13, Year = 1996} @article{strimmer97, Author = {K. Strimmer and N. Goldman and A. von Haeseler}, Journal = {Molecular Biology and Evolution}, Pages = {210-211}, Title = {Baysian Probabilities and Quartet puzzling}, Volume = 14, Year = 1997} @article{strimmer00, Author = {K. Strimmer and V. Moulton}, Journal = {Molecular Biology and Evolution}, Pages = {875-881}, Title = {Likelihood analysis of phylogenetic networks using directed graphical models}, Volume = 17, Year = 2000} @article{studier88, Author = {J. Studier and K. Kepler}, Journal = {Molecular Biology and Evolution}, Pages = {729-731}, Title = {A note on the neighbor-joining algorithm of Saitou and Nei}, Volume = 5, Year = 1988} @article{sullivan95, Author = {J. Sullivan and K. E. Holsinger and C. Simon}, Journal = {Molecular Biology and Evolution}, Pages = {988-1001}, Title = {Among-site variation and phylogenetic analysis of 12{S} r{RNA} in sigmontine rodents}, Volume = 12, Year = 1995} @article{sullivan97, Author = {J. Sullivan and D. Swofford}, Journal = {Journal of Mammalian Evolution}, Pages = {77-86}, Title = {Are Guinea pigs Rodents? The importance of adequate models in molecular phylogenetics.}, Volume = 4, Year = 1997} @article{susko02, Author = {E. Susko and Y. Inagaki and C. Field and M. Holder and A. Roger}, Journal = {Molecular Biology and Evolution}, Pages = {1514-1523}, Title = {Testing for differences in rates-across-sites distributions in phylogenetic subtrees}, Volume = 19, Year = 2002} @article{susko03, Author = {E. Susko and C. Field and C. Blouin and A. Roger}, Journal = {Systematic Biology}, Pages = {594-603}, Title = {Estimation of rates-across-sites distributions in phylogenetic substitution models}, Volume = 52, Year = 2003} @article{suzuki99, Author = {Y. Suzuki and T. Gojobori}, Journal = {Molecular Biology and Evolution}, Pages = {1315-1328}, Title = {A method for detecting positive selection at single amino acid sites}, Volume = 16, Year = 1999} @article{suzuki02, Author = {Y. Suzuki and G. V. Glazko and M. Nei}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {16138-16143}, Title = {Overcredibility of molecular phylogenies obtained by Bayesian phylogenetics}, Volume = 99, Year = 2002} @article{suzuki04, Author = {Y. Suzuki and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {914-921}, Title = {False-positive selection identified by {ML}-based methods: examples from the {\it Sig1} gene of the diatom {T}halassoria weissflogii and the {\it tax} gene of a human {T}-cell lymphotropic virus}, Volume = 21, Year = 2004} @article{swanson01, Author = {W. Swanson and Z. Yang and M. Wolfner and C. Aquadro}, Journal = {Proceedings of the National Academy of Sciences of the United States of America (PNAS)}, Pages = {2509-2514}, Title = {Positive Darwinian selection drives the evolution of several female reproductive proteins in mammals}, Volume = 98, Year = 2001} @incollection{swofford90, Address = {Sunderland, MA}, Author = {D. Swofford and G. Olsen}, Booktitle = {Molecular Systematics}, Chapter = 11, Editor = {D. M. Hillis and C. Moritz}, Pages = {411-501}, Publisher = {Sinauer}, Title = {Phylogeny reconstruction}, Year = 1990} @incollection{swofford91, Author = {D. Swofford}, Booktitle = {Phylogenetic analysis of {DNA} sequences}, Chapter = 14, Editor = {M. M. Miyamoto and J. Cracraft}, Pages = {295-333}, Publisher = {Oxford University press}, Title = {When are phylogeny estimates from molecular and morphological data incongruent ?}, Year = 1991} @incollection{swofford96, Address = {Sunderland, MA}, Author = {D. Swofford and G. Olsen and P. Waddel and D. Hillis}, Booktitle = {Molecular Systematics}, Chapter = 11, Editor = {D. Hillis and C. Moritz and B. Mable}, Publisher = {Sinauer}, Title = {Phylogenetic inference}, Year = 1996} @article{tajima82, Author = {Fumio Tajima and Masatoshi Nei }, Journal = {Journal of Molecular Evolution}, Pages = {115-120}, Title = {Biases of the estimates of {DNA} divergence obtained by the restriction enzyme technique}, Utilisateur = {Gilles Caraux}, Volume = 18, Year = 1982} @article{tajima84, Author = {Fumio Tajima and Masatoshi Nei }, Journal = {Molecular Biology and Evolution}, Pages = {269-285}, Title = {Estimation of evolution distance between nucleotide sequences}, Volume = 1, Year = 1984} @article{tajima92, Author = {Fumio Tajima }, Journal = {Molecular Biology and Evolution}, Pages = {168-181}, Title = {Statistical Method for estimating the standard errors of branch lengths in a phylognetic tree reconstructed without assuming equal rates of nucleotide substitution among different lineages}, Utilisateur = {Guillaume Andrieu}, Volume = 1, Year = 1992} @article{tajima93, Author = {Fumio Tajima }, Journal = {Molecular Biology and Evolution}, Pages = {677-688}, Title = {Unbiased Estimation of evolutionary distance between nucleotide sequences}, Utilisateur = {Gilles Caraux and Guillaume Andrieu}, Volume = 10, Year = 1993} @article{tajima94, Author = {Fumio Tajima and Naoko Takezaki}, Journal = {Molecular Biology and Evolution}, Pages = {278-286}, Title = {Estimation of Evolutionary Distance for Reconstructiong Molecular Phylogenetic Trees}, Volume = 11, Year = 1994} @article{takahashi00, Author = {Kei Takahashi and Masatoshi Nei}, Journal = {Molecular Biology and Evolution}, Pages = {1251-1258}, Title = {Efficiencies of Fast Algorithms of Phylogenetic Inference Under the Criteria of Maximum Parsimony, Minimum Evolution, and Maximum Likelihood When a Large Number of Sequences Are Used}, Volume = 17, Year = 2000} @article{takahata81, Author = {Naoyuki Takahata and M. Kimura}, Journal = {Genetics}, Pages = {641-657}, Title = {A Model of Evolutionary Base Substitutions and its Application with special Reference to rapid change of Pseudogenes}, Utilisateur = {Guillaume Andrieu}, Volume = 98, Year = 1981} @article{takezaki94, Author = {N. Takezaki and M. Nei}, Journal = {Journal of Molecular Evolution}, Pages = {210-218}, Title = {Inconsistency of the maximum parsimony method when the rate of nucleotide, substitution is constant}, Utilisateur = {Vincent}, Volume = 39, Year = 1994} @Article{takezaki95, Author="Takezaki, N. and Rzhetsky, A. and Nei, M. ", Title="{{P}hylogenetic test of the molecular clock and linearized trees}", Journal="Mol. Biol. Evol.", Year="1995", Volume="12", Pages="823--833", Month="Sep" } @article{tamura93, Author = {K. Tamura and M. Nei}, Journal = {Molecular Biology and Evolution}, Pages = {512-526}, Title = {Estimation of the number of nucleotide substitutions in the control region of mitochondrial {DNA} in humans and chimpanzees}, Volume = 10, Year = 1993} @article{tateno82, Author = {Y. Tateno and M. Nei and F. Tajima}, Journal = {Journal of Molecular Evolution}, Pages = {387-404}, Title = {Accuracy of Estimed Phylogenetic Trees from Molecular Data : I. Distantly Related Species}, Volume = 18, Year = 1982} @article{tavare86, Author = {S. Tavar\'e}, Journal = {Lectures on Mathematics in the Life Sciences}, Pages = {57-86}, Title = {Some probabilistic and statistical problems on the analysis of {DNA} sequences}, Volume = 17, Year = 1986} @article{tillier98, Author = {E. Tillier and R. Collins}, Journal = {Genetics}, Pages = {1993-2002}, Title = {High Apparent Rate of Simultaneous Compensatory Base-Pair Substitutions in Ribosomal RNA}, Volume = 148, Year = 1998} @article{clustal, Author = {J. Thompson and D. Higgins and T. Gibson }, Journal = {Nucleic Acids Research}, Pages = {4673-4680}, Title = {{CLUSTAL W}: improving the sensitivity of progressive multiple sequence alignment through sequence weighting, position-specific gap penalties and weight matrix choice}, Volume = 22, Year = 1994} @article{clustalx, Author = {J. Thompson and T. Gibson and F. Plewniak and F. Jeanmougin and D. Higgins}, Journal = {Nucleic Acids Research}, Pages = {4876-4882}, Title = {The {C}lustal{X} windows interface: flexible strategies for multiple sequences alignement aided by quality analysis tool}, Volume = 24, Year = 1997} @article{thorne91, Author = { J. L. Thorne and H. Kishino and J. Felsenstein}, Journal = {Journal of Molecular Evolution}, Pages = {114-124}, Title = {An Evolutionary Model for Maximum Likelihood Alignement of {DNA} Sequences}, Volume = 33, Year = 1991} @article{thorne92a, Author = { J. L. Thorne and H. Kishino and J. Felsenstein}, Journal = {Journal of Molecular Evolution}, Pages = {3-16}, Title = {Inching toward Reality: an Improved Likelihood Model of Sequence Evolution}, Volume = 34, Year = 1992} @article{thorne92b, Author = {J. L. Thorne and H. Kishino }, Journal = {Molecular Biology and Evolution}, Pages = {1148-1162}, Title = {Freeing Phylogenies from Artifacts of Alignement}, Utilisateur = {G. Andrieu}, Volume = 9, Year = 1992} @article{thorne98, Author = {J. Thorne and H. Kishino and I. Painter}, Journal = {Molecular Biology and Evolution}, Pages = {1647-1657}, Title = {Estimating the rate of evolution of the rate of molecular evolution}, Volume = 15, Year = 1998} @article{tourasse97, Author = {N.J. Tourasse and M. Gouy }, Journal = {Molecular Biology and Evolution}, Pages = {287-98}, Title = {Evolutionary distances between nucleotide sequences based on the distribution of substitution rates among sites as estimated by parsimony}, Volume = 14, Year = 1997} @book{trivedi01, Address = {Chichester}, Author = {K. Trivedi}, Publisher = {Wiley}, Title = {Probability and Statistics with Reliability, Queuing, and Computer Science Applications}, Year = {2001}} @article{tuffley98, Author = {C. Tuffley and M. Steel}, Journal = {Mathematical Biosciences}, Pages = {63-91}, Title = {Modeling the covarion hypothesis of nucleotide substitution}, Volume = 147, Year = 1998} @incollection{vach89, Author = {Werner Vach}, Booktitle = {Conceptual and numerical analysis of data}, Editor = {O. Opitz}, Pages = {230-238}, Publisher = {Springer Verlag}, Title = {Least squares approximation of additive trees}, Year = 1989} @article{wahlberg06, Author = {N. Wahlberg}, Journal = {Systematic Biology}, Title = {That awkward age for butterflies: insights from the age of the butterfly subfamily {N}ymphalinae ({L}epidoptera: {N}ymphalidae)}, Pages = {703-714}, Volume = {55}, Year = {2006}, } @article{wakeley93, Author = {J. Wakeley}, Journal = {J Mol Evol}, Number = 6, Pages = {613-23}, Title = {Substitution rate variation among sites in hypervariable region 1 of human mitochondrial DNA.}, Volume = 37, Year = 1993} @article{wakeley94, Author = {J. Wakeley}, Journal = {Molecular Biology and Evolution}, Pages = {436-442}, Title = {Substitution rate variation among sites and the estimation of transition bias}, Year = 1994} @article{vandepeer04, Author = {Y. Van de Peer}, Journal = {Nature Reviews Genetics}, Pages = {752-763}, Title = {Computational approaches to unveiling ancient genome duplications}, Volume = 5, Year = 2004} @article{vin04, Author = {L. Sy Vinh and A. von Haeseler}, Journal = {Molecular Biology and Evolution}, Pages = {1565-1571}, Title = {{IQPNNI}: Moving Fast Through Tree Space and Stopping in Time}, Volume = 21, Year = 2004} @article{vonhaeseler93, Author = {Arndt Von Haeseler and Gary A. Churchill}, Journal = {J. Mol Evol}, Pages = {77-85}, Title = {Network Models for Sequence Evolution}, Utilisateur = {Guillaume Andrieu}, Volume = 37, Year = 1993} @article{wagner02, Author = {A. Wagner}, Journal = {Genome Biology}, Pages = {1012.1-1012.3}, Title = {Selection and gene duplication : a view from the genome}, Volume = 3, Year = 2002} @phdthesis{waddell95, Author = {P.J. Waddell}, School = {Massey University}, Title = {Statisctical Methods of Phylogenetic Analysis: Including Hadamard Conjugations, LogDet Transforms, and Maximum Likelihood}, Year = 1995} @article{waterman77, Author = {M. S. Waterman and T. F. Smith and M. Singh and W. A. Beyer}, Journal = {Journal of Theoretical Biology}, Pages = {199-213}, Title = {Additive Evolutonary trees}, Utilisateur = {Gilles Caraux et Vincent}, Volume = 64, Year = 1977} @article{waterman78, Author = {M. S. Waterman and T. F. Smith}, Journal = {Journal of Theoretical Biology}, Pages = {789-800}, Title = {On the similarity of dendrograms}, Utilisateur = {Gilles Caraux}, Volume = 73, Year = 1978} @article{whelan01, Author = {S. Whelan and Pietro Li{\`o} and Nick Goldman}, Journal = {Trends in Genetics}, Number = 5, Pages = {262-272}, Title = {Molecular phylogenetics: state-of-the art methods for looking into the past}, Volume = 17, Year = 2001} @article{whelan01b, Author = {S. Whelan and N. Goldman}, Journal = {Molecular Biology and Evolution}, Pages = {691-699}, Title = {A General Empirical Model of Protein Evolution Derived from Multiple Protein Families Using a Maximum-Likelihood Approach}, Volume = 18, Year = 2001} @article{wilkinson95, Author = {M. Wilkinson}, Journal = {Systematic Biology}, Optnumber = {3}, Optpages = {435-439}, Optvolume = {44}, Title = {More on reduced consensus methods}, Year = {1995}} @article{whitley94, Author = {D. Whitley}, Journal = {Statistics and Computing}, Pages = {65-85}, Title = {A Genetic Algorithm Tutorial}, Volume = 4, Year = {1994}} @incollection{williams90, Address = {New York}, Author = {Patrick L. Williams and Walter M. Fitch}, Booktitle = {Molecular evolution : computer analysis of protein and nucleic acidsequences}, Chapter = 38, Editor = {Russsell F. Doolittle}, Pages = {615-626}, Publisher = {Academic Press}, Series = {Methods In Enzymology}, Title = {Phylogeny Determination Using Dynamically Weighted Parsimony Method}, Volume = 183, Year = 1990} @article{suzuki08, title={False-positive results obtained from the branch-site test of positive selection}, author={Suzuki, Yoshiyuki}, journal={Genes \& Genetic Systems}, volume={83}, number={4}, pages={331--338}, year={2008}, publisher={J-STAGE} } @article{nozawa09, title={Reliabilities of identifying positive selection by the branch-site and the site-prediction methods}, author={Nozawa, Masafumi and Suzuki, Yoshiyuki and Nei, Masatoshi}, journal={Proceedings of the National Academy of Sciences}, volume={106}, number={16}, pages={6700--6705}, year={2009}, publisher={National Acad Sciences} } @article{wong04, Author = {W. Wong and Z. Yang and N. Goldman and R. Nielsen}, Journal = {Genetics}, Pages = {1041-1051}, Title = {Accuracy and power of statistical methods for detecting adaptive evolution in protein coding sequences and for identifying positively selected sites}, Volume = {168}, Year = 2004} @article{yang11, title={Statistical properties of the branch-site test of positive selection}, author={Yang, Ziheng and dos Reis, Mario}, journal={Molecular Biology and Evolution}, volume={28}, number={3}, pages={1217--1228}, year={2011}, publisher={SMBE} } @article{yang93, Author = {Z Yang}, Journal = {Molecular Biology and Evolution}, Pages = {1396-1401}, Title = {Maximum-likelihood estimation of phylogeny from {DNA} sequences when substitution rates differ over sites}, Volume = {10}, Year = 1993} @article{yang94, Author = {Z. Yang and N. Goldman and A. Friday}, Journal = {Molecular Biology and Evolution}, Pages = {316-324}, Title = {Comparison of models for nucleotide substitution used in maximum-likelihood phylogenetic estimation.}, Volume = 11, Year = 1994} @article{yang94b, Author = {Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {306-314}, Title = {Maximum likelihood phylogenetic estimation from {DNA} sequences with variable rates over sites: approximate methods}, Volume = 39, Year = 1994} @article{yang94c, Author = {Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {105-111}, Title = {Estimating the pattern of nucleotide substitution}, Volume = 10, Year = 1994} @article{yang94d, Author = {Z. Yang}, Journal = {Systematic Biology}, Pages = {329-342}, Title = {Statistical properties of the maximum likelihood method of phylogenetic estimation and comparison with distance matrix methods}, Volume = 43, Year = 1994} @article{yang95a, Author = {Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {689-697}, Title = {Evaluation of several methods for estimating phylogenetic trees when substitution rates differ over nucleotide sites}, Volume = 40, Year = 1995} @article{yang95b, Author = {Z. Yang}, Journal = {Genetics}, Pages = {993-1005}, Title = {A space-time process model for the evolution of {DNA} sequences}, Volume = 193, Year = 1995} @article{yang96, Author = {Z. Yang and S. Kumar}, Journal = {Molecular Biology and Evolution}, Pages = {650-659}, Title = {Approximate methods for estimating the pattern of nucleotide substitution and the variation of substitution rates among sites}, Volume = 13, Year = 1996} @article{yang98, Author = {Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {568-573}, Title = {Likelihood ratio tests for detecting positive selection and application to primate lysozyme evolution}, Volume = 15, Year = 1998} @article{paml, Author = {Z. Yang}, Journal = {Computer Applications in the Biosciences (CABIOS)}, Pages = {555-556}, Title = {{PAML} : a program package for phylogenetic analysis by maximum likelihood}, Volume = 13, Year = 1997} @article{paml4, title={{PAML} 4: phylogenetic analysis by maximum likelihood}, author={Yang, Ziheng}, journal={Molecular Biology and Evolution}, volume={24}, number={8}, pages={1586--1591}, year={2007}, publisher={SMBE} } @article{yang96b, Author = {Z. Yang}, Journal = {Trends in Ecology and Evolution}, Number = 9, Pages = {367-372}, Title = {Among-site rate variation and its impact on phylogenetic analyses}, Volume = 11, Year = 1996} @article{yang96c, Author = {Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {294-307}, Title = {Phylogenetic analysis using parsimony and likelihood methods}, Volume = 42, Year = 1996} @article{yang97, Author = {Z. Yang}, Journal = {Trends in Ecology and Evolution}, Number = 9, Pages = {357}, Title = {Are big trees indeed easy ?}, Volume = 12, Year = 1997} @article{yang97b, Author = {Z. Yang and B. Rannala}, Journal = {Molecular Biology and Evolution}, Pages = {717-724}, Title = {Bayesian phylogenetic inference using {DNA} sequences: a Markov Chain {M}onte {C}arlo method}, Volume = 14, Year = 1997} @article{yang97c, Author = {Z. Yang}, Journal = {Molecular Biology and Evolution}, Pages = {105-108}, Title = {How often do wrong models produce better phylogenies?}, Volume = 14, Year = 1997} @article{yang00, Author = {Z. Yang}, Journal = {Journal of Molecular Evolution}, Pages = {423-432}, Title = {Maximum likelihood Estimation on large phylogenies and analysis of adaptative evolution in human influenza virus {A}}, Volume = 51, Year = 2000} @article{yang00d, title={Maximum-likelihood analysis of molecular adaptation in abalone sperm lysin reveals variable selective pressures among lineages and sites}, author={Yang, Z. and Swanson, W.J. and Vacquier, V.D.}, journal={Molecular Biology and Evolution}, volume={17}, number={10}, pages={1446--1455}, year={2000}, publisher={SMBE} } @Article{yang06, Author="Yang, Z. and Rannala, B. ", Title="{{B}ayesian estimation of species divergence times under a molecular clock using multiple fossil calibrations with soft bounds}", Journal="Mol. Biol. Evol.", Year="2006", Volume="23", Pages="212--226", Month="Jan" } @book{yang06b, title={Computational molecular evolution}, author={Yang, Z.}, volume={284}, year={2006}, publisher={Oxford University Press Oxford} } @article{pond11, title={A random effects branch-site model for detecting episodic diversifying selection}, author={Kosakovsky Pond, Sergei L and Murrell, Ben and Fourment, Mathieu and Frost, Simon DW and Delport, Wayne and Scheffler, Konrad}, journal={Molecular Biology and Evolution}, volume={28}, number={11}, pages={3033--3043}, year={2011}, publisher={SMBE} } @article{yokoyama96, Author = {S. Yokoyama and R. Yokoyama}, Journal = {Annual Review of Ecology and Systematics}, Pages = {543-567}, Title = {Adaptative evolution of photoreceptors and visual pigments in vertebrates}, Volume = 27, Year = 1996} @article{yang00b, Author = {Z. Yang and R. Nielsen}, Journal = {Molecular Biology and Evolution}, Pages = {32-43}, Title = {Estimating synonymous and nonsynonymous substitution rates under realistic evolutionary models}, Volume = 17, Year = 2000} @article{yang00c, Author = {Z. Yang and R. Nielsen and N. Goldman and A.-M. {Krabbe Pedersen}}, Journal = {Genetics}, Pages = {431-449}, Title = {Codon-substitution models for heterogeneous selection pressure at amino acid sites}, Volume = 155, Year = 2000} @article{yang02, Author = {Z. Yang and R. Nielsen}, Journal = {Molecular Biology and Evolution}, Pages = {908-917}, Title = {Codon-substitution models for detecting molecular adaptation at individual sites along specific lineages}, Volume = 19, Year = 2002} @article{yang05, Author = {Z. Yang and W. Wong and R. Nielsen}, Journal = {Molecular Biology and Evolution}, Pages = {1107-1118}, Title = {Bayes empirical {B}ayes inference of amino acid sites under positive selection}, Volume = 22, Year = 2005} @article{tateno94, Author = {Y. Tateno and N. Takezaki and M. Nei }, Journal = {Molecular Biology and Evolution}, Pages = {261-77}, Title = {Relative efficiencies of the maximum-likelihood, neighbor-joining, and maximum-parsimony methods when substitution rate varies with site.}, Volume = 11, Year = 1994} @article{uzzell71, Author = {T. Uzzell and K. Corbin}, Journal = {Science}, Pages = {1089-1096}, Title = {Fitting discrete probability distributions to evolutionary events}, Volume = 172, Year = 1971} @article{winter02, Author = {K.-U. Winter and H. Saedler and G. Theissen}, Journal = {The Plant Journal}, Pages = {457-475}, Title = {On the origin of class {B} floral homeotic genes: functional substitution and dominant inhibition in {\em \uppercase{A}rabidopsis} by expression of an orthologue from the gymnosperm {\em \uppercase{G}netum}}, Volume = 31, Year = 2002} @article{zahn05, Author = {L. Zahn and J. Leebens-Mack and C. DePamphilis and H. Ma and G. Theissen}, Journal = {Journal of Heredity}, Pages = {225-240}, Title = {To {B} or {N}ot to {B} a flower: the role of {DEFICIENS} and {GLOBOSA} orthologs in the evolution of the angiosperms}, Volume = {96}, Year = {2005}} @article{zaretskii65, Author = {K. Zaretskii }, Journal = {USpekHi Math. Nauk.}, Pages = {90-92}, Title = {Construction d'un arbre sur la base d'un ensemble de distances entre ses feuilles}, Volume = 20, Year = 1965} @article{zharkikh92a, Author = {Andrey Zharkikh and Wen-Hsiung Li }, Journal = {Molecular Biology and Evolution}, Pages = {1119-1147}, Title = {Statistical properties of Bootstrap estimation of phylogenies variability from nucleotide sequences. {I.} Four Taxa with a molecular clock.}, Volume = 9, Year = 1992} @article{zharkikh92b, Author = { Andrey Zharkikh and Wen-Hsiung Li}, Journal = {Journal of Molecular Evolution}, Pages = {356-366}, Title = {Statistical Properties of Bootstrap Estimation of Phylogenetic Variability from Nucleotide Sequences: {II.} Four Taxa without a Molecular Clock}, Volume = 35, Year = 1992} @article{zharkikh93, Author = {A. Zharkikh and W.-H. Li}, Journal = {Systematic Biology}, Pages = {113-125}, Title = {Inconsistency of the Maximum Parsimony Method: The Case of Five Taxa With a Molecular Clock}, Utilisateur = {Vincent}, Volume = 42, Year = 1993} @article{zharkikh94, Author = {A. Zharkikh}, Journal = {Journal of Molecular Evolution}, Pages = {315-329}, Title = {Estimation of evolutionary distance between nucleotide sequences}, Volume = 39, Year = 1994} @article{zharkikh95, Author = {A. Zharkikh and W.-H. Li}, Journal = {Mol. Phylogenet. Evol.}, Number = 1, Pages = {44-63}, Title = {Estimation of confidence in phylogeny: the complete-and-partial bootstrap technique}, Utilisateur = {Vincent et Olivier}, Volume = 4, Year = 1995} @inbook{zuckerkandl62, Address = {Amsterdam}, Author = {E. Zuckerkandl and L. Pauling}, Editor = {M. Kasha and B. Pullman}, Chapter = {Molecular disease, evolution, and genic heterogeneity}, Pages = {189-225}, Publisher = {Elsevier}, Title = {Horizons in Biochemistry}, Year = 1962} @incollection{vach92, Author = {V. Vach}, Booktitle = {Analysing and Modeling Data and Knowledge}, Editor = {M. Shader}, Pages = {141-150}, Publisher = {Springer}, Title = {The Jukes-Cantor Transformation and Additivity of Estimated Genetic Distances}, Year = 1992} @Article{wu85, Author="Wu, C. I. and Li, W. H. ", Title="{{E}vidence for higher rates of nucleotide substitution in rodents than in man}", Journal="Proc. Natl. Acad. Sci. U.S.A.", Year="1985", Volume="82", Pages="1741--1745", Month="Mar" } @phdthesis{garli, Author = {D. Zwickl}, School = {The University of Texas at Austin}, Title = {Genetic algorithm approaches for the phylogenetic analysis of large biological sequence datasets under the maximum likelihood criterion}, Year = {2006}} phyml-3.2.0/examples/000077500000000000000000000000001263450375500144755ustar00rootroot00000000000000phyml-3.2.0/examples/lg4x/000077500000000000000000000000001263450375500153535ustar00rootroot00000000000000phyml-3.2.0/examples/lg4x/X1.mat000066400000000000000000000035541263450375500163550ustar00rootroot000000000000000.295719 0.067388 0.448317 0.253712 0.457483 2.358429 1.029289 0.576016 0.251987 0.189008 0.107964 1.741924 0.216561 0.599450 0.029955 0.514644 0.736017 0.503084 109.901504 0.084794 4.117654 10.868848 0.704334 0.435271 1.070052 1.862626 0.246260 1.202023 0.380498 5.658311 4.873453 5.229858 0.553477 6.508329 1.634845 0.404968 0.084223 0.123387 0.090748 0.052764 0.151733 0.054187 0.060194 0.048984 0.204296 0.086976 0.221777 0.033310 0.021407 0.230320 0.195703 0.069359 0.069963 0.504221 1.495537 0.188789 93.433377 0.746537 0.621146 0.096955 1.669092 2.448827 0.256662 1.991533 0.091940 0.122332 0.286389 0.382175 0.128905 0.081091 0.352526 0.810168 0.232297 0.228519 0.655465 1.994320 3.256485 0.457430 0.155567 0.235965 0.127321 0.205164 0.590018 0.066081 0.064822 0.241077 6.799829 0.754940 2.261319 0.163849 1.559944 1.671061 6.535048 0.904011 5.164456 0.386853 2.437439 3.537387 4.320442 11.291065 0.170343 0.848067 5.260446 0.426508 0.438856 2.132922 0.525521 0.939733 0.747330 1.559564 0.165666 0.435384 3.656545 0.961142 0.050315 0.064441 0.360946 0.132547 0.306683 4.586081 0.529591 0.303537 0.435450 0.308078 0.606648 0.106333 0.290413 0.290216 0.448965 0.372166 0.102493 0.389413 0.498634 0.109129 2.099355 3.634276 0.115551 0.641259 0.046646 0.260889 0.587531 0.093417 0.280695 0.307466 6.227274 0.206332 0.459041 0.033291 0.559069 18.392863 0.411347 0.101797 0.034710 0.102453 0.289466 0.262076 0.185083 0.592318 0.035149 0.105999 0.096556 20.304886 0.097050 0.133091 0.115301 0.264728 66.647302 0.476350 0.148995 0.063603 20.561407 0.916683 0.102065 0.043986 0.080708 0.885230 0.072549 0.206603 0.306067 0.205944 5.381403 0.561215 0.112593 0.693307 0.400021 0.584622 0.089177 0.755865 0.133790 0.154902 0.147383 0.017579 0.058208 0.017707 0.026331 0.041582 0.017494 0.027859 0.011849 0.076971 0.147823 0.019535 0.037132 0.029940 0.008059 0.088179 0.089653 0.006477 0.032308 0.097931 phyml-3.2.0/examples/lg4x/X2.mat000066400000000000000000000035531263450375500163550ustar00rootroot000000000000000.066142 0.590377 0.468325 0.069930 0.013688 2.851667 9.850951 0.302287 3.932151 0.146882 1.101363 1.353957 8.159169 0.249672 0.582670 0.150375 0.028386 0.219934 0.560142 0.005035 3.054085 0.568586 0.037750 0.421974 0.046719 0.275844 0.129551 0.037250 0.051668 0.262130 2.468752 0.106259 0.098208 4.210126 0.029788 0.013513 0.127170 0.016923 0.344765 0.003656 0.445038 0.165753 0.008541 0.002533 0.031779 0.292429 0.064289 0.210724 0.004200 1.217010 1.088704 0.014768 0.005848 0.064558 7.278994 0.071458 0.855973 1.172204 0.014189 0.033969 1.889645 0.125869 0.031390 0.065585 0.029917 0.042762 1.218562 0.079621 0.763553 0.009876 1.988516 3.344809 0.056702 0.021612 0.079927 7.918203 14.799537 0.259400 0.075144 0.011169 0.082464 0.002656 0.681161 0.111063 0.004186 0.004854 0.095591 0.450964 1.506485 0.009457 1.375871 7.169085 0.161937 0.726566 0.040244 0.825960 2.067758 0.110993 0.129497 0.196886 0.169797 0.637893 0.090576 0.457399 0.143327 30.139501 0.276530 11.149790 0.267322 18.762977 3.547017 0.201148 0.976631 0.408834 0.104288 0.123793 0.292108 0.598048 0.328689 3.478333 13.461692 0.161053 4.782635 0.053740 11.949233 2.466507 0.139705 0.053397 0.126088 1.578530 0.641351 0.297913 4.418398 0.125011 2.984862 13.974326 0.021372 0.081472 0.058046 0.006597 0.286794 0.188236 0.009201 0.019475 0.037226 0.015909 0.154810 0.017172 0.239749 0.562720 0.061299 0.154326 0.060703 0.045779 0.036742 0.498072 0.027639 0.534219 0.203493 0.012095 0.004964 0.452302 0.094365 0.140750 0.021976 0.168432 1.414883 0.077470 0.224675 0.123480 0.447011 4.270235 0.030342 0.258487 0.012745 4.336817 0.281953 0.043812 0.015539 0.016212 16.179952 3.416059 0.032578 2.950318 0.227807 1.050562 0.112000 5.294490 0.033381 0.045528 0.063139 0.066357 0.011586 0.066571 0.010800 0.009276 0.053984 0.146986 0.034214 0.088822 0.098196 0.032390 0.021263 0.072697 0.016761 0.020711 0.020797 0.025463 0.045615 0.094372 phyml-3.2.0/examples/lg4x/X3.mat000066400000000000000000000035451263450375500163570ustar00rootroot000000000000000.733336 0.558955 0.597671 0.503360 0.058964 5.581680 4.149599 2.863355 1.279881 0.225860 1.415369 2.872594 1.335650 0.434096 1.043232 1.367574 0.258365 0.397108 2.292917 0.209978 4.534772 1.263002 0.366868 1.840061 1.024707 0.823594 0.377181 0.496780 0.994098 2.578946 5.739035 0.821921 3.039380 4.877840 0.532488 0.398817 0.517204 0.358350 0.284730 0.027824 1.463390 0.370939 0.232460 0.008940 0.349195 0.775054 0.672023 0.109781 0.021443 1.983693 1.298542 0.169219 0.043707 0.838324 5.102837 0.763094 5.349861 1.612642 0.088850 0.397640 3.509873 0.755219 0.436013 0.888693 0.561690 0.401070 1.890137 0.691594 0.466979 0.060820 2.831098 2.646440 0.379926 0.087640 0.488389 7.010411 8.929538 1.357738 0.540460 0.063347 0.141582 0.018288 4.102068 0.087872 0.020447 0.064863 1.385133 3.054968 5.525874 0.043394 3.135353 0.200122 0.032875 0.019509 0.042687 0.059723 0.072299 0.023282 0.036426 0.050226 0.039318 0.067505 0.023126 0.012695 0.015631 4.972745 0.821562 4.670980 1.199607 5.901348 1.139018 0.503875 1.673207 0.962470 0.204155 0.273372 0.567639 0.570771 0.458799 0.233109 1.825593 0.580847 1.967383 0.420710 2.034980 0.864479 0.577513 0.124068 0.502294 2.653232 0.437116 1.048288 2.319555 0.151684 0.077004 8.113282 0.450842 0.661866 0.088064 0.037642 2.600668 0.390688 0.109318 0.218118 1.065585 0.564368 1.927515 0.120994 1.856122 4.154750 0.011074 0.377578 0.222293 0.526135 0.265730 0.581928 0.141233 5.413080 0.322761 0.153776 0.039217 8.351808 0.854294 0.940458 0.180650 0.975427 11.429924 0.026268 0.429221 0.273138 4.731579 3.839269 0.395134 0.145401 0.090101 4.193725 0.625409 0.696533 0.104335 0.377304 15.559906 2.508169 0.449074 3.404087 1.457957 0.052132 0.260296 2.903836 0.564762 0.681215 0.062457 0.066826 0.049332 0.065270 0.006513 0.041231 0.058965 0.080852 0.028024 0.037024 0.075925 0.064131 0.019620 0.028710 0.104579 0.056388 0.062027 0.008241 0.033124 0.050760 phyml-3.2.0/examples/lg4x/X4.mat000066400000000000000000000035471263450375500163620ustar00rootroot000000000000000.658412 0.566269 0.540749 0.854111 0.058015 3.060574 0.884454 5.851132 1.279257 0.160296 1.309554 2.294145 1.438430 0.482619 0.992259 1.272639 0.182966 0.431464 2.992763 0.086318 2.130054 1.874713 0.684164 2.075952 1.296206 2.149634 0.571406 0.507160 0.552007 3.192521 4.840271 0.841829 5.103188 4.137385 0.351381 0.679853 0.227683 0.528161 0.644656 0.031467 3.775817 0.437589 0.189152 0.025780 0.665865 0.581512 1.128882 0.266076 0.048542 3.954021 2.071689 0.217780 0.082005 1.266791 8.904999 0.695190 3.010922 2.084975 0.132774 0.190734 2.498630 0.767361 0.326441 0.680174 0.652629 0.440178 0.967985 1.012866 0.720060 0.133055 1.776095 1.763546 0.278392 0.343977 0.717301 10.091413 14.013035 1.082703 0.344015 0.227296 0.291854 0.056045 4.495841 0.116381 0.092075 0.195877 4.001286 2.671718 5.069337 0.091278 4.643214 0.978992 0.156635 0.028961 0.209188 0.264277 0.296578 0.177263 0.217424 0.362942 0.086367 0.539010 0.172734 0.121821 0.161015 3.427163 0.878405 4.071574 0.925172 7.063879 1.033710 0.451893 3.057583 1.189259 0.359932 0.742569 0.693405 0.584083 1.531223 1.287474 2.333253 0.802754 2.258357 0.360522 2.221150 1.283423 0.653836 0.377558 0.964545 4.797423 0.780580 1.422571 4.216178 0.599244 0.444362 5.231362 0.154701 0.830884 0.073037 0.094591 3.017954 0.312579 0.074620 0.401252 1.350568 0.336801 1.331875 0.068958 1.677263 5.832025 0.076328 0.548763 0.208791 0.221089 0.431617 1.238426 0.313945 8.558815 0.305772 0.181992 0.072258 12.869737 1.021885 1.531589 0.163829 1.575754 33.873091 0.079916 0.831890 0.307846 5.910440 2.088785 0.456530 0.199728 0.118104 4.310199 0.681277 0.752277 0.241015 0.531100 23.029406 4.414850 0.481711 5.046403 1.914768 0.466823 0.382271 3.717971 0.282540 0.964421 0.106471 0.074171 0.044513 0.096390 0.002148 0.066733 0.158908 0.037625 0.020691 0.014608 0.028797 0.105352 0.007864 0.007477 0.083595 0.055726 0.047711 0.003975 0.010088 0.027159phyml-3.2.0/examples/lg4x/lg4x.xml000066400000000000000000000037121263450375500167560ustar00rootroot00000000000000 phyml-3.2.0/examples/nexus_example.nxs000066400000000000000000000041771263450375500201150ustar00rootroot00000000000000[ This is a comment ] #NEXUS BEGIN DATA; DIMENSIONS NTAX=10 NCHAR=60; FORMAT DATATYPE=STANDARD INTERLEAVE SYMBOLS="00 01 02 03"; MATRIX tax1 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 03 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax2 01 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 02 00 00 01 03 00 00 01 01 00 02 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax3 02 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 02 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax4 03 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax5 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 01 01 00 02 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax6 01 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 00 00 02 00 00 00 01 03 00 00 01 01 00 02 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax7 02 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 02 00 03 03 03 01 01 03 03 00 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 02 tax8 03 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? tax9 00 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 02 02 00 03 03 03 01 03 03 01 02 03 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 03 00 tax10 01 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 00 02 01 02 02 01 02 00 02 01 02 00 00 01 00 02 02 00 00 00 03; END; phyml-3.2.0/examples/nucleic000066400000000000000000001665431263450375500160610ustar00rootroot0000000000000054 886 tax1 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C---CC tax2 ATTGCCTCAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-TCAC tax3 ?????????? TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TG----TGAT tax4 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T-CC tax5 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAAGC TGG-C----- tax6 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax7 ?T-GCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA --TTGAAATC TGGGC-T--C tax8 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax9 ?????????? TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax10 ????????AG TA-CGGCGAG TGAAGCGGCA ACAGCTCCA- T-TTGAAATC TGG-C-T--C tax11 ?TTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax12 ATTGCCCTAG TA-CGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax13 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax14 ?TTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax15 ?TTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax16 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax17 ATTGCCTCAG TAACGGCGAG TGAAGCGGCA TCAGCTCAAA T-TTGAAATC TGG-C-T--C tax18 ATTGCCCCAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAATC TGG-C--CCC tax19 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax20 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax21 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax22 ATTGCCTTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CCTCTT tax23 ATTGCCTCAG TAACGGCGAG TGAAGCGGCA AAAGCTCAGA T-TTGAAATC TGG-CGTCTT tax24 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-TCTG tax25 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax26 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax27 ATTGCCTCAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T-CC tax28 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CCT-CC tax29 ?TTGCCCTAG TA-CGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax30 ATTGCCCTAG TA-CGGCGAG TGA-GCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax31 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax32 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CGT--C tax33 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax34 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTAAAATC TGG-C-TCTG tax35 ????????AG TA-CGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-TCTC tax36 ATTGCCTCAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-CCG-TT tax37 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAAGC TGG-C----- tax38 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAAGC TGG-C----- tax39 ATTGCCTTAG TAACGGCGAG T-AAGC-GCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax40 ?????????? ?????????? ?????????A ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax41 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax42 ATTGCCCTAG TAACGGCGAG T-AAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax43 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax44 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax45 ??TGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax46 ?TTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax47 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax48 ATTGCCCTAG TAACGGCGAG T-AAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax49 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCTCAAA T-TTGAAATC TGG-C-T--C tax50 ATAGCCCTAG TAACGGCGAG TGAAGCGGCT ACAGCTCAAA T-TTGAAATC TGG-CCTC-C tax51 ATTGCCCTAG TAACGGCGAG TGAAGCGGCA ACAGCACAAA T-TTGAAATC TGG-C---TC tax52 ATTGCCCCAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAATC TGG-C---CC tax53 TTCGCCCCAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAATC TGG-C---CC tax54 ???GCCCCAG TAACGGCGAG TGAAGCGGCA ATAGCTCAAA T-TTGAAATC TGG-C---CC TCTCAG--GG TCCGAGTTGT AATTTGTAGA GGGTGCTTTG GCATTGGTTG TGGTCTAAGT ---------G CCCGAGTTGT AATTTGTAGA GGATGTTTCG GGTGAAGCCG CGGTCCAAGT ---GAAA--G CCCGAGTTGT AATTTGCAGA GGATGTTTCG GGCGAGGCCG CGGTCCAAGT TTT-GG--GG TCCGAGTTGT AATTTGTAGA GGGTGCTTTG GCGTTGGCTG TGGTCTAAGT TT----ATGG CCCGCATTGT AATTTGTAGA GGATGCTTTT AGGCAGCCGC CGGTCTAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GTGTCGGCAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGTGCTTTG GCAAAGGTTG TGGTCTAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATAGGCAG CGATTCAAGT TTT-GG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GAGTTGGCTG CAGCCTAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGTGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCGTTGGGAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCGTTGGCAG CGGTCCAAGT T---GG--GG TCCGAATTGT AATTTGGAGA GGATGTTTTT GGGTGTCCGC CGGCCTAAGT C---GG-C-G TCCGAGTTGT AATCTGTAGA GGATGCCTTT GGGTAGCCAC CGGTCTAAGT TAAAAGA--G TCCGAGTTGT AATTTGTAGA GGGTGCTTTG GTGTTGGTAG CGGTCTAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTT-GGA--G TCCGAGTTGT AATTTGTAGA GGGTGCTTTG GCGTTGGTTG TGGTCTAAGT TTTGGG--GG TCCGAGTTGT AATTTGCAGA GGGTGCTTTG GCATTGGCGG CGGTCTAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTT-GG-C-G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCATTGGCAG CGGTCCAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCGTTGGCAG CGGTCCAAGT CTCTAG--GG TCCGAGTTGT AATTTGTAGA GGGTGCTTTG GCACTGATGG CGGTCTAAGT TTTGGG--GG TCCGAGTTGT AATTTGCAGA GGATGCTTTG GCATTGGCGG CGGTCTAAGT TA-----CGG TCCGAGTTGT AATTTGTAGA GGATGTTTTG GGTACCGCCC CGGTTTAAAT TT----ATGG TCCGCATTGT AATTTGTAGA GGATGATTTT AGGCAGCCGC CGGTCTAAGT TT----ATGG CCCGCATTGT AATTTGTAGA GGATGCTTTT AGGCAGCCGC CGGTCTAAGT TTTTAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTCAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TTTTAGA--G TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCTTTGGCAG CGGTCCAAGT TCTGGG--GG TCCGAGTTGT AATTTGCAGA GGATGCTTTG GCGTTGGCGG CGGTCTAAGT TTTTA---GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GCGTTGGCAG CGGTCCAAGT TTTCAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GTGTCGGCAG CAGCCTAAGT TTTCAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GTGTCGGCAG CAGCCTAAGT TTTCAG--GG TCCGAGTTGT AATTTGCAGA GGGCGCTTTG GAGTCGGCAG CAGCCTAAGT TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGCCGCCA ACCTTC-GCC CCCTTGGAAC AGGACGTCAT AGAGGGTGAG AACCCCGTAC CTGGCCGCCG GTGCCC--CC CCCTTGGAAC AGGACGTCAT AGAGGGTGAG AACCCCGTAC CTGGCCGCCG GCTCCCC-CC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGCCGCCA GCCTCC-GCC TCCTTGGAAC AGGACGTCAT AGAGGGTGAG AATCCCGTAT GTGACCGGCT -CTGGC-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTC-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGCCGCCA ACCCGC-GCT TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATC-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATC-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTCTT-GCC TCCTTGGAAC AGGTCATCAT AGAGGGTGAG AATCCCGTAT GTGGTTGCAT GCCTTC-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATC-GCC TCTTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA TCCTTC-GCC TCTTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTC-GCC CCCTTGGAAC AGGGCGTCAT AGAGGGTGAG AATCCCGTAT GTGGCCGGAA AGGTACC-CT CCCCTGGAAC GGGGTGTCAC AGAGGGTGAG AATCCCGTAT GTGACCGGAA GGGCGCC-CT TCCTTGGAAC AGGACATCAC AGAGGGTGAG AATCCCGTAT GTGGTCGCTA GCCTTC-GCT TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGCCGCCA GCCTCC-GCC TCCTTGGAAC AGGACATCGC AGAGGGTGAG AATCCCGTAC GTGGGCGCCT GCCTTT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCCTTT-ACC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTG GCCTTC-GCC TCCTTGGAAC AGGACATCAC AGAGGGTGAG AATCCCGTAT GTGGTCGCTG ATCTTT-GCC TCCTTGGAAC AGGACATCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCCT GCCTTT-GCC TTCTTGGAAC AGAATGTCAA AGAGGGTGAG AGTCCCGTCT TGGACCGCGG TAGGGC-CT- TCCTTGGAAC AGGACGTCAT AGAGGGTGAG AATCCCGTAT GTGACCGGCT -CTGGC-ACC TCCTTGGAAC AGGACGTCAT AGAGGGTGAG AATCCCGTAT GTGACCGGCT -CTGGC-ACC TCCTTGGAAC AGGACGTCAC A-AGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC A-AGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC A-AGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTA GCTATT-GCC TCCCTGGAAC AGGACATCGC AGAGGGTGAG AATCCCGTAC GTGGGCGCCT GCCTTC-GCC TCCTTGGAAC AGGACGTCAC AGAGGGTGAG AATCCCGTAC GTGGTCGCTG GCCTTC-GCC TCCTTGGAAC AGGTCATCAT AGAGGGTGAG AATCCCGTAT GTGGCTGCTT GTCTTC-ACC TCCTTGGAAC AGGTCATCAT AGAGGGTGAG AATCCCGTAT GTGGCTGCTT GTCTTC-ACC TCCTTGGAAC AGGTCATCAT AGAGGGTGAG AATCCCGTAT GTGGCTGCTT GTCTTC-GCC --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --GCTGTGAA ACTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATTGG-TGG --GCTGTGAA ACTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATTGG-TGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG TTA-TGTAAA GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --A-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG C--C-GTAAA ACTCCTTCGA CGAGTCGGGT TGTTTGGGAA TGCAGCCCTA AATGGG-AGG --A-TACATG GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG ---CTGTAAA GCCCCTTCAA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCAA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA ACTCCTTCGA CGAGTCGACT TGTTTGGGAA TGCAGGTCAA AATGGG-TGG TTA-TGTAAA GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG TTA-TGTAAA GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGGGAGG C-G-TGTAAA GCCCCTTCGA CGAGTCGAGT -GTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCTCCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA ATTGGG-AGG --G-TGTAAA GCCTCTTCGA CGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG --G-TGTAAA GCCCCTTCGA TGAGTCGAGT TGTTTGGGAA TGCAGCTCTA AATGGG-AGG TAAATTCCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTCCAT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTCCAT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTTGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCGA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTCCTT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTTGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCAT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCGA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCGA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAA-GCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACCGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATACTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG TAAATTTCTT CTAAAGCTAA ATATTGGCCA GAGACCGATA GCGCACAAGT AGAGTGATCG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGA AAAGAGAGTT AAAA-GTACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGA AAAGAGAGTT AAAAAGTACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AAAACTTTGG AAAGAGAGTT AAACAGCATG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGTACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGTACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGA AAAGAGAGTT AAACAGTATG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTT AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAACAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGTACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAATAGCACG TGAAATTGTT AAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGCACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG AAAGATGAAA AGTACTTTGG AAAGAGAGTC AAAAAGCACG TGAAATTGTT GAAAGGGAAG CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CACCTCGGC- -TTCTG--CC TTGGGTACTC CGCTTGCGGC CAGACTTGCC TGCGGTTGCT CATCCCGCC- -TTTTG--GC GGGTGCACTC CGCTTGCGGC CAGACTTGCC CGCGGTTGCT CAGCCCGCC- -TTTTG--GC GGGTGCACTC CGCTTGCAGC TAGACGTGCC TTGGGTTGAT CAGCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAAT CAGACTTGGA CTTGGCTGTT CAACAGGTC- -TTCTG--AC CTGCCTATTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT TATCCGGAC- -TTTTG--TC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CACCCGGGC- -CTCTGTGCC CGGTGCATTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CACCCGGGC- -CTCTGTGCC CGGTGCATTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGAC- -TTTTG--TC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCCGC CAGACTTGCT TGCAGTTGCT CACCCGGGCC CTTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC CGTAGTTGCT CATCCGGGC- -TCTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGC- -TCTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC CGCAGTTGCT CATCCGGGG- -TTCT-C-CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TTCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT TATCTGGAC- -TTTTG--TC CAGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT TATCCGGAC- -TTTTG--TC CGGTGCACTC CGCTTGCGAT CAGTCTCGAC GGCGGCCGTT CGGCCTCTC- -TTCTG--AG TGGTTTATTC CGCTTGCAAC CAGACTTGTT GGCGGTGTTC C-GCCGGTC- -TTCTG--AC CGGTCTACTC CGCTTGCCGC CAGACTTGCC TGCAGTTGCT CATCTGGGCA -TTGTG--CC CTGTGCATTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTTTA--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTTTA--CC CGGTGCACTC CGCTTGCAGC TAGACGTGCC TTGGGTTGAT CAGCCGGAC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC CGCAGTTGCT CACCTAGGC- -TTTCG--CC TGGGGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTCTA--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTCTA--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTCTA--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCCGGGT- -TTCTA--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCC TGTAGTTGCT CATCTGGGC- -TTTTG--TC CAGTGCACTC CGCTTGCCGC CAGACTTGCC TGCAGTTGCT CACCTAGGCG -TTCAG--CC TGGGGCACTC CGCTTGCAGC CAGACTTGCC CGCAGTTGCT CACCCAGGC- --TTTG-GCC CGGGGCACTC CGCTGGCAAC CAGACTCGTG CGCGGG-GTT CCCCCTTGC- -TTCTG--CT TGGGTCACTT CGCTTGCAAT CAGACTTGGA CTTGGCTGTT CAACAGGTC- -TTCTG--AC CTGCCTATTC CGCTTGCAAT CAGACTTGGA CTTGGCTGTT CAACAGGTC- -TTCTG--AC CTGCCTATTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTTCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTT---CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACTTGCT TGCAGTTGCT CATCCGGGC- -TTTTG--CC CGGTGCACTC CGCTTGCAGC CAGACGTGCC CGCAGTTGCT CACCCAGGC- --TCCGG-CC TGGGGCACTC CGCTTGCAGC CAGACTTGCC CGTAGTTGCT CATCCAGGC- -TTTTG---C CTGTGCACTC CGCTTGCAGC CAGACGTGCC CGTAGTTGCT CATCTGGGG- -TTTTC--CC CAGTGTATTC CGCTTGCAGC CAGACGTGCC CGTAGTTGCT CATTCGGGG- -TTCTC--CC CGATGTACTC CGCTTGCAGC CAGACGTGCC CGCAGTTGCT CATCCGGGG- -ATTTC--CC CGGTGCACTC TTCTACGGGC AGGCCAGCAT CAGTCCGGGC GGTTGGATAA ATGCCTGCTA AATGTACCTC TTCCGCAGTC AGGCCAGCAT CGGTTTGGGC GGTCGGATAA AGGCGCTGGG AACGTGGCCT TTCCGCGGTC AGGCCAGCAT CGGTTCGGGC GGTCGGATAA AGGCGACGGG AACGTGGCCT TTCCTTTGGC AGGCCAGCAT CAGTTTGGGC GGCTGGATAA AGGTCTGTTA AACGTGACTC AGTCTTGTCC AGGCCAGCAT CAGTTTCGGC GGCCGGATAA AGGCCCTAGG AATGTGGCTT TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CATGTACCTC TTCTGCGGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTATGGGC AGGCCAGCAT CAGTCTTGGC GGTCGGATAA ATGCGTGCTA AACGTACCTC TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTGTGGGC AGGCCAGCAT CAGTTCGGGC GGTTGGAGAA AGACCTGTGT CATGTAGCTG TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGCTTTTGG AATGTGGCTC TTCTGCGGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTGCGGGC AGGCCAGCAT CAGTTTAGGC GGTTGGATAA AGGTCTCTAT CACGTACCTC GGTCGCCGCC GGGCCAGCAT CAGTTTCGGC GGTTGGATAA AGGTTGTGGG AATGTGGCCC ACC-GTCTGC AGGCCAGCAT CATCTGGGAC CGCTGGATAA AAGCGGAGGG AATGTGGCTC TTCTGCAAGC AGGCCAGCAT CAGTTTAGAC AGTCAGATAA GGGTCTCTGT CATGTATCTT TTCTATAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTATAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCCTTTGGC AGGCCAGCAT CAGTTTGGGC GGCTGGATAA AGGTCTGTTA AACGTGACTT TTCTGCGGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGCCTCTGT CACGTATCTC TTCTATAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTATAGGC AGGCCAGCAT CGGGGTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTATAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTATAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CATGTACCTC TTCTACAGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC AGCCGGATAA AGGTCTCTGA CACGTTCCTA TTCTGCGGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGCCTCTGT CACGTATCTC CCCCGTGTCC GGGCCATCAT CAGTTTCGGG GGCCGGTTAA AGGCCTTGGG AATGTATCCA AGTCTTGTCC AGGCCAGCAT CAGTTTGGGC GGCCGGATAA AGGCTTTGGG AATGTGGCTT AGTCTTGTCC AGGCCAGCAT CAGTTTCGGC GGCCGGATAA AGGCCCTAGG AATGTGGCTT TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGA CACGTTCCTT TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGGTAA AGGTCTCTGT CACGT-CCTC CTCTGCAGGC AG-CCAGCAT CAGTTTGG-C GGTGGGATAA AGGTCTTTGA CACGTTCCTT TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGA CACGTTCCTT TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGA CACGTTCCTT TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGT CACGTACCAT TTCTGTAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCT-TGT CACGTACCTC TTCTGCAGGC AGGCCAGCAT CAGTTTGGGC GGTGGGATAA AGGTCTCTGA CACGTTCCTT TTCTGCGGGC AGGCCAGCAT CGGTTCGGGC GGTCGGATAA AGGTCTCTGT CACGTACCTC TTCTATGGGC AGGCCAGCAT CAGTTTGGGC GGTTGGATAA AGGTCTCTGT CA???????? TTCTATGGGC AGGCCAGCAT CAGTTCGGGC GGTTGGAGAA AGACCTGTGT CACGTAGCTC TTCTATGGGC AGGCCAGCAT CAGTTCGGGC GGTTGGAGAA AGACCTGTGT CACGTAGCTC TTCTGTGGGC AGGCCAGCAT CAGTTCGGGC GGTTGGAGAA AGACCTGTGT CACGTAGCTC TC--CTCGGG G----A--GG A-CTTATAGG GTAGGC-GGC ATACAACCAG CCTGGACTGA CCC-CTCGGG G--AG---GT G--TTATAGC CCGGCGCGCA ATGCGACCAG CCCGGACCGA CCC-CTCGGG G--AG---GT G--TTATAGC CCGGCGCGCA ATGCGGCCAG CCCGGACCGA CC--TTCGGG G----A--GA G-CTTATAGG GCAGAC-GAC ATGCAGCCAG TCCGAACTGA TCCCTTCGGG GG-A-A--GT G--TTATAGC CTAGGGTGTA ATACGGCCAG CTGGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGC-GAC ATACCACCAG CCTAGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGACGGAC ATGCAACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG A-CTTATAGG GCACGC-GGC ATACGACCAG CCGGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGC-GAC ATACAACCAG CCTAGACTGA TT--CTCGGG C----A--GT G--TTATAGG GCAGGTTGGA ATGCAACCAG CTCGAACTGA TC--TTCGGG G----A--GG -CCTT-TAGG GGAAGGTGTA ATACCACCAG CTGGGACTGA CT--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATGCAACCAG CCTGGACTGA CC--TTCGGG GTT-----GG -CCTTATAGG GGAGAC-GAC ATGCAACCAG CCTGAACTGA C---CTCGGG GG-------T G--TTATAGC CCACTTCGTA ATACAACCAG CTGGGACTGA C---TCCGGG ---A----GT G--TTATAGC CCTCTGTGTA ATACAGCGAG TCCCGGGTGA TC--TTCGGA A------TGA -CCTTATAGG GGGGGC-GTA GTATGGCTAG TCTAGACTGA TC--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCCGGACTGA TC--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCCGGACTGA CC--TTCGGG G----A--GA G-CTTATAGG GTAGAC-GAC ATGCAGCCAG CCTGAACTGA CC--TTCGGG GT------GA -CCTTATAGG GGAGGC-GCA ATGCAACCAG CCCGGACTGA CT--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCCGGACTGA CT--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCCGGACTGA CT--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCTGGACTGA CT--TTCGGG G----A--GA A-CTTATAGG GGAGAC-GAC ATGCAACCAG CCTGGACTGA CC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATGCAACCAG CCTGGACTGA CC--TTTGTG -T---A--GG -CCATATAGG GGAGAC-GTC ATGCGGTTAG CCTGGACTGA CC--TTCGGG GT------GA -CCTTATAGG GGAGGC-GCA ATGCAACCAG CCCGGACTGA CGCCTTCGGG GG-----TG- GACTTATAGC CCAGGGTGTC ATGCGGCCAC CCGGGACTGA TCT-TCCGGG GG-A-A--GT ---TTATAGG --AAGGTGTA ATACGGCCAG CTGGGACTGA TCCCTTCGGG GG-A-A--GT G--TTATAGC CTAGGGTGTA ATACGGCCAG CTGGGACTGA CC--TTCGGG -TT-----GG -CCATATAGG GGAGAC-GTC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG A-CTTATAGG GGAGGC-GAC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGGCC-AC ATACCACCAG CCTGGACTGA CC--TTCGGG -TT-----G- -CCATATAGG G-AGAC-GTC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA CC--TTCGGG -TT-----GG -CCATATAGG GGAGAC-GTC ATACCACCAG CCTGGACTGA CC--TTCGGG -TT-----GG -CCATATAGG GGAGAC-GTC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA CC--TTCGGG -----AT-GG -CCATATAGG GGAGAC-GTC ATACCACCAG CCTGGACTGA TC--TTCGGG G----A--GG -CCTTATAGG GGAGAC-GAC ATACCACCAG CCTAGACTGA CC--TTCGGG -TT-----GG -CCATATAGG GGAGAC-GTC ATACCACCAG CCTGGACTGA CC--TTCGGG GT------GG -CCTTATAGG GGAGAC-GCA ATGCGACCAG CCCGGACCGA ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? CT--TTCGGG G----A--GT G--TTATAGG GCAGGT-GGA ATGCAACCAG CCTGAACTGA TC--TTCGGG G----A--GT G--TTATAGG GCAGGT-GGA ATGCAACCAG CCTGAACTGA TC--TTCGGG G----A--GT G--TTATAGG GCAGGT-GGA ATGCAACCAG CCTGAACTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTTCGCGC- TTT----GCT AGGATGCTGG CGTAATGGCC GT-AAGC-GG CCCGTCTTGA GGTTCGCGC- TCT----GCT AGGATGCTGG CGTAATGGCC GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATAGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCT TC---G-GCT AGGATGCTGG CGTAATGGTT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA T-T----GCT AGGATGCTGG CGTAAGGGCT GT--AGC-GG -CCGTCTTGA GGTCCGCGCA TTT--ATGCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TTT--ATGCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TTT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TTTTT-TGCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TTC--GTGCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCC-CGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCT TCT----GCT AGGATGCTGG CGTAATGGCT GTCAAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCT TC---G-GCT AGGATGCTGG CAAAATGGTC GT-AAGC-GG CCCGTCTTGA GGTCCGCGCT TC---G-GCT AGGATGCTGG CGTAATGGTC GT-AAGC-GG CCCGTCTTGA GGTCCGCGCT TTT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CATAATAGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AA-CGGG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TT-----GCT AGGATGCTGG CGTAATGGCT G-CAAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGAACGCGCT TC---G-GCG AGGATGATGG CGTAATGGTT GTC-AGC-GG CCCGTCTTGA GGTCCGCGCT TC---G-GCT AGGATGCTGG CGTAATGGTT GTCAAGC-GG CCCGTCTTGA GGTCCGCGCT TC---G-GCT AGGATGCTGG CGTAATGGTT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGAGCA TCT----GCT AGGA-GCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTG- CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GG-CCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCC AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA GGTCCGCGCA TCT----GCT AGGATGCTGG CGTAATGGCT GT-AAGC-GG CCCGTCTTGA AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTAAAG CCCGGACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAA CCCGTGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAA CCCGTGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGGGAC CAAGGAGTC- TAACATCTAT GCGAGTGTTA GGGTGTCAAA CCCTTACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC C-----GT-- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCAGACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCAGACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCAGACGCG AACACGG-AC CAAGGAGTC- TAACATCTAC GCGAGTGTTC GGGTGTCAAA CCCGTGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTC GGGTGTCAAA CCCCTACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGGGCGCA AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGGGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGGGAC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGGACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTC GGGTGTCAAA CCCTTGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTA GGGTGTCAAA CCCTTACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTA GGGTGTCAAA CCCTTACGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTAAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGGGCGCG ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG AACACGG-AC CAAGGAGTC- TAACATCTAT GCGAGTGTTT GGGTGTCAAG CCCGAGCGCG CAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCGC -----AAGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACC-G CA---A-GGT GCACCATC-G ACCGATCCTG TAATGAAAGT AAACGGAGG- TGGGAACCCT TT----GGGT GCACCACC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGAGAACCCG CA---AGGGT GCATCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCT TT----GGGT GCACCATCCG ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TT---A-GGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TT---A-GGT GCACCATC-G ACCGATCCTG CAATGAAAGT GAACGGAGG- TGGGATCCCG CA---AGGGC GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TT---A-GGT GCACCATC-G ACCGATCCTG TAATAAAAGT GAACGGAGG- TGGGAACCTT TTT----GGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT AAACGTAGG- TGGGAACCTT TT---A-GGT GCACCATC-G ACCGATCTTG CAATGAAAGT GAACGGAGG- TGGGAACC-G CA---A-GGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGGG TGGGAACCTT TC---G???? ?????????? ?????????? TAATGAAAGT GAACGGAGG- TGGGAACCTT TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCTT TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGACCCCT TTT--AGGGT GCACCATC-G ACCGATCCTG CAATAAACGT GAACGGAGG- TGGGAACCCT CTTTGGGGGT GCACCATC-G ACCGATCCTG CAATGAAAGT GAACGGAGG- TGGGAACCCT TTT---GGGT GCACCATC-G ACCGATCCTG GAATGAAAGT GAACGGAGG- TAGGAAGGCT TA---AGCCT GCACTATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGAGAACCCG CA---AAGGT GCATCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGAGAACCCG CA---AGGGT GCATCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGC GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGC GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGC GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCG CA---AGGGT GCACCATC-G ACCGATCCTG CAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGC GCACCATC-G ACCGATCCTG ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGC GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG TAATGAAAGT GAACGGAGG- TGGGAACCCC TC---GGGGT GCACCATC-G ACCGATCCTG AAGTTTACGG ATGGATTTGA GTATGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTTTTCGG ATGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCGT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA AAGTTTACGG AAGGATTTGA GTAAGAGCAT GGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA ATGTCTTCGG ATGGATTTGA GTAAGAGCAT AGCTGTTGGG ACCCGAAAGA TGGTGAACTA TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCGTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCGTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA -GGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTCCGCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGGATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCGTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCA?? ?????????? TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAGGC CAGAGGAAAC TCTGGTGGAG GCT??????? ?????????? TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCT??????? ?????????? TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG?? ?????????? ?????????? ?????????? ?????????? TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCTTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG ?????????? ?????????? ?????????? ?????????? ?????????? ?????????? TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCCTGAATA GGGTGAAG-C CAGAGGAAAC TCTGGTGGAG GCTC-GCAGC GGTTCTGACG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGCGTATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAA?? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGTATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAA??? TGCAAATCGA TCGTCAAATT TGGGC????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAAT?? TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGA? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGA? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGTATAGG GGCGAAAG?? ?????? TGCAAATCGA TCGTCAAATT TGGGTATAGG GGCGAAAG?? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAAT?? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAAT?? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAATCG ?????????? ?????????? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAAT?? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG G????????? ?????? TGCAAATCGA TCGTCAAATT TGCGTATAGG GGCGAAAG?? ?????? TGCAAATCGA TCGTCAAATT TGGGTATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGTATAGG GGCGAAAGAC TAATCG ?????????? ?????????? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG ?????????? ?????????? ?????????? ?????????? ?????? ?????????? ?????????? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG G-CGAAAGAC TAAT?? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG ?????????? ?????????? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG ?????????? ?????????? ?????????? ?????????? ?????? TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG TGCAAATCGA TCGTCAAATT TGGGCATAGG GGCGAAAGAC TAATCG phyml-3.2.0/examples/phytime_input_files/000077500000000000000000000000001263450375500205555ustar00rootroot00000000000000phyml-3.2.0/examples/phytime_input_files/p1.calib000066400000000000000000000036151263450375500220760ustar00rootroot00000000000000p1c066-126 | -11 -11 p1c003-24 | -74 -74 p1c045-440 | -32 -32 p1c003-18 | -74 -74 p1c061-11 | -16 -16 p1c077-308 | 0 0 p1c061-05 | -16 -16 p1c024-52 | -53 -53 p1c045-93 | -32 -32 p1c014-05 | -63 -63 p1c068-150 | -9 -9 p1c068-144 | -9 -9 p1c034-64 | -43 -43 p1c003-17 | -74 -74 p1c014-22 | -63 -63 p1c024-57 | -53 -53 p1c077-313 | 0 0 p1c061-10 | -16 -16 p1c045-98 | -32 -32 p1c034-81 | -43 -43 p1c077-307 | 0 0 p1c061-04 | -16 -16 p1c066-136 | -11 -11 p1c045-81 | -32 -32 p1c034-75 | -43 -43 p1c077-176 | 0 0 p1c068-149 | -9 -9 p1c014-33 | -63 -63 p1c014-27 | -63 -63 p1c051-115 | -26 -26 p1c034-86 | -43 -43 p1c045-92 | -32 -32 p1c045-86 | -32 -32 p1c051-326 | -26 -26 p1c014-38 | -63 -63 p1c024-62 | -53 -53 p1c003-16 | -74 -74 p1c077-306 | 0 0 p1c061-03 | -16 -16 p1c014-32 | -63 -63 p1c051-120 | -26 -26 p1c077-317 | 0 0 p1c051-114 | -26 -26 p1c024-44 | -53 -53 p1c061-08 | -16 -16 p1c068-159 | -9 -9 p1c034-79 | -43 -43 p1c066-123 | -11 -11 p1c024-61 | -53 -53 p1c003-15 | -74 -74 p1c024-55 | -53 -53 p1c077-311 | 0 0 p1c045-96 | -32 -32 p1c066-134 | -11 -11 p1c066-128 | -11 -11 p1c068-147 | -9 -9 p1c034-67 | -43 -43 p1c014-25 | -63 -63 p1c061-13 | -16 -16 p1c045-90 | -32 -32 p1c068-158 | -9 -9 p1c045-84 | -32 -32 p1c068-141 | -9 -9 p1c003-20 | -74 -74 p1c024-60 | -53 -53 p1c061-01 | -16 -16 p1c077-173 | 0 0 p1c066-127 | -11 -11 p1c068-146 | -9 -9 p1c034-66 | -43 -43 p1c077-167 | 0 0 p1c024-71 | -53 -53 p1c014-30 | -63 -63 p1c003-19 | -74 -74 p1c014-24 | -63 -63 p1c077-315 | 0 0 p1c061-12 | -16 -16 p1c045-435 | -32 -32 p1c061-06 | -16 -16 p1c051-106 | -26 -26 p1c034-77 | -43 -43 p1c051-323 | -26 -26 p1c066-121 | -11 -11 p1c024-53 | -53 -53 p1c014-12 | -63 -63 p1c066-132 | -11 -11 p1c068-151 | -9 -9 @root@ | -74 -120 phyml-3.2.0/examples/phytime_input_files/p1.nxs000066400000000000000000001414321263450375500216340ustar00rootroot0000000000000087 561 p1c066-126 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGCCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCATACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTACGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGTTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c003-24 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATCTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c045-440 GAAGAGGTAGTAACTAGATCTGAAAATTTAACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAGCTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c003-18 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c061-11 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGAACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGGAATAATAGGAAATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAAAACTTTAACACGGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGGACGAAATCTTCAGACCTGGA p1c077-308 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACATTAGTAAAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAAATATTGCAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c061-05 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATGGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAGCAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAAGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c024-52 GAAGAGGTAGTAATTAGATCTGACAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTAGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGGCGAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACGAGAGATGGTGGTAACATGAGCGAAGTCTTCAGACCTGGA p1c045-93 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACATGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGGGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGAATGGGATAACACTTTAAAACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTCCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c014-05 GAAGAGGTAGTAATTAGATCTGAAAAGTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c068-150 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGCATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGACAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c068-144 AAAGAGGTAGTAATTAGATCTGAGAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGGGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c034-64 GAAGAGGTAGTAATTAGATCTGAAAATTTAACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGCTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAAGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c003-17 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAGGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTGTTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c014-22 GAAGAGGTAGTAATTAGATCCGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAGAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c024-57 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAACGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATCAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAAAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAAAGCAAAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGCGGAGGGAAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAGCGAAATCTTCAGACCTGGA p1c077-313 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGAAGAGCATTTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTGAGACAGATAGTTGAAAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGATCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACATAAACGAAATCTTCAGACCTGGA p1c061-10 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAAATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTGAGAAATTAAGAGAACAATCTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTAAAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c045-98 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAACAACACTTTAACACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCGGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGAACGAAATCTTCAGACCTGGA p1c034-81 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGACAACACGAACGAAATCTTCAGACCTGGA p1c077-307 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGCAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAGATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c061-04 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATACATGTAGGACCAGGGAGAGCAATTTATGCAACAGGAAGAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAACCAGGTAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAGCGAAACCTTCAGACCTGGA p1c066-136 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATCATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c045-81 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTAAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATGCAGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGCTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c034-75 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACGGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c077-176 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGCAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGAAGAGCATTTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTGAGACAGATAGTTGAAAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGATCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCCCCCATCAGCGGACAAATTAGATGTTCATCAAATACTACAGGGCTGCTATTAACAAGAGATGGTGGCAACATAGACGAAATCTTCAGACCTGGA p1c068-149 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATATCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAGAATAATAGGAGATATAAGAAAAGCACATTGTAACATTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGGATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCACGCTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGG p1c014-33 GAAGAGGTAGTAATTAGATCTGAAAATTTCATGGACAACGCTAAAACTATAATAGTACAGCTGAGGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACGAGAGATGGTGGTAACACGAGCGAAGTTTTCAGACCTGGA p1c014-27 GAAGAGGTAGTAATTAGATCTGAGAATTTCATGGACAATGCTAAAACCATAATAGTACAGCTGAGGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAGATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGATCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGCTGAATACTGAAGGGAATATCACACTCCCATGTAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAGTCTTCAGACCTGGA p1c051-115 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAGGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGTAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATTTTCAGACCTGGA p1c034-86 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c045-92 GAAGAGGTAGTAATTAGATCTGAAAATTTAACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATACGACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c045-86 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGGCAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAACACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCCCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c051-326 GAAGAGATAGTAATTAGATCTGAAAATTTAACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGGCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACATGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAAATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGCTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCTAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAAGGATGAAGGGACTATCACGCTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGGAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTACTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c014-38 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAACGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACCATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGATGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c024-62 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGAGCGAAATCTTCAGACCTGGA p1c003-16 GAAGAGGTAGTAATTAGATCTGAAAATTCCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c077-306 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGGGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACACTAGTAAAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAGACGAAATCTTCAGACCTGGA p1c061-03 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAGCAGATAGTCGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCATGCTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAGGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGTTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c014-32 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c051-120 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c077-317 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACTATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCATTTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGACGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTCCAGACCTGGA p1c051-114 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGCCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCATACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTACGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGTTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c024-44 GAAGAGGTAGTAATTAGATCTGACAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATGCAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGGAGGAAAAGCATTGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGGCACGAACGAAATCTTCAGACCTGGA p1c061-08 AAAGAGGTAGTAATTAGATCTGAAAATTTCACAGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATATCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAAGAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c068-159 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTATTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAAAGAATATCACACTCCCATGCAGAGTAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c034-79 GAAGAGGTAGTAATTAGATCTGACAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAATCTTTAACCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATGGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTACGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c066-123 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGACAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAGTTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c024-61 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATGATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAGGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGAGCGAAATCTTCAGACCTGGA p1c003-15 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATTTAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTGAATTGTAGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c024-55 GAAGAGGTAGTAATTAGATCTGAAAATTTAACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAGAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACGAGAGATGGTGGTAACACGAGTGAAATCTTCAGACCTGGA p1c077-311 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAACATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAAATATTACAGGGCTACTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c045-96 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTACAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGGAGGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGAACGAAATCTTCAGACCTGGA p1c066-134 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTATACAAGACCCAGTAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCTTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAAGGAATATCATACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c066-128 GAAGAGTTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGTAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATTTTCAGACCTGGA p1c068-147 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAGGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACAAACGAAATCTTCAGACCTGGA p1c034-67 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACGATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGGGGGGGATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c014-25 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACGCTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c061-13 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATACGTGTAGGACCAGGGAGAGCAATTTATGCAACAGGAAGAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAACCAGGTAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGTTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c045-90 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGATCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAGCAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCCCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c068-158 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAGCAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACCTTAAAACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAACAGTCTTTAATCGACCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c045-84 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACGCTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATCCTGAAAGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATTAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c068-141 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTTAGACCTGGA p1c003-20 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c024-60 GAAGAGGTAGTAATTAGATCTGACAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTATTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTGTAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCTCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGGCACGAACGAAATCTTCAGACCTGGA p1c061-01 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAGCGAAACCTTCAGACCTGGA p1c077-173 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGGAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAGATGAAATCTTCAGACCTGGA p1c066-127 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAGGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGTAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATTTTCAGACCTGGA p1c068-146 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c034-66 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAATATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c077-167 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATGTAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGGAGGGACGACCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAACGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAGACGAAATCTTCAGACCTGGA p1c024-71 GAAGAGGTAGTAATTAGATCTGACAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGAGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGGCACGAACGAAATCTTCAGACCTGGA p1c014-30 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGACACGAGCGAAATCTTCAGACCTGGA p1c003-19 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c014-24 GAAGAGATAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGCGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGGATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACGAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c077-315 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAACGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAACAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGAGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGATGATCATACTCCAATGCAGAATAAAACAAATTGTAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGCGGACAGATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c061-12 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGAAGCCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAAATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAGCAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAAGGAATATCACACTCCCATGCAAAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTGACACGAGCGAAATCTTCAGACCTGGA p1c045-435 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACGATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAACTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTGGAATACTGCAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c061-06 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATATCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAAGAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGCATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAGCGAAACCTTCAGACCTGGA p1c051-106 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCCAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACCGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGGAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c034-77 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAGAGCAATTTATGCAACAGGAGAAATAATAGGAGATATAAGACAAGCACACTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAATATGTGGCAGGAAGTAGGAAAAGCAGTGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c051-323 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGCCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAACAACACTTTAACACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTAAAGGGAATATCACACTCACATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAGGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c066-121 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGGAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGTTGCTATTAACAAGAGATGGTGGCAACACGAACGAAATCTTCAGACCTGGA p1c024-53 GAAGAGGTAGTAATTAGATCTGACAATTTCATGGACAATGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTGTACAGGTAGGACCAGGGAGAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGCTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCGGCACGAACGAAATCTTCAGACCTGGA p1c014-12 GAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAACGCTAAAACCATAATAGTACAGCTGAAGGAGTCTGTAGTAATTAATTGTACAAGACCCAATAACAATACAAGAAAAAGTATACAGGTAGGACCAGGGAAAGCAATTTATACAACAGGAGAAATAATAGGAGATATAAGACAAGCACATTGTAACCTTAGTAGAGCAGAATGGAATAACACTTTAAAACAGATAGTTAAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCAATCCTCAGGAGGGGACCCAGAAATTGTAATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATTCAACACAACTGTTTAATAGTACTTGGTTGAATACTGAAGGGAATATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGAGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGTAACACGAGCGAAATCTTCAGACCTGGA p1c066-132 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGAAAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAATACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCACACTCCCATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA p1c068-151 AAAGAGGTAGTAATTAGATCTGAAAATTTCACGGACAATGCTAAAACCATAATAGTACAGCTGAATGAGTCTGTAGTAATTAATTGTACAAGACCCAGTAACAATACAAGAAGAAGTATAGCGGTAGGACCAGGGAGAGCAATTTATGCAACAGATAAAATAATAGGAGATATAAGAAAAGCACATTGTAACCTTAGTAGAGCAGCATGGAATAACACTTTAAGACAGATAGTTGAGAAATTAAGAGAACAATTTGGGAATAAAACAATAGTCTTTAATCGATCCTCAGGAGGGGACCCAGAAATTGTGATGCACAGTTTTAATTGTGGAGGGGAATTTTTCTACTGTAGTACAACACAACTGTTTAATAGTACTTGGTTAAATACTGAAGGGAAGATCATACTCCAATGCAGAATAAAACAAATTATAAACATGTGGCAGGAAGTAGGAAAAGCAATGTATGCCCCTCCCATCAGTGGACAAATTAGATGTTCATCAAATATTACAGGGCTGCTATTAACAAGAGATGGTGGCAACACAAACGAAATCTTCAGACCTGGA phyml-3.2.0/examples/phytime_input_files/p1.tree000066400000000000000000000062611263450375500217630ustar00rootroot00000000000000((((p1c024-62:0.001000,(p1c014-30:0.010000,(p1c061-11:0.015290,p1c045-98:0.004157)0.878000:0.016334)0.000000:0.100000)0.000000:0.010000,(p1c024-61:0.004139,(p1c024-53:0.04097,(p1c024-60:0.06169,(p1c024-44:0.06252,p1c024-71:0.002059)0.000000:0.020000)0.000000:0.003000)0.963000:0.018401)0.773000:0.02045)0.827000:0.102057,(p1c014-32:0.000100,((p1c003-24:0.02058,(p1c003-16:0.002058,p1c014-05:0.02059)0.000000:0.000000)0.000000:0.000000,((p1c034-86:0.010000,(p1c003-18:0.000200,p1c003-15:0.06337)0.000000:0.100000)0.000000:0.030000,(p1c014-25:0.002056,(p1c003-19:0.030000,(p1c003-20:0.050000,(((p1c045-86:0.06232,p1c051-323:0.010552)0.750000:0.02140,((p1c024-57:0.019383,(p1c014-12:0.000100,p1c014-38:0.004206)0.000000:0.010000)0.806000:0.02066,(((p1c066-128:0.04166,(p1c066-127:0.100000,p1c051-115:0.200000)0.000000:0.300000)0.748000:0.05635,(p1c014-33:0.007820,p1c014-27:0.011384)0.364000:0.004172)0.782000:0.002751,(p1c014-24:0.008364,(p1c014-22:0.004177,p1c024-55:0.06299)0.366000:0.002079)0.000000:0.100000)0.000000:0.030000)0.000000:0.100000)0.000000:0.040000,((p1c034-66:0.040000,p1c034-77:0.004105)0.763000:0.02142,(p1c024-52:0.016976,(p1c034-75:0.008236,((p1c034-79:0.010306,((p1c034-67:0.006136,(p1c045-84:0.008265,(p1c034-81:0.002037,((p1c045-93:0.017023,(p1c034-64:0.006125,(p1c051-326:0.030690,p1c045-81:0.010405)0.327000:0.02232)0.772000:0.002113)0.314000:0.002074,(p1c045-435:0.010446,(p1c051-106:0.004514,((p1c061-03:0.016801,p1c068-158:0.020503)0.859000:0.007790,(((p1c061-06:0.06121,(p1c068-149:0.012554,p1c061-08:0.002099)0.911000:0.006163)0.000000:0.100000,(((p1c066-126:0.010000,p1c051-114:0.010000)0.969000:0.008221,(p1c061-01:0.004106,(p1c066-132:0.020000,(p1c051-120:0.020000,(p1c077-173:0.10418,(p1c068-151:0.002062,(((p1c077-317:0.06185,(p1c077-313:0.01902,p1c077-176:0.08556)0.980000:0.012925)0.748000:0.02133,((p1c077-308:0.04121,p1c077-306:0.08485)0.860000:0.04254,(p1c077-315:0.010647,(p1c077-307:0.06066,(p1c077-311:0.011436,p1c077-167:0.008778)0.000000:0.01929)0.750000:0.002404)0.758000:0.002033)0.776000:0.02064)0.769000:0.02061,((p1c068-146:0.010000,p1c068-144:0.008384)0.817000:0.002041,((p1c068-150:0.002052,p1c066-123:0.004098)0.761000:0.02055,(p1c068-141:0.002047,(p1c066-136:0.002091,p1c068-147:0.004152)0.766000:0.002039)0.000000:0.010000)0.000000:0.100000)0.000000:0.020000)0.782000:0.002052)0.854000:0.004161)0.758000:0.002121)0.000000:0.100000)0.927000:0.06260)0.758000:0.02062)0.000000:0.010000,(p1c066-121:0.006053,p1c068-159:0.019444)0.648000:0.02188)0.956000:0.08229)0.827000:0.005795,(p1c061-04:0.010791,p1c061-13:0.003790)0.961000:0.011377)0.865000:0.07491)0.924000:0.07656)0.767000:0.03628)0.859000:0.04255)0.000000:0.010000)0.000000:0.010000)0.000000:0.020000)0.823000:0.02040,(p1c045-96:0.008335,(p1c045-92:0.002029,p1c045-440:0.008390)0.873000:0.04272)0.762000:0.01974)0.000000:0.030000)0.883000:0.04102,(p1c045-90:0.04188,(p1c061-12:0.06372,(p1c061-05:0.08630,(p1c066-134:0.08886,p1c061-10:0.08525)0.732000:0.01678)0.897000:0.06511)0.909000:0.08252)0.834000:0.03998)0.757000:0.02127)0.765000:0.02003)0.385000:0.02118)0.919000:0.06214)0.846000:0.02065)0.000000:0.100000)0.000000:0.100000)0.000000:0.100000)0.000000:0.010000)0.000000:0.020000)0.000000:0.300000)0.000000:0.02065,p1c003-17:0.02065); phyml-3.2.0/examples/proteic000066400000000000000000000626061263450375500160770ustar00rootroot0000000000000037 547 tax1 ALSDPSKLES DKDLRIDITP DKENKTLTIR DTGIGMTKAD LVNNLGTIAR SGTKQFMEAL tax2 SLSDPSKLDT GKDLRIDIIP DKENKTLTIQ DTGIGMTKAD LVNNLGTIAR SGTKQFMEAL tax3 SLTDASVLES KTELEIKIIP DKTAKTLTLI DSGIGMTKTD MVKNLGTIAR SGTKNFMEQL tax4 SLTDKSKLDA QPELFIRIIP DKATNTLTLI DSGIGMTKSD LVNNLATIGR SGTKDFMEAL tax5 SLTDKSKLDA QPELFIRLVP DKASKTLSII DSGVGMTKSD LVNNLGTIAR SGTKEFMEAL tax6 SLTDKSKLDG QPELFIHIIP DKANNTLTII DSGIGMTKAD LVNNLGTIAR SGTKEFMEAL tax7 SLSDKSILDT EAAMEIRIIA DKEAKTLTLQ DTGVGMTKGD LVNNLGMIAN SGTKSYMEAL tax8 SLTDSSVLDN EPKLEIRILT DKNNKSLTLI DTGIGMTKDD LIQNLGTIAK SGTKSFMEAL tax9 SLTDKSKLDA QPELFIHIVP DKASNTLSII DSGIGMTKSD LVNNLGTIAR SGTKEFMEAL tax10 SLTDKSKLDG QPELFIHIIP DKTNNTLTII DSGIGMTKAD LVNNLGTIAR SGTKEFMEAL tax11 SLTDKSKLDG QPELFIHIIP DKTNNTLTII DSGIGMTKAD LVNNLGTIAR SGTKEFMEAL tax12 SLTDKSKLDG QPELFIHIIP DKTNNTLTII DSGIGMTKAD LVNNLGTIAR SGTKEFMEAL tax13 SLTDKSKLDA QPELFIRLVP DKTNKTLSII DSGVGMAKAD LVNNLGTIAR SGTKEFMEAL tax14 SLTDPSVLGE SPRLCIRVVP DKENKTLTVE DNGIGMTKAD LVNNLGTIAR SGTKAFMEAL tax15 SLTDPSVLGD ATRLCVRVVP DKENKTLTVE DNGIGMTKAD LVNNLGTIAR SGTKAFMEAL tax16 SLTNQSVLGD EPHLRIRVIP DRVNKTLTVE DSGIGMTKAD LVNNLGTIAR SGTKSFMEAL tax17 SLTNQAVLGD ESHLRIRVVP DKANKTLTVE DTGIGMTKAE LVNNLGTIAR SGTKAFMEAL tax18 ALTEPSELDT GKELFIKITP NKEEKTLTIM DTGIGMTKAD LVNNLGTIAK SGTKAFMEAL tax19 ALTEPAELET GKELYIKITP NKADKTLTIM DTGIGMTKAD LVNNLGTIAK SGTKAFMEAL tax20 SLTDPTKLDS GKDLKIDIIP NVQERTLTLI DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax21 SLTDPSKLDS GKELHINIIP NKQDRTLTIV DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax22 SLTDPTKLDS GKELFIKIIP NKEAGTLTLI DTGIGMTKAD LVNNLGTIAK SGTKAFMEAL tax23 SLTDPSKLDS GKELYIKLIP NKTAGTLTII DTGIGMTKSD LVNNLGTIAK SGTKAFMEAL tax24 SLTDPTKLDN GKELKIDVIP NVEERTLTLI DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax25 SLTDPSKLDS GKELKIDIIP NPQEATLTLV DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax26 SLTDPSKLDS GKELHINLIP SKQDRTLTIV DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax27 SLTDPSKLDS GKELKIDIIP NPQERTLTLV DTGIGMTKAD LINNLGTIAK SGTKAFMEAL tax28 VCSDPSKPGL QDHSSIDIIP DKANKTLTIR DTGIGMTKAD LVNNLGTIAR SGTKQFMEAL tax29 ALSDPSQLES EPELFIRITP HKDQKVLEIR DSGIGMTKAD LVNNLGTIAK SGTKSFMEAL tax30 ALSDPSQLES EPELFIRIIP QKDQKVLEIR DSGIGMTKAD LVNNLGTIAK SGTKSFMEAL tax31 SLSDPHALDA EKDLFIRITP DKENKILSIR DTGIGMTKND LINNLGVIAK SGTKQFMEAA tax32 SLSDPKQLET EPDLFIRITP KPEQKVLEIR DSGIGMTKAE LINNLGTIAK SGTKAFMEAL tax33 AIKDPKQVED FPEYQISLSA DKTNKTLTIE DTGIGMTKTD LINNLGTIAK SGTKAFMEAI tax34 SITDTQKLSA EPEFFIRIIP DKTNNTLTIE DSGIGMTKND LINNLGTIAR SGTKAFMEAI tax35 SITDSEKAKL EPNFRIRIIP DKANNTLTLW DTGIGMTKKE LINNLGTIAK SGTKAFMEAL tax36 AITEPEKLKT KPELFIRLIP DKANNTLTIE NSGIGMTKAD LVNNLGTIAR SGTKAFMEAL tax37 AIKDPKQIED QPDYYIRLYA DKNNNTLTIE DSGIGMTKAD LVNNLGTIAK SGTRAFMEAL TSMIGQFGVG FYSAYLVADK VTVISKSNDD QYIWESNAGG TFKVTDGRAI GRMILHLDEQ TSMIGQFGVG FYSAYLVADR VTVVSKNNDD QYIWESSAGG TFNISDGPSI GRIILHLDEQ QSMIGQFGVG FYSAYLVADT VIVHSKNNDD QYVWESSAGG EFTIADTEPL GRIVLHMEDQ ASMIGQFGVG FYSAYLVAER VIVTSKHNDD QHVWESQAGG SFTVTDGEPL GRITLYLDDQ ASMIGQFGVG FYSAYLVADR VMVTTKHNDD QYVWESQAGG SFTVTDGEQL GRITLFLDDQ ASMIGQFGVG FYSAYLVAEK VVVTTKHNDD QYVWESQAGG SFTVTDGENL GRMVLYLEDQ SSMIGQFGVG FYSAYLAADN VVVHTKHNDD QYVWESSAGG SFTIRKGPAL TRVVLHLDDQ QSMIGQFGVG FYSAYLVADR VVVETKNNND QYIWESSAGG SFTINDITDL ARITLFLDDQ ASMIGQFGVG FYSAYLVAER VVVTTKHNDD QYVWESQAGG SFTVTDGEQL GRITLYLDDQ ASMIGQFGVG FYSAYLVADK VVVTTKHNDD QYVWESQAGG SFTVTDGEAL GRMVLYLEDQ ASMIGQFGVG FYSAYLVADK VVVTTKHNDD QYVWESQAGG SFTVTDGETL GRMVLYLEDQ ASMIGQFGVG FYSAYLVADK VVVTTKHNDD QYVWESQAGG SFTVTDGEAL GRMILYLEDQ QSMIGQFGVG FYSAYLVAEK VIVTTKHNDD QYIWESQAGG SFTVTDGEQL GRITLFLEDQ ESMIGQFGVG FYSAYLVADR VTVTSKNNSD SYVWESSACG TFTITTESDM KRITLHLEDQ ESMIGQFGVG FYSAYLVADR VTVTSKNNSD VYVWESSAGG TFTITAESDM KLITLHLEDQ ESMIGQFGVG FYSAYLVADR VTVVSKNNED AYTWESSAGG TFTVTTDCDL KRIVLHLEDQ ESMIGQFGVG FYSAYLVADR VTVVSKNNDD AYTWESSAGG TFTVTTDCDL KRIVLHLEDQ QSMIGQFGVG FYSAFLVADK VVVTSKNNDD SYQWESSAGG SFVVRFDPEV TRIVMHIEDQ QSMIGQFGVG FYSAFLVADK VVVASKHNDD CYQWESSAGG SFIIRVDPEL TRITLYIEDQ QSMIGQFGVG FYSAYLVAEK VTVITKHNDD QYAWESSAGG SFTVKDGEPI GRVILHLEDQ QSMIGQFGVG FYTAYLVAEK VTVITKHNDD QYAWESSAGG SFTVRDGEPM GRVILHLEDQ QSMIGQFGVG FYSAYLVADK VVVTSKNNDD QYVWESSAGG SFTVRDGEPL GRIVLHIEDQ QSMIGQFGVG FYSAYLVADK VTVTSKNNDD QYVWESSAGG SFTVRDSEPL GRIVLYIEDQ QSMIGQFGVG FYSAYLVAER VTVITKHNDD QYIWESSAGG SFTVKDGEPM LRVILHMEDQ QSMIGQFGVG FYSAYLVAEK VVVITKHNDD QYAWESSAGG SFTVRDGEPI GRVILHLEDQ QSMIGQFGVG FYSAYLVAEK VTVITKHNDD QYAWESSAGG SFTVRDGEPM GRVILHLEDQ QSMIGQFGVG FYSAYLVAEK VVVITKHNDD QYAWESSAGG SFTVRDGEPI GRVILHLEDQ TSMIGQFGVG FYSAYLVADR VTVVSKHNDD QYIWESSAGG TFTIRDGEPL AKIILHLEEQ SSMIGQFGVG FYSLFLVADH VQVVSKHNDD QYIWESNAGG KFTVTDNERL GRLRLFLEDQ SSMIGQFGVG FYSLFLVADH VQVISKHNDD QYVWESNAGG KFTVTDNERL GRLRLFLEDQ ASMIGQFGVG FYSAYLVADK VQVVSKHNDD QYIWESSAGG SFTVTDGPRL LRIRLFMEDQ SSMIGQFGVG FYSLFLVADR VQVISKSNDD QYIWESNAGG SFTVTDNERI GRLRLFLDDQ QSMIGQFGVG FYSAYLVADK VTVVSKNNND QYVWESNASG HFTVTDEDQL KRLILHLDDQ QSMIGQFGVG FYSAYLVADH VVVISKNNDD QYVWESAAGG SFTVTDNEKL GRIILHLEDQ SSMIGQFGVG FYSAYLVAEK VEVISKSNDD QWRWESSAGG TFTVVDNPEK LRIILHMNDN QSMIGQFGVG FYSAYLVADS VTVVSKHNDD QYVWESAAGG SFTVQDYEPL GRIILHLEDQ QSMIGQFGVG FYSAYLVADK VTVVSKNNAD QYVWESTASG HFTVKDHEPL KRLILHLEDQ TEYLNESKIK EVVKKQSEFI FYPIYLHVLK EEKEVPDAKK TKKIKENKIE EEELNKTKPI TDYLNESKIK EVIKKHSEFI SYPIYLHVQK EEVEVPDKPK TKKVKEVKTE EEELNKQKPI LDYLDETKIK NLVKKHSEFI QYPISLLTIK EDEETTAEKE KKKVKVQEKE WDVLNKTKPL LEYLEERRLK DLVKKHSEFI SYPISLWTEK TEKEISDEKK KKKIKEVSHE WNLINKQKPI LEYLEERRLK DLVKKHSEFI SYPIYLWTEK TEKEISDSKK KKKVKEVSHE WVQINKQKPI LEYLEERRLK DLIKKHSEFI SYPISLWVEK TEKEISDEKK KKKVKEVSNE WSLVNKQKPI QEWLEERRIK DLVKKHSEFI QYPIKLWVEK EEKEVEVKKK TKKIKEKEHE WQLLNKNKPI LEYLEERRLK DLVKKHSEFI QYPINLWVEK EEKEVDAEKK KKKIKEISHE WQFLNKNKPI LEYLEERRLK DLIKKHSEFI SYPISLWTEK TEKEISDEKK KKKIKEVSHE WSLVNKQKPI MEYIEERRLK DLVKKHSEFI SMGISLWIEK TEKEISDEKK KKKIKEVSHE WDLVNKQKPI LEYLEERRLK DLVKKHSEFI SYPISLWIEK TEKEISDEKK KKKIKEVSHE WDLVNKQKPI MEYIEERRLK DLVKKHSEFI SYPISLWIEK TEKEISDEKK KKKIKEVTHE WDLVNKQKPI LEYLEERRIK DLVKKHSEFI SYPIYLWTEK TEKEISDGKK KKKIKEVSHE WQLINKQKPI MEYLEPRRLK ELIKKHSEFI GYDIELMVEK TEKEVTDKKK TKKVKEVTKE YEVQNKHKPL LEYLEARRLK ELIKKHSEFI GYDIELMVEK TEKEVTDKKK TKKVKEVTKE YEVQNKHKPL QEYLEERRLK DLIKKHSEFI GYDIELMVEN TEKEVTDKKK TKKVKEVKQE FVVQNKHKPL QEYLEERRLK DLIKKHSEFI GYDIELMVEK AEKEVTDKKK TKKVKEVTQE FVVQNKHKPL IDFLEERKIK EIVKKHSQFI GYPIKLVVEK EEKEVEDKKK TKKIKEKYFE DEELNKTKPI TDYLEERRIK EIVKKHSQFI GYPIKLTVEK EDKEVSDDKK KKKIKEKYHE DEELNKTKPI TEYIEEKRVK EVVKKHSQFI GYPITLYVEK EDKEISDKKK KKKIKEKYID QEELNKTKPI TEYMEERRIK EIVKKHSQFI GYPITLFVEK EDKEVSDKKK KKKIKEKYID QEELNKTKPI LEYLEESKIK QIVNKHSQFI GYPIKLLVEK EEKEVSDDKK KKTVKVKYTE DEELNKTKPI TDYLEESKIK EIVNKHSQFI GYPIKLLVEK EEKEVSDAKK KKTIKEKYTE DEELNKTKPI TEYVEEKRVK EVVKKHSQFI GYPITLFVEK EEKEISDKKK TKKIKEKYID QEELNKTKPI TEYLEERRVK EVVKKHSQFI GYPITLYLEK EEKEISDKKK TKKIKEKYID QEELNKTKPI TEYLEERRIK EIVKKHSQFI GYPITLFVEK EDKEVSDKKK KKKIKEKYID QEELNKTKPI TEYLEERRVK EVVKKHSQFI GYPITLYLEK EEKEISDKKK TKKIKEKYID QEELNKTKPI LDYLNESRIK EVVKKHSEFI SYPIYLHVQI SEVTEEGRRR SRTIKETRSE EEELNKQKPI LEYLEEKRII EVVKKHSEFV AYPIQLVVTK EEKEVPEEKK TKKIKEEVTE TEELNKTKPL LEYLEEKRIK EVVKKHSEFV AYPIQLVVTK EEKEVPEEKK TKTVKEEVTE TEELNKTKPL LQYLEEKTIK DTVKKHSEFI SYPIQLVVTR EEKEVPEKKE KKKVKETTTE TEELNKTKPI LEYLEEKRIK EVIKRHSEFV AYPIQLVVTK EEKEVPIKPK TKKVKEEVQE IEELNKTKPL SEYLEERRLK ELVKKHSEFI SFPIRLSVEK TETEVTDEKK KRKVTNVTRE WEMLNKQKPI LEYLEEKRIK DLVKKHSEFI SFPIKLYCER QEKEITAEKR KKKIHTVEHE WEELNKQKPL LEFLEERRIK DLIKKHSEFI AFPIELQVEK TEKEETDDKK KKKVKVVHTE FEEQNKNKPL GEYLEERRLK DLVKKHSEFI SFPIELAVEK TEREVTETGK TKKVQEVTRE WEQLNKQKPL TEYLEERRLK ELVKKHSEFI SFPISLSVEK TETEVTDKKK KRKVTNVTRE WEMLNKQKPI WTRNPADITQ EEYASFYKTN DWEDHLAVKH FSVEGQLEFR AILFVPKRAP FDLFETKTKN WTRNPQDITQ EEYAAFYKSN DWEDHLAVKH FSVEGQLEFK AILFVPKRAP FDLFETKTKN WTRNPSDVTK EEYNSFYKSN DWEEPLAVKH FSVEGQLEFK AILFVPKKAP FDLFESKKAN WMRKPEEITK DEFAAFFKTN DWEEHLGVKH FSVEGQLEFK AVLFVPKRAP FDLFDTRKLN WLRKPEEITR DEYASFYKTN DWEDHLAVKH FSVEGQLEFK AILFVPRRAP FDLFDTRKLN WMRKPEEITK EEYAAFYKTN DWEEHLAVKH FSVEGQLEFK AVLFVPKRAP FDLFDTKKPN WTRKPEEVTK EEYASFYKTN DWEEHLTVKH FSLEGQLEFR AILFCPKRAP FDLFEPRKLN WTRKPEEISK EEYSSFYKSN DWEDHLAVKH FSVEGQLEFK ALLFVPKRAP FDLFEPRKNN WMRKPEEITK EEYAAFYKTN DWEEHLAVKH FSVEGQLEFK AVLFVPKRAP FDLFDTRKLN WMRKPEEINK EEYAAFYKSN DWDKDLAVKH FSVEGQLEFK AILFVPKRRP FDLLYTKKPN WMRKPEEINK EEYAAFYKSN DWEEHLAVKH FSVEGQLEFK AILFVPKRAP FDLFDTKKPN WMRKPEEINK EEYAAFYKSN DWEEHLAVKH FSVEGQLEFK AILFVPKRAP FDLFDTKKPN WLRKPEEITK EEYASFYKTN DWEDHLAVKH FSVEGQLEFK AILFVPKRAP FDLFDTRKMN WTRDPKDVTK EEYAAFYKSN DWEDPRATKH FSVEGQLEFR SIMFVPKRAP FDMFEPNKRN WTRDPKDVTK EEYAAFYKSN DWEDPPATKH FSVEGQLEFR AIMFVPKRAP FDMLEPNKRN WTRDPKDVTK EEYASFYKSN DWEEQLSTKH FSVEGQLEFR AILFLPKRAP FDMFEPNKRN WTRDPKDVTK EEYAAFYKSN DWEEPLSTKH FSVEGQLEFR AILFVPKRAP FDMFEPSKRN WTRNPDDISN EEYAEFYKSN DWEDHLAVKH FSVEGQLEFR ALLFVPQRAP FDLFENKSKN WTRNPDDISN EEYAEFYKSN DWEDHLAVKH FSVEGQLEFR ALLFVPQRAP FDLFENKTKN WTRNPDDISN EEYGEFYKTN DWEDHLAVKH FSVEGQLEFR ALLFIPRRAP FDLFENKKKN WTRNPDDITN EEYGEFYKTN DWEEHLAVKH FSVEGQLEFR ALLFVPRRAP FDLFENRKKN WTRNADDISQ EEYGEFYKTN DWEDHLAVKH FSVEGQLDFR ALLFVPRRMP FDLFENKKKN WTRNPDDISQ EEYGEFYKTN DWEDHLAVKH FSVEGQLEFR ALLFIPRRTP FDLFENQKRN WTRNPDDITM EEYGEFYKTN DWEEHLAVKH FSVEGQLEFR ALLFIPRRAP FDLFENKKKN WTRNPDDITQ EEYGEFYKTN DWEDHLAVKH FSVEGQLEFR ALLFIPRRAP FDLFENKKKN WTRNPDDITN EEYGEFYKTN DWEEHLAVKH FSVEGQLEFR ALLFVPRRAP FDLFENRKKN WTRNPDDITQ EEYGEFYKTN DWEDHLAVKH FSVEGQLEFR ALLFIPRRAP FDLFENKKKN WTRNPQDITQ EEYAAFYKSN DWEDHLAVKH FSVEGQLEFR AILFVPKRAP FDLFETKTKS WTRNPSDITQ EEYNAFYKSN DWEDPLAVKH FSVEGQLEFR AILFVPKRAP FDAFESKKKS WTRNPSDITQ DEYNAFYKSN DWEDPLAVKH FSVEGQLEFR AILFVPKRAP FDAFESKKKN WTRNPSEVTK EEYASFYKTN DWEDHLAVKH FSVEGQLEFR AILFVPRRAP MDLFEAKKKN WTRNPSDITQ EEYNAFYKSN DWEDPLYVKH FSVEGQLEFR AILFIPKRAP FDLFESKKKN WMRLPTEVTN EEYASFYKSN DWEDHLAVKH FSVEGQLEFK AILFVPKRAP FDMFENRKKN WMRKPEEVTN EEYASFYKTN DWEDHLAVKH FSVEGQLEFK ALLFIPKRAP FDMFENRKRN WMRKPEEITK EEYVNFYKTN DWEEHQAVKQ FSVEGQLEFR AILFIPKRAP FDLFETKKKN WMRKPEEVTE EEYASFYKSN DWEEHLAVKH FSVEGQLEFK ALLFVPKRAP FDLFETRKRN WMRLPSEVTN EEYAAFYKTN DWEDHLAVKH FSVEGQLEFK ALLFVPRRAP FDMFESRKKN NIKLYVRRVF ITDDATDLIP EWLSFIKGVV DSEDLPLGLS RETLQQNKIM KVIKNIVKKT NIKLYVRRVF ITDDATDLIP EWLSFVKGVV DSEDLPLNLS RETLQQNKIM KVIKNIVKKA NIKLYVKRVF IMDNCADIIP EYLNFVRGIV DSEDLPLNIS RETLQQNKIL TVIKNLVKKC NIKLYVRRVF IMDNCEELIP EWLSFVKGIV DSEDLPLNIS RETLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCEELIP EWLGFVKGVV DSDDLPLNIS RETLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCDELIP EYLSFVKGIV DSEDLPLNIS RETLQQNKIL KVIKNLVKKC NIKLYVKRVF IMDNCEDIIP EYLNFVKGVV DSEDLPLNLS REMLQQNKIL KVIKNLVKKC NIKLYVKRVF IMDNCDEIIP EYLNFIKGVV DSEDLPLNIS RETLQQNKVV KVIKNIVKKC NIKLYVRRVF IMDNCEELIP EWLSFVKGIV DSEDLPLNIS REMLQQNKIL KVIKNLVKKC NISLYVRRVF IMTYCEDIIP EYLGFVKGIV DSEDLPLNIS RETLQQNKIS MVIKNLVKKC NIKLYVRRVF IMDNCEDIIP EYLGFVKGIV DSEDLPLNIS RETLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCEDIIP DYLGFVKGIV DSEDLPLNIS RETLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCEELIP EYLGFVKGVV DSDDLPLNIS REMLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCEDLCP DWLGFVKGVV DSEDLPLNIS RENLQQNKIL KVIKNIVKKC NIKLYVRRVF IMDNCEDLCP DWLGFVKGVV DSEDLPLNIS RENLQQNKIL KVIKNIVKKC NIKLYVRRVF IMDNCEDLCP EWLGFLRGVV DSEDLPLNIS RENLQQNKIL KVIKNIVKKA NIKLYVRRVF IMDNCEDLCP EWLAFVRGVV DSEDLPLNIS RENLQQNKIL KVIKNIVKKA SIKLYVRRVF IMENCEELMP EYLNFIKGVV DSEDLPLNIS REMLQQSKIL KVIKNLVKKC AIKLYVRRVF IMENCDELMP EYLNFIKGVV DSEDLPLNIS REMLQQSKIL KVIKNLVKKC NIKLYVRRVF IMDNCEELIP EYLNFIRGVV DSEDLPLNIS REMLQQSKIL KVIKNIVKKC NIKLYVRRVF IMDNCEELFP EYLNFIRGVV DSEDLPLNIS REILQQSKIL KVIKNLVRKC NIKLYVRRVF IMDNCEELIP DYLNFMKGVV DSEDLPLNIS REMLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDNCEDLIP EYLNFMKGVV DSEDLPLNIS REMLQQNKVL KVIKNLVKKT NIKLYVRRVF IMDSCEELIP EYLNFVRGVV DSEDLPLNIS REMLQQSKIL KVIKNIVKKC NIKLYVRRVF IMDSCDDLIP EYLNFIRGVV DSEDLPLNIS REMLQQSKIL KVIKNIVKKC NIKLYVRRVF IMDNCEELIP EYLNFIRGVV DSEDLPLNIS REMLQQSKIL KVIKNLVKKC NIKLYVRRVF IMDSCDELIP EYLNFIRGVV DSEDLPLNIS REMLQQSKIL KVIKNIVKKC NIKLYVRRVF ITEHATDLVP EWLSFIKGVV DSEDLPLNLS RETLQQNKIM KVIKNIVKKS NSKLYVRRVF ITDDAEELIP EWLSFVKGVV DSEDLPLNLS REMLQQNKIL KVIKNISKKM NIKLYVRRVF ITDDAEELIP EWLSFIKGVV DSEDLPLNLS REMLQQNKIL KVIKNIVKKM NIKLYVRRVF ITDDCEELIP EWLGFIKGVV DSEDLPLNLS REMLQQNKIM KVIKNLVRRC NIKLYVRRVF ITDEAEDLIP EWLSFVKGVV DSEDLPLNLS REMLQQNKIM KVIKNIVKKL NIKLYVRRVF IMDDCDELIP EWLGFVKGVV DSEDLPLNIS REVLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDDCEEIIP EWLNFVKGVV DSEDLPLNIS RESLQQNKIL KVIKNLIKKC NIKLYVRRVF IMDDCEELIP EYLNFIKGVV DSEDLPLNIS REFLQHNKIL KVIKNIVKKC NIKLYVRRVF IMDDCEDIIP EWLNFVKGVV DSEDLPLNIS RESLQQNKIL KVIKNLVKKC NIKLYVRRVF IMDDCEELIP EWLSFVKGVV DSEDLPLNIS RETLQQNKIL KVIKNLVKKC LELFNEIAED REQFKFYSAF SKNIKLGVHE DAQNRPALAK LLRYNSTTTS LTDYVTRMPE LELFTEIAED KEQFKFYTAF SKNIKLGIHE DSQNRNTLAK LLRFNSTQTS LSDYVTRMPE IELFNEIAEN SEDYKFYEAF SKNLKLGVHE DSQNREKFAD LLRYQTSLVT LKEYVGRMKE IELFFEIAEN KEDYKFYEAF SKNLKLGVHE DSTNRTKLAE LLRYHSTLTS LKDYVTRMKE IEMFFEIAEN KDDYKFYDAF SKNIKLGIHE DSQNRAKLAD LLRYHSTTTS LKDYVTRMKE VELFFEIAEN KEDYKFYEAF SKNLKLGIHE DSQNRAKFAE LLRYHSTMTS LKDYVTRMKE MDMFAEAAEN KEDYVFYEQF SKNLKLGIHE DAQNREKLAE LLRYNTTLTS LKEYVSRMKE LELFLEISEN KDDVIFYDQY SKNIKLGIHE DSQNRSKLAD LLRYKSTTTT LKEYVSRMKE VELFFEIAEN KEDYKFYEAF SKNLKLGIHE DSTNRNKIAE LLRYHSTLTS LKDYVTRMKE LELFFEIAEN KEDYKFYEAF SKNLKPGIHE DSKIRTKIAE LLRYHSTLTS LKDYVTRMKE LELFFEIAEN KEDYKFYEAF SKNLKLGIHE DSQNRTKIAE LLRYHSTLTS LKDYVTRMKE LELFFEIAEN KEDYKFYEAF SKNLKLGIHE DSQNRTKIAE LLRYHSTLTS LKDYVTRMKE IEMFNEIAEN KDDYKFYEAF SKNLKLGIHE DSQNRAKLAD LLRYYSTLTS LKDYVTRMKE LEMFDEVAEN KEDYQFYEQF GKNIKLGIHQ DTANRKKLME FVRFYSSMTT LKDYVTRMKA LEMFEEVAEN KEDYQFYEQF GKNIKLGIHE DTANRKKLME LLRFYSTMTT LKDYVTRMKA LELFEELAGN KEDYKFYEQF SKNVKLGIHE DSTNRKKLME LLRFHSSMTT LKDYVTRMKE LELFEEIAEN KEDYKFYEQF GKNVKLGIHE DSANRKKLME LLRFHSSMTT LKDYVTRMKE MELIDEVAED KDNFKFYEQF GKNLKLGIHE DSTNRKKLSD FLRYSTSPTS LKEYVSRMKE LELFDEIAED KDNFKFYEQF SKNIKLGIHE DSTNRKKLSE FLRFYTSMTS LKDYVSRMKE LELFAELAED KDNYKFYDAF SKNLKLGIHE DCQNRKKLSE LLRYQSSMTS LTEYVSRMKE LELFHELAED KENYKFYEQF SKNIKLGIHE DSQNRKKLSE LLRYYTSMVS LKDYCTRMKE MELFEELAED KETYKFYDQF SKNLKLGVHE DSQNRQKLAD LLRFNTSYCS LNDYVGRMKE MELIEELTED KENYKFYDQF SKNLKLGVHE DSNNRAKLAD FLRFHTSFCS LADYVSRMKD MELFGELAED RENYKFYDGF SKNLKLGIHE DSQNRKKLSE LLRYHSSLTS LTEYLTRMKD LELFSELAED KENYKFYEAF SKNLKLGIHE DSTNRRRLSE LLRYHTSMTS LSEYVSRMKE LELFTELAED KENYKFYEQF SKNIKLGIHE DSQNRKKLSE LLRYYTSMVS LKDYCTRMKE LELFSELAED KENYKFYEAF SKNLKLGIHE DSTNRRRLSE LLRYHTSMTS LSEYVSRMKE IELFNEIAED KEQFKFYSAF SKNIKLGIHE DAQNRSALAK LLRFHSTMTS LSDYVARMPE IETFNEISED QEQFQFYTAF SKNIKLGIHE DAQNRQALAK LLRFYSTMTS LSDYVTRMPE IETFNEISED QEQFQFYTAF SKNIKLGIHE DAQNRQSLAK LLRFYSTMTS LSDYVTRMPE LDMFNEIAED KENFTFYDAF SKNLKLGIHE DAANRPALAK LLRYNSLLIS LEDYITKMPE IEAFNEIAED SEQFKFYSAF SKNIKLGVHE DTQNRAALAK LLRYNSTLTS LTDYVTRMPE LELFSELTEK KEDFKFYEQF SKNLKLGIHE DNTNRNKISE LLRYETSAIS LKEYVDRMKP LDMFSELAEN KENYKFYEQF SKNLKLGIHE DNANRTKITE LLRFQTSMIG LKEYVDRMKE LDLIQEVADN EEDFKFYEQF GKNLKLGIHE DSANREKLSS FLRYHSSLTT LKDYVSRMKE LEMFAEIEEK KENYKFYEQF SKNLKLGIHE DSANRAKIAE LLRFHSSMVS FKEYVDRMKE LELFNELTEK KEDFKFYEQF SKNLKLGIHE DNANRSKIAE LLRFETTLVS LKEYVDRMKS HHKTIYYITG ESLKAVQKSP FLDTLKEKNF EVLFLVDPND EYAMTQLKEF DGKKLVDITK HQKNMYYITG ESIKAVSKSP FLDSLKEKGF EVLFLVDPID EYAMTQLKEF EGKKLVDITK GQNEIYYITG ESKKAVENSP FIEGLKKKNL EVIYMCDPID EYAVQQLKEY DGKKLVSITK GQNDIYYITG ESKKAVENSP FLEKLKKKGY EVLYMVDAID EYSIGQLKEF EGKKLVSATK GQKDIYYITG ESRKAVENSP FLERLKKKGY EVLFMVDAID EYAVGQLKEY DGKKLVSATK GQNDIYYITG ESKKAVENSP FLEKLKKKGY EVLYMVDAID EYSIGQLKEF EGKKLVSATK GQKNIYYITG ASKKAVENAP FLEKLKKKGF EVIYMTEPID EYCVQQLKEY DGKKLVCTTK NQNQIYYITG ESQKSVENSP FLEKLKQKGF EVLFMIEPID EYCVQQLKEY EGKKLVCATK GQNDIYYITG ESKKAVENSP FLEKLKKKGY EVLYMVDAID EYAVGQLKEF EGKKLVSATK GQNDIFYITG ESKKAVENSP FLEKLKKKGI EVLYMVDAID EYAIGQLKEF EGKKLVSATK GQNDIFYITG ESKKAVENSP FLEKLKKKGI EVLYMVDAID EYAIGQLKEF EGKKLVSATK GQNEIFYITG ESKKAVENSP FLEKLKKKGY EVLYMVDAID EYAIGQLKEF EGKKLVSATK GQKDIYYITG ESKKAVENSP FLERLKKKGY EVLFMVDAID EYAVGQLKEY DGKKLVSATK GQKSIYYITG DSKKKLESSP FIEQAKRRGL EVLFMTEPID EYVMQQVKDF EDKKFACLTK EQNSIYYITG DSKKKLESSP FIEQAKRRGF EVLFMTEPYD EYVMQQVKDF EDKKFACLTK GQKCIYYVTG DSKKKLETSP FIEQARRRGM EVLFMTDPID EYVMQQVKDF EDKKFACLTK GQKCIYYVTG DSKKKLETSP FIEQARRRGF EVLFMTEPID EYVMQQVKDF EDKKFACLTK NQTQIYYITG ESKDVVAASA FVERVKSRGF EVLYMCDPID EYCVQQLKEY DGKKLVSVTK NQKQIYFITG ESREAVASSA FVERVKRRGF EVIYMTDPID EYCVQQLKEY DGKKLVSVTK NQKSIYYITG ESKDQVAHSA FVERVCKRGF EVLYMTEPID EYCVQQLKDF DGKSLVSVTK NQKHIYFITG ETKDQVANSA FVERLRKHGL EVIYMIEPID EYCVQQLKEF EGKTLVSVTK NQTQIYFITG ESIEQVKNSA FVERVKKRGF EVIYMTEAID EYVIQQLKEY KGKQLVCVTK NQKHVYFITG ESKDQVSNSA FVERVKARGF EVVYMTEPID EYVIQHLKEY KGKQLVSVTK NQKSIYYITG ESKDQVANSA FVERVRKRGF EVLYMTEPID EYCVQQLKEF DGKTLVSVTK TQKSIYYITG ESKEQVANSA FVERVRKRGF EVVYMTEPID EYCVQQLKEF DGKSLVSVTK NQKHIYFITG ETKDQVANSA FVERLRKHGL EVIYMIEPID EYCVQQLKEF EGKTLVSVTK TQKSIYYITG ESKEQVANSA FVERVRKRGF EVVYMTEPID EYCVQQLKEF DGKSLVSVTK HQKNIYYITG ESIKAVSKSP FLDALKEKGF EVLFLVDPID EYAMTQLKEF EGKKLVDITK HQKNIYYITG ESIKAVEKSP FLDALKAKNF EVLFMVDPID EYAMTQLKEF EDKKLVDITK HQKNIYYITG ESIKAVEKSP FLDALKAKNF EVLFMVDPID EYAMTQLKEF EDKKLVDITK HQKNIYFITG ESKQAVENSP FLEIFRAKKF DVLFMVDPID EYAVTQLKEF EGKKLVNITK HQKNIYYITG ESLKAVEKSP FLDALKAKNF EVLFLTDPID EYAFTQLKEF EGKTLVDITK EQKYIYYITG ESKQSVANSP FLECLRSRGI EVIYMTDPID EYAVQQIKEF EGKKLKCCTK NQKDIYYITG ESINAVSNSP FLEALTKKGF EVIYMVDPID EYAVQQLKDF DGKKLKCCTK GQKDIFFITG ESRAAVAASP FVESLRKRGY EVLYMVDPID EYVIQQLKEY DGKKLKNCSK GQKDIYYITG ESRQTVANSP FLEKLTKKGY EVLYMTDPID EYAVQQLKEF DNHKLRCCTK DQKYVYYITG ESKQSVASSP FLETLRSRDY EVLYMTDPID EYAVQQIKEF EGKKLKCCTK DFELEETEEE KKDREAEEKE YEGLAKSLEN ILGDKVEKVV VSHKLIGSPC AIRTGQFGWS DFELEETEEE KKQREAEEKE YDGLAKALKN VLGDKVEKVV VSHKLVGAPC AIRTGQFGWS ELKLDETEDE KKKAEQDKAA NEELLKQVKD VLGDKVEKVV LSTRLANSPC VLVTSEYGWS ELKLDDSEEE KKRKEELKEK FEGLCKVIKE VLGDRVEKVI VSDRVVDSPC CLVTGEYGWT ELKLDDEDDE EKKREERKKR FEELCKVIKD ILGDRVEKVV VSDRIVDSPC CLVTGEYGWT ELKLDESEDE KKKQEELKEK FEGLCKVMKD VLGDKVEKVI VSDRVVDSPC CLVTGEYGWT EMQLEESEEE KAAREAEAKA CETLCEVIKE NLGEKVEKVV VSDRLADSPC ILVTGEYGWS ELDLGDSEND KKVKENEKEQ FDELCKVIKE TLNDKVEKVV ISDRLSDSPC ILVTGEYGWS ELKLDESEDE KKRKEELKEK FEGLCKVIKE VLGDKVEKVV VSDRVVDSPC CLVTGEYGWT ELKLDETEDE KKKKEELNEK FEGLCKVIKD VLGDKVEKVI VSDRVLDSPC CLVTGEYGWT ELKLDETEDE KKKKEELKEK FEGLCKVIKD VLGDKVEKVI VSDRVVDSPC CLVTGEYGWT ELKLEETDDE KKKKEELKEK FEGLCKVIKD VLGDKVEKVI VSDRVVDSPC CLVTGEYGWT ELKLEDDDEE EKKKREEKKS FENLCKIIKD ILGDKVEKVV VSDRIVDSPC CLVTGEYGWT EVHFEESEEE KQQREEEKAA CEKLCKTMKE VLGDKVEKVI VSECLSTSPC ILVTSEFGWS EVHFEESEEE KRQREEEKAT CEKLCKTMKE VLGDKVEKVT VSERLSTSPC ILVTSEFGWS EVHFEETEEE KKQREEEKAS YERLCKAMKE VLGDKVEKVV VSDRLATSPC ILVTSEFGWS EVHFEETEEE KKQREEEKTA YERLCKAMKD VLGDKVEKVV VSERLATSPC ILVTSEFGWS ELELPETEEE KKKFEEDKVA YENLCKVIKD ILEKKVEKVG VSNRLVSSPC CIVTSEYGWS ELELPESEEE KKKFEEDKVK FENLCKVMKD ILEKKVEKVA VSNRLVSSPC CIVTSEYGWS ELELPEDEDE KKKMEEDKAK FENLCKLMKE ILDKKVEKVT VSNRLVSSPC CIVTSTYGWT ELELPEDEEE KKKQEEKKTK FENLCKIMKD ILEKKVEKVV VSNRLVTSPC CIVTSTYGWT ELELPEDEAE KKKREEDKAK FENLCKVMKS VLESKVEKVV VSNRLVDSPC CIVTSQYGWS ELELPEDESE KKKREEDKAK FESLCKLMKS ILDNKVEKVV VSNRLVDSPC CIVTSQFGWS ELELPEDEEE KKKMDEDKTK FENLCKLMKE ILDKKVEKVT VSNRLVSSPC CIVTSTYGWT ELELPEDEEE KKKMEESKAR FENLCKLMKE ILDKKVEKVT ISNRLVSSPC CIVTSTYGWT ELELPEDEEE KKKQEEKKTK FENLCKIMKD ILEKKVEKVV VSNRLVTSPC CIVTSTYGWT ELELPEDEEE KKKMEESKAK FENLCKLMKE ILDKKVEKVT ISNRLVSSPC CIVTSTYGWT DFELEETEEE KKQREQEEKE YEDLCKALKN ILGDKVEKVV VSHKLVGSPC AIRTGQFGWS DFDLEETEEE KSTREKEIKE FEPLTKALKD ILGDQVEKVV VSYKLVDAPA AIRTGQFGWS DFELEESDEE KAAREKEIKE YEPLTKALKD ILGDQVEKVV VSYKLVDAPA AIRTGQFGWS DLELEETDEE KAAREKLEKE YEEFAKQLKT ILGDKVEKVV VSNKIVGSPC LLTTGQYGWS DFELEETDEE KAEREKEIKE YEPLTKALKE ILGDQVEKVV VSYKLLDAPA AIRTGQFGWS ELELEDTEEE RKNFETLEKE MEPLCRLIKE ILHDKVEKVV CGKRFTESPC ALVTSEFGWS ELDIDDSEEA KKDFETLKAE YEGLCKVIKD VLHEKVEKVV VGQRITDSPC VLVTSEFGWS ELELEQTEDE KKKFEEKKAA YEPLCKQIKE VLGDKVEKVV VGQRLDESPC VLVTGEYGWS ELEIDESEEE KKKFEELKAE FEPLLKLIKE VLHDKVDKVV LSNRITDSPC VLVTTEFGWS ELDLDEGEDE KKSFEALKEE MEPLCKHIKE VLHDKVEKVV CGTRFTDSPC ALVTSEFGWS ANMERIMKAQ ALRDTSMSSR RSSRPTENRT VKSITQLLFE TSLLSGFTIE EPSFAGRIHK ANMERIMKAQ ALRDTSMSSY MSSKPKENKT VKSIVQLLFE TSLLSGFTIE EPAFAERIHK ANMERIMKAQ ALRDSSMSSY MSSKPRDSKT FKDFVYLLYE TALLSGFSLD EPSFASRIHR ANMERIMKAQ ALRDTSMGGY MSSKAEENKS VKDLVMLLFE NSLLSGFSLD DPNFGTRIHR ANMERIMKAQ ALRDSSMSAY MSSKGEENKS VKDLVLLLFE TALLSGFSLD DPNFAARIHR ANMERIMKAQ ALRDSSMAGY MSSKSDENKS VKDLVLLLFE TALLSGFSLE EPNFGNRIHR ANMERIMSSQ ALRDNSLSTY MSSRSRETKT VKDLVSLLFD TAMLSGFSLE EPHFAGRIQR ANMERIMKAQ ALRDSSLSTY MSSRSNENKT VKDLVNLLFD TSLLSGFSLD EPHFAERIHR ANMERIMKAQ ALRDSSMAGY MSSKAEENKS VKDLVLLLFE TALLSGFSLD DPNFGSRIHR ANMERIMKAQ ALRDSSMGGY MSSKLDENKS VKDLVLLLFE TALLSGFSLD EPNFGSRIHR ANMERIMKAQ ALRDSSMAGY MSSKSDENKS VKDLVLLLFE TALLSGFSLD EPNFGSRIHR ANMERIMKAQ ALKDSNTGGY MSSKSDENKS VKDLVLLLFE TALLSGFSLD EPNFGSRIHR ANMERIMKAQ ALRDSSMSSY MSSKGEENKS VKDLVLLLFE TALLSGFSLD DPNFGARIHR AHMEQIMRNQ ALRDSSMAQY MMSKPKENKA VKDLVFLLFD TSLLSGFQLE DPTYAERINR AHMEQMMRNQ ALRDSSMAQY MMSKPKENKA VKDLVFLLFD TSLLSGFQLE DPTYAERINR AHMEQIMRNQ ALRDSSMSAY MMRKAKENKA AKDLIFLLFD TSLLSGFTLD DPTYADRIHR AHMEQIMRNQ ALRDSSMSAY MMSKPKENKA VKDLVYLLFD TALLSGFTLD DPTYAERIHR ANMERIMKAQ ALRDSSTMGY MAAKAKTNKT VKDLVVLLFE TALLSGFSLE EPQHASRIYR ANMERIMKAQ ALRDSSTMGY MAAKSKANKT VKDLVVLLFE TALLSGFSLE DPQHASRIYR ANMERIMKAQ ALRDNSTMGY MMANPETNKA VKDLVILLFE TALLSGFSLD DPQHSNRIYR ANMERIIKAQ ALRDNSTMGY MAAKSETNKS VKDLVILLYE TALLSGFSLE DPQHANRIYR ANMERIMKAQ ALRDSSAMGY MAGKAETNKA VKDLVILLFE TALLSGFSLD EPGHAARIYR ANMERIMKAQ ALRDTATMGY MAGKPETNKA VKDLVILLFE TSLLSGFSLD SPQHASRIYR ANMERIMKAQ ALRDNSTMGY MMAKPETNKA VKDLVILLFE TALLSGFSLD DPQHSNRIYR ANMERIMKAQ ALRDNSTMGY MMAKPETNKA VKDLVVLLFE TALSLASHFR RPKHSNRIYR ANMERIMKAQ ALRDNSTMGY MAAKSETNKS VKDLVILLYE TALLSGFSLE DPQHANRIYR ANMERIMKAQ ALRDNSTMGY MMAKPETNKA VKDLVVLLFE TALLSGFSLE DPQHSNRIYR ANMERIMKAQ ALRDTSMSSY MSSKPKENKT VKSIVQLLYE TSLLSGFTID EPALPRGIHK ANMERIMKAQ ALRDTTMSSY TSSKPKEEKT VKDLTTLLFD TALLSGFTLD EPSFAHRINR ANMERIMKAQ ALRDTTMSSY MSSKPKEEKT VKDLTTLLFD TALLSGFTLD EPSFAHRINR ANMERIMKAQ ALRDTSMSAY MSSRPAEERS VKDLATILYE TALLSGFTLD DPSYAQRINR ANMERIMKAQ ALRDSSMSSY MSSKPKEQKT VKDLTKLLYE TALLSGFSLD EPTFASRINR ANMERIMKAQ ALRDSSFGSF MISKSKESKT LKDLVWLLYD TAMLSGFNLD DPTFGGRIYR ANMERIMKAQ ALRDNSMTSY MLSKPSASKT VKDLIWLLFD TSLLSGFALE EPTFSKRIHR ANMERIMKAQ ALRDASMSTY MISKAQEAKT VKDLIWLLFE TSLLSGFSLD DPSFANRIHR ANMERIMKAQ ALRDNSMTSY MVSKSIESKT VKDLIWLLYD TALLSGFSLE EPTFAARIHR ANMERIMKAQ ALRDSSITSY MLSKSKETKT VKDLVWLLYD TALLSGFNLD EPTFGNRIYR LVSLGLN LVALGLN MIKLGLS MLKLGLS MLKLGLN MLKLGLS MLMLGLQ MIKLGLS MLKLGLS MLKLGLS MLKLGLS MLKLGLS MLKLGLS MIKLGLS MIKLGLS MIKLGLS MIKLGLS MIKLGLD MIKLGLD MIKLGLG MIKLGLG MVKLGLG MIKLGLG MIKLGLG MIKLGLG MIKLGLG MIKLGLG LVSLGQN LIALGLN LIALGLN LISLGLS LISLGLN MIKLGLS MIKLGLS MIKLGLQ MIKLGLS MIKLGLS phyml-3.2.0/src/000077500000000000000000000000001263450375500134465ustar00rootroot00000000000000phyml-3.2.0/src/Makefile.am000066400000000000000000000223011263450375500155000ustar00rootroot00000000000000# EXTRA_DIST = doc bin examples DEFS = $(REVISION) if WANT_PHYTIME bin_PROGRAMS = phytime PROG = PHYTIME else if WANT_PHYCONT bin_PROGRAMS = phycont PROG = PHYCONT else if WANT_PART bin_PROGRAMS = part PROG = PART else if WANT_RWRAP PROG = RWRAP else if WANT_TIPORDER bin_PROGRAMS = tiporder PROG = TIPORDER else if WANT_M4 bin_PROGRAMS = m4 PROG = M4 else if WANT_RF bin_PROGRAMS = rf PROG = RF else if WANT_MPI bin_PROGRAMS = phyml-mpi PROG = PHYML else if WANT_TEST bin_PROGRAMS = test PROG = TEST else if WANT_INVITEE bin_PROGRAMS = invitee PROG = INVITEE else if WANT_GEO bin_PROGRAMS = phylogeo PROG = GEO else if WANT_EVOLVE bin_PROGRAMS = evolve PROG = EVOLVE else if WANT_CHECKPOINT bin_PROGRAMS = checkpoint PROG = CHECKPOINT else if WANT_BEAGLE bin_PROGRAMS = phyml-beagle PROG = PHYML else if WANT_PHYREX bin_PROGRAMS = phyrex PROG = PHYREX else bin_PROGRAMS = phyml PROG = PHYML endif endif endif endif endif endif endif endif endif endif endif endif endif endif endif if WANT_PHYTIME phytime_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ times.c times.h\ m4.c m4.h\ draw.c draw.h\ rates.c rates.h\ mcmc.c mcmc.h\ stats.c stats.h\ mg.c mg.h\ tiporder.c tiporder.h\ io.c io.h\ make.c make.h\ mixt.c mixt.h\ init.c init.h\ nexus.c nexus.h\ xml.c xml.h\ phyrex.c phyrex.h phytime_LDADD = -lm else if WANT_PHYCONT phycont_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ times.c times.h\ m4.c m4.h\ draw.c draw.h\ rates.c rates.h\ mcmc.c mcmc.h\ stats.c stats.h\ mg.c mg.h\ tiporder.c tiporder.h # continuous.c continuous.h phycont_LDADD = -lm else if WANT_RWRAP lib_LTLIBRARIES = librwrap.la librwrap_la_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ rwrapper.c rwrapper.h librwrap_la_LIBADD = -lm librwrap_la_LDFLAGS = -I/usr/share/R/include -shared -module -flat_namespace librwrap_la_CFLAGS=-std=gnu99 -fPIC -Wl,-z,defs else if WANT_PART part_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ mg.c mg.h\ spr.c spr.h\ m4.c m4.h\ draw.c draw.h\ stats.c stats.h\ tiporder.c tiporder.h part_LDADD = -lm else if WANT_TIPORDER tiporder_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ mg.c mg.h\ times.c times.h\ mcmc.c mcmc.h\ rates.c rates.h\ spr.c spr.h\ m4.c m4.h\ draw.c draw.h\ stats.c stats.h\ tiporder.c tiporder.h tiporder_LDADD = -lm else if WANT_M4 m4_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ mg.c mg.h\ times.c times.h\ mcmc.c mcmc.h\ rates.c rates.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ tiporder.c tiporder.h\ m4.c m4.h m4_LDADD = -lm else if WANT_RF rf_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ mg.c mg.h\ times.c times.h\ mcmc.c mcmc.h\ rates.c rates.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ tiporder.c tiporder.h\ m4.c m4.h rf_LDADD = -lm else if WANT_MPI phyml_mpi_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ mpi_boot.c mpi_boot.h phyml_mpi_LDADD = -lm else if WANT_TEST test_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h test_LDADD = -lm else if WANT_INVITEE invitee_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ invitee.c invitee.h\ mixt.c mixt.h invitee_LDADD = -lm else if WANT_EVOLVE evolve_SOURCES = main.c\ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h evolve_LDADD = -lm else if WANT_GEO phylogeo_SOURCES = main.c\ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ geo.c geo.h phylogeo_LDADD = -lm else if WANT_CHECKPOINT checkpoint_SOURCES = main.c\ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ checkpoint.c checkpoint.h checkpoint_LDADD = -lm else if WANT_PHYREX phyrex_SOURCES = main.c\ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ phyrex.c phyrex.h else if WANT_BEAGLE phyml_beagle_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h\ beagle_utils.c beagle_utils.h phyml_beagle_LDADD = -lm -lhmsbeagle else phyml_SOURCES = main.c \ utilities.c utilities.h\ optimiz.c optimiz.h\ lk.c lk.h\ bionj.c bionj.h\ models.c models.h\ free.c free.h\ help.c help.h\ simu.c simu.h\ eigen.c eigen.h\ pars.c pars.h\ alrt.c alrt.h\ interface.c interface.h\ cl.c cl.h\ spr.c spr.h\ draw.c draw.h\ stats.c stats.h\ rates.c rates.h\ mcmc.c mcmc.h\ times.c times.h\ tiporder.c tiporder.h\ mg.c mg.h\ m4.c m4.h\ io.c io.h\ make.c make.h\ nexus.c nexus.h\ init.c init.h\ xml.c xml.h\ mixt.c mixt.h phyml_LDADD = -lm endif endif endif endif endif endif endif endif endif endif endif endif endif endif endif all-am: intro $(bin_PROGRAMS) @echo "" @echo "Done." intro: @echo "" @echo "" @echo ".: Building [$(bin_PROGRAMS)]. Version $(VERSION) :." @echo "" @echo "" phyml-3.2.0/src/Makefile_mc.am000066400000000000000000000015671263450375500161720ustar00rootroot00000000000000# AM_CFLAGS=-mpowerpc # AM_CFLAGS=-O3 -fomit-frame-pointer -funroll-loops -Wall -m64 # AM_CFLAGS=-O2 -Wall # AM_CFLAGS=-m64 # AM_CFLAGS=-g -Wall # AM_LDFLAGS=-lm # DEFS = -DUNIX -D$(PROG) -DDEBUG -DBATCH -DQUIET # DEFS=-DUNIX -D$(PROG) -DDEBUG # DEFS=-DUNIX -D$(PROG) # DEFS = -DUNIX -D$(PROG) AM_MAKEFLAGS = -f Makefile_mc bin_PROGRAMS = mc PROG = MC DEFS=-DUNIX -D$(PROG) -DDEBUG mc_SOURCES = main.c utilities.c optimiz.c lk.c bionj.c models.c free.c\ help.c simu.c eigen.c pars.c alrt.c interface.c cl.c spr.c mc.c m4.c draw.c rates.c mcmc.c numeric.c # mc_LDADD = -lm # SCOMPILE = $(CC) $(SDEFS) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(SCFLAGS) # SCCLD = $(CC) $(LIBS) # SLINK = $(SCCLD) $(AM_CFLAGS) $(SLDFLAGS) $(LDFLAGS) $(INCLUDES) $(AM_LDFLAGS) all-am: intro mc$(EXEEXT) @echo "" @echo "Done." intro: @echo "" @echo "** Building MC version $(VERSION) **" @echo "" phyml-3.2.0/src/Makefile_r.am000066400000000000000000000035621263450375500160310ustar00rootroot00000000000000bin_PROGRAMS = rwrapper PROG = RWRAP rwrapper_SOURCES = main.c utilities.c optimiz.c lk.c bionj.c models.c free.c\ help.c simu.c eigen.c pars.c alrt.c interface.c cl.c spr.c draw.c rates.c rwrapper.c numeric.c mcmc.c rwrapper_LDADD = main.o utilities.o optimiz.o lk.o bionj.o models.o free.o\ options.o simu.o eigen.o pars.o alrt.o interface.o cl.o spr.o draw.o rates.o rwrapper.o numeric.o mcmc.o AM_CFLAGS=-fPIC -Wall AM_LDFLAGS=-lm DEFS=-DUNIX -D$(PROG) -DDEBUG # SCOMPILE = $(CC) $(SDEFS) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(SCFLAGS) SCOMPILE = $(CC) $(SDEFS) $(DEFS) $(INCLUDES) $(AM_CFLAGS) $(SCFLAGS) -I/Library/Frameworks/R.framework/Versions/2.8/Resources/include/ SCCLD = $(CC) $(LIBS) SLINK = $(SCCLD) $(AM_CFLAGS) $(SLDFLAGS) $(LDFLAGS) $(INCLUDES) $(AM_LDFLAGS) -bundle -flat_namespace -undefined suppress rwrapper$(EXEEXT): $(rwrapper_LDADD) $(rwrapper_SOURCES) $(SLINK) $(rwrapper_LDADD) -o $@.so main.o: main.c $(SCOMPILE) -c main.c utilities.o: utilities.c utilities.h $(SCOMPILE) -c utilities.c optimiz.o: optimiz.c optimiz.h $(SCOMPILE) -c optimiz.c lk.o: lk.c lk.h $(SCOMPILE) -c lk.c bionj.o: bionj.c bionj.h $(SCOMPILE) -c bionj.c models.o: models.c models.h $(SCOMPILE) -c models.c free.o: free.c free.h $(SCOMPILE) -c free.c options.o: help.c help.h $(SCOMPILE) -c help.c simu.o: simu.c simu.h $(SCOMPILE) -c simu.c eigen.o: eigen.c eigen.h $(SCOMPILE) -c eigen.c pars.o: pars.c pars.h $(SCOMPILE) -c pars.c alrt.o: alrt.c alrt.h $(SCOMPILE) -c alrt.c interface.o: interface.c interface.h $(SCOMPILE) -c interface.c cl.o: cl.c cl.h $(SCOMPILE) -c cl.c spr.o: spr.c spr.h $(SCOMPILE) -c spr.c mg.o: mg.c $(SCOMPILE) -c mg.c draw.o: draw.c $(SCOMPILE) -c draw.c rates.o: rates.c $(SCOMPILE) -c rates.c rwrapper.o: rwrapper.c $(SCOMPILE) -c rwrapper.c numeric.o: numeric.c $(SCOMPILE) -c numeric.c mcmc.o: mcmc.c $(SCOMPILE) -c mcmc.c phyml-3.2.0/src/alrt.c000066400000000000000000001115111263450375500145540ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Implementation of aLRT branch tests, and 5-branchs NNI research optimization. Authors : Jean-Francois Dufayard & Stephane Guindon. */ #include "alrt.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* * Check every testable branch of the tree, * check for NNIs, optimizing 5 branches, * param tree : the tree to check */ int Check_NNI_Five_Branches(t_tree *tree) { int best_edge; phydbl best_gain; int best_config; int i; int better_found; /* = 1 if a phylogeny with greater likelihood than current one was found */ int result; phydbl init_lnL; init_lnL = UNLIKELY; better_found = 1; //While there is at least one NNI to do... while(better_found) { Update_Dirs(tree); //Interface output if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Checking for NNIs, optimizing five branches...\n"); better_found = 0; result = -1; best_edge = -1; best_gain = tree->mod->s_opt->min_diff_lk_local; best_config = -1; MIXT_Set_Alias_Subpatt(YES,tree); Set_Both_Sides(YES,tree); init_lnL = Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); //For every branch For(i,2*tree->n_otu-3) { //if this branch is not terminal if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) { result = -1; //Try every NNIs for the tested branch result = NNI_Neigh_BL(tree->a_edges[i],tree); //Look for possible NNI to do, and check if it is the best one switch(result) { case 1 : /* lk1 > lk0 > lk2 */ { if((tree->a_edges[i]->nni->lk0 - tree->a_edges[i]->nni->lk1) < best_gain) { better_found = 1; best_edge = i; best_gain = tree->a_edges[i]->nni->lk0-tree->a_edges[i]->nni->lk1; best_config = 1; } break; } case 2 : /* lk2 > lk0 > lk1 */ { if((tree->a_edges[i]->nni->lk0 - tree->a_edges[i]->nni->lk2) < best_gain) { better_found = 1; best_edge = i; best_gain = tree->a_edges[i]->nni->lk0-tree->a_edges[i]->nni->lk2; best_config = 2; } break; } case 3 : /* lk1 > lk2 > lk0 */ { if((tree->a_edges[i]->nni->lk2 - tree->a_edges[i]->nni->lk1) < best_gain) { better_found = 1; best_edge = i; best_gain = tree->a_edges[i]->nni->lk2-tree->a_edges[i]->nni->lk1; best_config = 1; } break; } case 4 : /* lk2 > lk1 > lk0 */ { if((tree->a_edges[i]->nni->lk1 - tree->a_edges[i]->nni->lk2) < best_gain) { better_found = 1; best_edge = i; best_gain = tree->a_edges[i]->nni->lk1-tree->a_edges[i]->nni->lk2; best_config = 2; } break; } default : /* lk2 = lk1 = lk0 */ { if(best_gain > .0) best_gain = .0; break; } } } } if((tree->c_lnL < init_lnL - tree->mod->s_opt->min_diff_lk_local) || (tree->c_lnL > init_lnL + tree->mod->s_opt->min_diff_lk_local)) { PhyML_Printf("\n\n== tree->c_lnL = %f init_lnL = %f.",tree->c_lnL,init_lnL); PhyML_Printf("\n== Err. in file %s at line %d\n\n.\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } //Don't do any NNI if the user doesn't want to optimize topology if(!tree->mod->s_opt->opt_topo) better_found = 0; /* if(FABS(best_gain) <= tree->mod->s_opt->min_diff_lk_move) better_found = 0; */ //If there is one swap to do, make the best one. if(better_found) { Make_Target_Swap(tree,tree->a_edges[best_edge],best_config); MIXT_Set_Alias_Subpatt(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(YES,tree); if(tree->c_lnL < init_lnL) { PhyML_Printf("\n\n== tree->c_lnL = %f init_lnL = %f.",tree->c_lnL,init_lnL); PhyML_Printf("\n== Err. in file %s at line %d\n\n.\n",__FILE__,__LINE__); Exit("\n"); } if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology ]"); if(FABS(tree->c_lnL - init_lnL) < tree->mod->s_opt->min_diff_lk_move) return 0; return 1; } } return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Compute aLRT supports */ void aLRT(t_tree *tree) { int i; char *method; // Print_All_Edge_Likelihoods(tree); Unscale_Br_Len_Multiplier_Tree(tree); Br_Len_Not_Involving_Invar(tree); // Print_All_Edge_Likelihoods(tree); /* aLRT support will label each internal branch */ tree->print_alrt_val = YES; /* The topology will not be modified when assessing the branch support. We make sure that it will not be modified afterwards by locking the topology */ method = (char *)mCalloc(100,sizeof(char)); switch(tree->io->ratio_test) { case ALRTCHI2: { strcpy(method,"aLRT"); break; } case MINALRTCHI2SH: { strcpy(method,"aLRT"); break; } case ALRTSTAT: { strcpy(method,"aLRT"); break; } case SH: { strcpy(method,"SH"); break; } case ABAYES: { strcpy(method,"aBayes"); break; } default : return; } if(tree->io->quiet == NO) PhyML_Printf("\n\n. Calculating fast branch supports (using '%s').",method); Free(method); MIXT_Set_Alias_Subpatt(YES,tree); Set_Both_Sides(YES,tree); // Print_All_Edge_Likelihoods(tree); Lk(NULL,tree); // Print_All_Edge_Likelihoods(tree); MIXT_Set_Alias_Subpatt(NO,tree); For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) { /* Compute likelihoods for each of the three configuration */ NNI_Neigh_BL(tree->a_edges[i],tree); /* Compute the corresponding statistical support */ Compute_Likelihood_Ratio_Test(tree->a_edges[i],tree); } tree->lock_topo = YES; Br_Len_Involving_Invar(tree); Rescale_Br_Len_Multiplier_Tree(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* * Launch one branch testing, * analyse the result * and convert supports as wished by the user. * param tree : the tree to check * param tested_t_edge : the tested t_edge of the tree * param old_loglk : the initial likelihood, before any aLRT analysis * param isBoot : 1 if used from the Bootstrap procedure, 0 if not * return an integer, informative to analyse the results and potential NNIs to do */ int Compute_Likelihood_Ratio_Test(t_edge *tested_edge, t_tree *tree) { int result=0; tested_edge->ratio_test = 0.0; tested_edge->alrt_statistic = -1.0; if((tested_edge->nni->lk0 > tested_edge->nni->lk1) && (tested_edge->nni->lk0 > tested_edge->nni->lk2)) { if(tested_edge->nni->lk1 < tested_edge->nni->lk2) { //lk0 > lk2 > lk1 tested_edge->alrt_statistic = 2*(tested_edge->nni->lk0 - tested_edge->nni->lk2); } else { //lk0 > lk1 >= lk2 tested_edge->alrt_statistic = 2*(tested_edge->nni->lk0 - tested_edge->nni->lk1); } if (tested_edge->alrt_statistic < 0.0) { tested_edge->alrt_statistic = 0.0; tested_edge->ratio_test = 0.0; } else { //aLRT statistic is valid, compute the branch support if (tree->io->ratio_test == ALRTCHI2) { tested_edge->ratio_test = Statistics_To_Probabilities(tested_edge->alrt_statistic); } else if(tree->io->ratio_test == MINALRTCHI2SH) { phydbl sh_support; phydbl param_support; sh_support = Statistics_To_SH(tree); param_support = Statistics_To_Probabilities(tested_edge->alrt_statistic); if(sh_support < param_support) tested_edge->ratio_test = sh_support; else tested_edge->ratio_test = param_support; } else if(tree->io->ratio_test == ALRTSTAT) { tested_edge->ratio_test=tested_edge->alrt_statistic; } else if(tree->io->ratio_test == SH) { tested_edge->ratio_test = Statistics_To_SH(tree); } else if(tree->io->ratio_test == ABAYES) { phydbl Kp0,Kp1,Kp2,logK; logK = 1. - MAX(MAX(tested_edge->nni->lk0,tested_edge->nni->lk1),tested_edge->nni->lk2); Kp0 = EXP(tested_edge->nni->lk0+logK); Kp1 = EXP(tested_edge->nni->lk1+logK); Kp2 = EXP(tested_edge->nni->lk2+logK); tested_edge->ratio_test = Kp0/(Kp0+Kp1+Kp2); } } } //statistic is not valid, give the negative statistics if wished, or a zero support. else if((tested_edge->nni->lk1 > tested_edge->nni->lk0) && (tested_edge->nni->lk1 > tested_edge->nni->lk2)) { /* tested_edge->ratio_test = 2*(tested_edge->nni->lk0-tested_edge->nni->lk1); */ tested_edge->ratio_test = 0.0; if(tree->io->ratio_test > 1) tested_edge->alrt_statistic = 0.0; } else if((tested_edge->nni->lk2 > tested_edge->nni->lk0) && (tested_edge->nni->lk2 > tested_edge->nni->lk1)) { /* tested_edge->ratio_test = 2*(tested_edge->nni->lk0-tested_edge->nni->lk2); */ tested_edge->ratio_test = 0.0; if(tree->io->ratio_test > 1) tested_edge->alrt_statistic = 0.0; } else // lk0 ~ lk1 ~ lk2 { tested_edge->ratio_test = 0.0; if(tree->io->ratio_test > 1) tested_edge->ratio_test = 0.0; } return result; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* * Test the 3 NNI positions for one branch. * param tree : the tree to check * param tested_t_edge : the tested t_edge of the tree * param old_loglk : the initial likelihood, before any aLRT analysis * param isBoot : 1 if used from the Bootstrap procedure, 0 if not */ int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree) { /*! syntax : (node) [edge] (left_1) . .(right_1) \ (left) (right) / \._____________./ / [b_fcus] \ / \ (left_2) . .(right_2) */ int site; t_node *v1,*v2,*v3,*v4; t_edge *e1,*e2,*e3,*e4; phydbl *len_e1,*len_e2,*len_e3,*len_e4; phydbl lk0, lk1, lk2; phydbl *bl_init; phydbl l_infa, l_infb; phydbl lk_init, lk_temp; int i; int result,counter,wei; void *buff; result = 0; /*! Initialization */ bl_init = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree); lk_init = tree->c_lnL; lk_temp = UNLIKELY; b_fcus->nni->score = .0; lk0 = lk1 = lk2 = UNLIKELY; v1 = v2 = v3 = v4 = NULL; /*! vertices */ v1 = b_fcus->left->v[b_fcus->l_v1]; v2 = b_fcus->left->v[b_fcus->l_v2]; v3 = b_fcus->rght->v[b_fcus->r_v1]; v4 = b_fcus->rght->v[b_fcus->r_v2]; if(v1->num < v2->num) { PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Exit(""); } if(v3->num < v4->num) { PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Exit(""); } /*! edges */ e1 = b_fcus->left->b[b_fcus->l_v1]; e2 = b_fcus->left->b[b_fcus->l_v2]; e3 = b_fcus->rght->b[b_fcus->r_v1]; e4 = b_fcus->rght->b[b_fcus->r_v2]; /*! record initial branch lengths */ len_e1 = MIXT_Get_Lengths_Of_This_Edge(e1,tree); len_e2 = MIXT_Get_Lengths_Of_This_Edge(e2,tree); len_e3 = MIXT_Get_Lengths_Of_This_Edge(e3,tree); len_e4 = MIXT_Get_Lengths_Of_This_Edge(e4,tree); /*! Optimize branch lengths and update likelihoods for the original configuration. */ do { lk0 = lk_temp; For(i,3) //a branch has three nodes if(b_fcus->left->v[i] != b_fcus->rght)//Only consider left_1 and left_2 { Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left)//Only consider right_1 and right_2 { Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->rght); if(lk_temp < lk0 - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== lk_temp = %f lk0 = %f\n",lk_temp,lk0); PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Exit("\n"); } } while(FABS(lk_temp-lk0) > tree->mod->s_opt->min_diff_lk_global); //until no significative improvement is detected lk0 = tree->c_lnL; buff = (t_tree *)tree; do { counter=0; For(site,tree->n_pattern) { wei=0; For(wei,tree->data->wght[site]) { tree->log_lks_aLRT[0][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site]; counter++; } } tree = tree->next_mixt; } while(tree); tree = (t_tree *)buff; /*! Go back to initial branch lengths */ MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree); MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree); MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree); MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree); MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree); Update_PMat_At_Given_Edge(e1,tree); Update_PMat_At_Given_Edge(e2,tree); Update_PMat_At_Given_Edge(e3,tree); Update_PMat_At_Given_Edge(e4,tree); Update_PMat_At_Given_Edge(b_fcus,tree); /* Sanity check */ MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,b_fcus,b_fcus->rght); Update_P_Lk(tree,b_fcus,b_fcus->left); lk_temp = Lk(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); if((lk_temp > lk_init + tree->mod->s_opt->min_diff_lk_local) || (lk_temp < lk_init - tree->mod->s_opt->min_diff_lk_local)) { PhyML_Printf("\n== lk_temp = %f lk_init = %f",lk_temp,lk_init); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } /*! Do first possible swap */ Swap(v2,b_fcus->left,b_fcus->rght,v3,tree); MIXT_Set_Alias_Subpatt(YES,tree); Set_Both_Sides(YES,tree); Update_P_Lk(tree,b_fcus,b_fcus->left); Update_P_Lk(tree,b_fcus,b_fcus->rght); lk1 = Lk(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); /*! Optimize branch lengths and update likelihoods */ lk_temp = UNLIKELY; do { lk1 = lk_temp; For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) { Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) { Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->rght); if(lk_temp < lk1 - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== lk_temp = %f lk1 = %f\n",lk_temp,lk1); PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } while(FABS(lk_temp-lk1) > tree->mod->s_opt->min_diff_lk_global); /*! until no significative improvement is detected */ lk1 = tree->c_lnL; /*! record likelihood of each site, in order to compute branch supports */ buff = (t_tree *)tree; do { counter=0; For(site,tree->n_pattern) { wei=0; For(wei,tree->data->wght[site]) { tree->log_lks_aLRT[1][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site]; counter++; } } tree = tree->next_mixt; } while(tree); tree = (t_tree *)buff; Swap(v3,b_fcus->left,b_fcus->rght,v2,tree); /*! Go back to initial branch lengths */ MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree); MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree); MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree); MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree); MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree); Update_PMat_At_Given_Edge(e1,tree); Update_PMat_At_Given_Edge(e2,tree); Update_PMat_At_Given_Edge(e3,tree); Update_PMat_At_Given_Edge(e4,tree); Update_PMat_At_Given_Edge(b_fcus,tree); /* Sanity check */ MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,b_fcus,b_fcus->rght); Update_P_Lk(tree,b_fcus,b_fcus->left); lk_temp = Lk(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); if((lk_temp > lk_init + tree->mod->s_opt->min_diff_lk_local) || (lk_temp < lk_init - tree->mod->s_opt->min_diff_lk_local)) { PhyML_Printf("\n== lk_temp = %f lk_init = %f",lk_temp,lk_init); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } /*! do the second possible swap */ Swap(v2,b_fcus->left,b_fcus->rght,v4,tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,b_fcus,b_fcus->left); Update_P_Lk(tree,b_fcus,b_fcus->rght); lk2 = Lk(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); /*! Optimize branch lengths and update likelihoods */ lk_temp = UNLIKELY; do { lk2 = lk_temp; For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) { Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->left->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree); if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->left->b[i]->l->v,b_fcus->left->b[i]->l_var->v); PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2); PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__); Exit("\n"); } } Update_P_Lk(tree,b_fcus,b_fcus->left); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->l->v,b_fcus->l_var->v); PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2); PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__); Exit("\n"); } For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) { Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); l_infa = 10.; l_infb = MAX(0.0,tree->mod->l_min/b_fcus->rght->b[i]->l->v); lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree); if(lk_temp < lk2 - tree->mod->s_opt->min_diff_lk_local) { Set_Both_Sides(YES,tree); Lk(b_fcus,tree); Check_Lk_At_Given_Edge(YES,tree); PhyML_Printf("\n== l_infa: %f l_infb: %f l: %f var:%f",l_infa,l_infb,b_fcus->rght->b[i]->l->v,b_fcus->rght->b[i]->l_var->v); PhyML_Printf("\n== lk_temp = %f lk2 = %f",lk_temp,lk2); PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__); Exit("\n"); } } Update_P_Lk(tree,b_fcus,b_fcus->rght); } while(FABS(lk_temp-lk2) > tree->mod->s_opt->min_diff_lk_global); //until no significative improvement is detected lk2 = tree->c_lnL; /*! save likelihood of each sites, in order to compute branch supports */ buff = (t_tree *)tree; do { counter=0; For(site,tree->n_pattern) { wei=0; For(wei,tree->data->wght[site]) { tree->log_lks_aLRT[2][counter]= tree->c_lnL_sorted[site] / tree->data->wght[site]; counter++; } } tree = tree->next_mixt; } while(tree); tree = (t_tree *)buff; /*! undo the swap */ Swap(v4,b_fcus->left,b_fcus->rght,v2,tree); /***********/ /*! restore the initial branch length values */ MIXT_Set_Lengths_Of_This_Edge(len_e1,e1,tree); MIXT_Set_Lengths_Of_This_Edge(len_e2,e2,tree); MIXT_Set_Lengths_Of_This_Edge(len_e3,e3,tree); MIXT_Set_Lengths_Of_This_Edge(len_e4,e4,tree); MIXT_Set_Lengths_Of_This_Edge(bl_init,b_fcus,tree); /*! recompute likelihoods */ Update_PMat_At_Given_Edge(e1,tree); Update_PMat_At_Given_Edge(e2,tree); Update_PMat_At_Given_Edge(e3,tree); Update_PMat_At_Given_Edge(e4,tree); Update_PMat_At_Given_Edge(b_fcus,tree); MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,b_fcus,b_fcus->left); Update_P_Lk(tree,b_fcus,b_fcus->rght); For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); MIXT_Set_Alias_Subpatt(NO,tree); lk_temp = Lk(b_fcus,tree); if((lk_temp > lk_init + tree->mod->s_opt->min_diff_lk_local) || (lk_temp < lk_init - tree->mod->s_opt->min_diff_lk_local)) { PhyML_Printf("\n== lk_temp = %f lk_init = %f",lk_temp,lk_init); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } //save likelihoods in NNI structures b_fcus->nni->lk0 = lk0; b_fcus->nni->lk1 = lk1; b_fcus->nni->lk2 = lk2; b_fcus->nni->score = lk0 - MAX(lk1,lk2); if((b_fcus->nni->score < tree->mod->s_opt->min_diff_lk_local) && (b_fcus->nni->score > -tree->mod->s_opt->min_diff_lk_local)) { b_fcus->nni->score = .0; b_fcus->nni->lk1 = b_fcus->nni->lk2 = b_fcus->nni->lk0; } if((b_fcus->nni->lk1 > b_fcus->nni->lk0) && (b_fcus->nni->lk1 > b_fcus->nni->lk2)) { if(b_fcus->nni->lk0 > b_fcus->nni->lk2) result = 1; //lk1 > lk0 > lk2 else result = 3; //lk1 > lk2 > lk0 } else if((b_fcus->nni->lk2 > b_fcus->nni->lk0) && (b_fcus->nni->lk2 > b_fcus->nni->lk1)) { if(b_fcus->nni->lk0 > b_fcus->nni->lk1) result = 2; //lk2 > lk0 > lk1 else result = 4; //lk2 > lk1 > lk0 } Free(len_e1); Free(len_e2); Free(len_e3); Free(len_e4); Free(bl_init); return result; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* * Make one target swap, optimizing five branches. * param tree : the tree to check * param tested_t_edge : the swaping t_edge of the tree * param swapToDo : 1 or 2, to select the first or the second swap to do */ void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo) { t_node *v1,*v2,*v3,*v4; phydbl lktodo; phydbl l_infa, l_infb; phydbl lk_init, lk_temp; int i; if(swaptodo < 0) { PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } //Initialization lk_init = tree->c_lnL; b_fcus->nni->score = .0; lktodo = UNLIKELY; v1 = v2 = v3 = v4 = NULL; v1 = b_fcus->left->v[b_fcus->l_v1]; v2 = b_fcus->left->v[b_fcus->l_v2]; v3 = b_fcus->rght->v[b_fcus->r_v1]; v4 = b_fcus->rght->v[b_fcus->r_v2]; if(v1->num < v2->num) { PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(v3->num < v4->num) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } /***********/ //make the selected swap if(swaptodo==1) { Swap(v2,b_fcus->left,b_fcus->rght,v3,tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) Swap(v3,b_fcus->left,b_fcus->rght,v2,tree); } else { Swap(v2,b_fcus->left,b_fcus->rght,v4,tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) Swap(v4,b_fcus->left,b_fcus->rght,v2,tree); } MIXT_Set_Alias_Subpatt(YES,tree); Set_Both_Sides(YES,tree); lktodo = Update_Lk_At_Given_Edge(b_fcus,tree); For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); MIXT_Set_Alias_Subpatt(NO,tree); //Optimize branch lengths and update likelihoods lk_temp = UNLIKELY; do { lktodo = lk_temp; For(i,3) if(b_fcus->left->v[i] != b_fcus->rght) { Update_P_Lk(tree,b_fcus->left->b[i],b_fcus->left); l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->left->b[i]->l->v; lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->left->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->left); l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->l->v; lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); For(i,3) if(b_fcus->rght->v[i] != b_fcus->left) { Update_P_Lk(tree,b_fcus->rght->b[i],b_fcus->rght); l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->rght->b[i]->l->v; lk_temp = Br_Len_Brent(l_infb,l_infa,b_fcus->rght->b[i],tree); } Update_P_Lk(tree,b_fcus,b_fcus->rght); if(lk_temp < lktodo - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n. Edge %3d lk_temp = %f lktodo = %f\n",b_fcus->num,lk_temp,lktodo); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } while(FABS(lk_temp-lktodo) > tree->mod->s_opt->min_diff_lk_global); //until no significative improvement is detected /* PhyML_Printf("\n.<< [%3d] l=%f lk_init=%f tree->c_lnL=%f score=%12f v1=%3d v2=%3d v3=%3d v4=%3d >>", */ /* b_fcus->num, */ /* b_fcus->l->v, */ /* lk_init, */ /* tree->c_lnL, */ /* lk_init-tree->c_lnL, */ /* v1->num,v2->num,v3->num,v4->num); */ if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n. [%3d] v1=%d v2=%d v3=%d v4=%d", b_fcus->num,v1->num,v2->num,v3->num,v4->num); PhyML_Printf("\n. tree->c_lnL = %f lk_init = %f\n",tree->c_lnL,lk_init); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /** * Convert an aLRT statistic to a non-parametric support * param in: the statistic */ phydbl Statistics_To_Probabilities(phydbl in) { phydbl rough_value=0.0; phydbl a=0.0; phydbl b=0.0; phydbl fa=0.0; phydbl fb=0.0; if(in>=0.000000393 && in<0.00000157) { a=0.000000393; b=0.00000157; fa=0.0005; fb=0.001; } else if(in>=0.00000157 && in<0.0000393) { a=0.00000157; b=0.0000393; fa=0.001; fb=0.005; } else if(in>=0.0000393 && in<0.000157) { a=0.0000393; b=0.000157; fa=0.005; fb=0.01; } else if(in>=0.000157 && in<0.000982) { a=0.000157; b=0.000982; fa=0.01; fb=0.025; } else if(in>0.000982 && in<0.00393) { a=0.000982; b=0.00393; fa=0.025; fb=0.05; } else if(in>=0.00393 && in<0.0158) { a=0.00393; b=0.0158; fa=0.05; fb=0.1; } else if(in>=0.0158 && in<0.0642) { a=0.0158; b=0.0642; fa=0.1; fb=0.2; } else if(in>=0.0642 && in<0.148) { a=0.0642; b=0.148; fa=0.2; fb=0.3; } else if(in>=0.148 && in<0.275) { a=0.148; b=0.275; fa=0.3; fb=0.4; } else if(in>=0.275 && in<0.455) { a=0.275; b=0.455; fa=0.4; fb=0.5; } else if(in>=0.455 && in<0.708) { a=0.455; b=0.708; fa=0.5; fb=0.6; } else if(in>=0.708 && in<1.074) { a=0.708; b=1.074; fa=0.6; fb=0.7; } else if(in>=1.074 && in<1.642) { a=1.074; b=1.642; fa=0.7; fb=0.8; } else if(in>=1.642 && in<2.706) { a=1.642; b=2.706; fa=0.8; fb=0.9; } else if(in>=2.706 && in<3.841) { a=2.706; b=3.841; fa=0.9; fb=0.95; } else if(in>=3.841 && in<5.024) { a=3.841; b=5.024; fa=0.95; fb=0.975; } else if(in>=5.024 && in<6.635) { a=5.024; b=6.635; fa=0.975; fb=0.99; } else if(in>=6.635 && in<7.879) { a=6.635; b=7.879; fa=0.99; fb=0.995; } else if(in>=7.879 && in<10.828) { a=7.879; b=10.828; fa=0.995; fb=0.999; } else if(in>=10.828 && in<12.116) { a=10.828; b=12.116; fa=0.999; fb=0.9995; } if (in>=12.116) { rough_value=0.9999; } else if(in<0.000000393) { rough_value=0.0001; } else { rough_value=(b-in)/(b-a)*fa + (in - a)/(b-a)*fb; } rough_value=rough_value+(1.0-rough_value)/2.0; rough_value=rough_value*rough_value*rough_value; return rough_value; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /** * deprecated * Compute a RELL support, using the latest tested branch * param tree: the tested tree */ phydbl Statistics_to_RELL(t_tree *tree) { int i; int occurence=1000; phydbl nb=0.0; phydbl res; int site; phydbl lk0=0.0; phydbl lk1=0.0; phydbl lk2=0.0; phydbl buff = -1.; int position = -1; t_tree *buff_tree; /*! 1000 times */ For(i,occurence) { lk0=0.0; lk1=0.0; lk2=0.0; /*! Shuffle the data and increment the support, if needed */ buff_tree = tree; do { For(site, tree->data->init_len) { buff = rand(); buff /= (RAND_MAX+1.); buff *= tree->data->init_len; position = (int)FLOOR(buff); lk0+=tree->log_lks_aLRT[0][position]; lk1+=tree->log_lks_aLRT[1][position]; lk2+=tree->log_lks_aLRT[2][position]; } if (lk0>=lk1 && lk0>=lk2) nb++; tree = tree->next_mixt; } while(tree); tree = buff_tree; } res= nb/(phydbl)occurence; return res; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Compute a SH-like support, using the latest tested branch param tree: the tested tree */ phydbl Statistics_To_SH(t_tree *tree) { int i; int occurence=1000; phydbl nb=0.0; phydbl res; int site; phydbl lk0=0.0; phydbl lk1=0.0; phydbl lk2=0.0; phydbl c0=0.0; phydbl c1=0.0; phydbl c2=0.0; phydbl buff=-1.; int position=-1; phydbl delta_local=-1.; phydbl delta=0.0; t_tree *buff_tree; /*! Compute the total log-lk of each NNI position */ buff_tree = tree; do { For(site, tree->data->init_len) { c0+=tree->log_lks_aLRT[0][site]; c1+=tree->log_lks_aLRT[1][site]; c2+=tree->log_lks_aLRT[2][site]; } tree = tree->next_mixt; } while(tree); tree = buff_tree; if (c0>=c1 && c0>=c2) { if (c1>=c2) { delta=c0-c1; } else { delta=c0-c2; } } else if(c1>=c0 && c1>=c2) { if (c0>=c2) { delta=c1-c0; } else { delta=c1-c2; } } else { if (c1>=c0) { delta=c2-c1; } else { delta=c2-c0; } } /*! 1000 times */ For(i,occurence) { lk0=0.0; lk1=0.0; lk2=0.0; buff_tree = tree; do { /*! Shuffle the data */ For(site, tree->data->init_len) { buff = rand(); buff /= (RAND_MAX+1.); buff *= tree->data->init_len; position = (int)FLOOR(buff); lk0+=tree->log_lks_aLRT[0][position]; lk1+=tree->log_lks_aLRT[1][position]; lk2+=tree->log_lks_aLRT[2][position]; } tree = tree->next_mixt; } while(tree); tree = buff_tree; /*! return to null hypothesis */ lk0=lk0-c0; lk1=lk1-c1; lk2=lk2-c2; /*! compute results and increment if needed */ delta_local=0.0; if (lk0>=lk1 && lk0>=lk2) { if (lk1>=lk2) { delta_local=lk0-lk1; } else { delta_local=lk0-lk2; } } else if(lk1>=lk0 && lk1>=lk2) { if (lk0>=lk2) { delta_local=lk1-lk0; } else { delta_local=lk1-lk2; } } else { if (lk1>=lk0) { delta_local=lk2-lk1; } else { delta_local=lk2-lk0; } } if (delta>(delta_local+0.1)) { nb++; } } res= nb/occurence; return res; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /** * deprecated * Compute one side likelihood * param b_fcus : concerned edge * param tree : b_fcus tree * param exclude : side to exclude for computation */ phydbl Update_Lk_At_Given_Edge_Excluding(t_edge *b_fcus, t_tree *tree, t_node *exclude) { if((!b_fcus->left->tax) && (exclude == NULL || exclude != b_fcus->left)) Update_P_Lk(tree,b_fcus,b_fcus->left); if((!b_fcus->rght->tax) && (exclude == NULL || exclude != b_fcus->rght)) Update_P_Lk(tree,b_fcus,b_fcus->rght); tree->c_lnL = Lk(b_fcus,tree); return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/alrt.h000066400000000000000000000016631263450375500145670ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef ALRT_H #define ALRT_H #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "models.h" #include "free.h" #include "simu.h" void aLRT(t_tree *tree); int Check_NNI_Five_Branches(t_tree *tree); int Compute_Likelihood_Ratio_Test(t_edge *tested_edge, t_tree *tree); int NNI_Neigh_BL(t_edge *b_fcus, t_tree *tree); void Make_Target_Swap(t_tree *tree, t_edge *b_fcus, int swaptodo); phydbl Statistics_To_Probabilities(phydbl in); phydbl Statistics_To_RELL(t_tree *tree); phydbl Statistics_To_SH(t_tree *tree); phydbl Update_Lk_At_Given_Edge_Excluding(t_edge *b_fcus, t_tree *tree, t_node *exclude); #endif phyml-3.2.0/src/beagle_utils.c000066400000000000000000000416211263450375500162550ustar00rootroot00000000000000/* * author: Imran Fanaswala */ #ifndef BEAGLE_UTILS_CPP #define BEAGLE_UTILS_CPP #include #include "beagle_utils.h" #define CLEAN_BEAGLE_API /* Attempting to remove unnecessary communication with BEAGLE device */ double* int_to_double(const int* src, int num_elems) { double* dest = (double*)malloc(num_elems*sizeof(double)); if (NULL==dest) Warn_And_Exit("\n. Couldn't allocate memory.\n"); int i; for(i=0; ilength; i++) { fprintf(stdout, "\t\tResource %i:\n\t\tName : %s\n", i, rList->list[i].name); fprintf(stdout, "\t\t\tDesc : %s\n", rList->list[i].description); fprintf(stdout, "\t\t\tFlags:"); print_beagle_flags(rList->list[i].supportFlags); fprintf(stdout, "\n"); } fflush(stdout); } void print_beagle_instance_details(BeagleInstanceDetails *inst) { int rNumber = inst->resourceNumber; fprintf(stdout, "\tUsing resource %i:\n", rNumber); fprintf(stdout, "\t\tRsrc Name : %s\n", inst->resourceName); fprintf(stdout, "\t\tImpl Name : %s\n", inst->implName); fprintf(stdout, "\t\tImpl Desc : %s\n", inst->implDescription); fprintf(stdout, "\t\tFlags:"); fflush(stdout); print_beagle_flags(inst->flags); fflush(stdout); } int create_beagle_instance(t_tree *tree, int quiet, option* io) { if(UNINITIALIZED != tree->b_inst){ // fprintf(stdout,"\n\tWARNING: Creating a BEAGLE instance on a tree with an existing BEAGLE instance:%d\n",tree->b_inst); } if(!quiet){ // print_beagle_resource_list(); } int i; BeagleInstanceDetails inst_d; int num_rate_catg = tree->mod->ras->n_catg; int num_branches = 2*tree->n_otu-1; //rooted tree //Recall that in PhyML, each edge has a "left" and "right" partial vectors. Therefore, //in BEAGLE we have 2*num_branches number of partials. //BEAGLE's partials buffer = [ tax1, tax2, ..., taxN, b1Left, b2Left, b3Left,...,bMLeft, b1Rght, b2Rght, b3Rght,...,bMRght] (N taxa, M branches) int num_partials = 2*(tree->n_otu + num_branches); /* TODO: This does not seem correct; suspect poor indexing elsewhere */ /* In update_operations, indexes range from 0 to almost 2 (n_otu + num_branches), but not all integers are used */ int resourceList[1]; resourceList[0] = io->beagle_resource; // DUMP_I(tree->n_otu, num_rate_catg, num_partials, num_branches, tree->mod->ns, tree->n_pattern, tree->mod->whichmodel); int beagle_inst = beagleCreateInstance( tree->n_otu, /**< Number of tip data elements (input) */ num_partials, /**< Number of partial buffer (input) */ /* PhyML uses partials */ 0, /**< Number of compact state representation buffers to create (input) */ tree->mod->ns, /**< Number of states in the continuous-time Markov chain (input) */ tree->n_pattern, /**< Number of site patterns to be handled by the instance (input) */ 1, /**< Number of rate matrix eigen-decomposition,state freqs, and category weight buffers*/ num_branches, /**< Number of rate matrix buffers (input) */ num_rate_catg, /**< Number of rate categories (input) */ -1, /**< Number of scaling buffers. Unused because we use SCALING_ALWAYS */ resourceList, /**< List of potential resource on which this instance is allowed (input, NULL implies no restriction */ 1, /**< Length of resourceList list (input) */ BEAGLE_FLAG_FRAMEWORK_CPU | BEAGLE_FLAG_PROCESSOR_CPU | BEAGLE_FLAG_SCALING_ALWAYS | BEAGLE_FLAG_EIGEN_REAL | ((sizeof(float)==sizeof(phydbl)) ? BEAGLE_FLAG_PRECISION_SINGLE:BEAGLE_FLAG_PRECISION_DOUBLE), 0, /**< Bit-flags indicating required implementation characteristics, see BeagleFlags (input) */ &inst_d); if (beagle_inst < 0){ fprintf(stderr, "beagleCreateInstance() failed:%i\n\n",beagle_inst); return beagle_inst; } if(!quiet){ fprintf(stdout, "\n\tUnique BEAGLE instance id:%i\n", beagle_inst); print_beagle_instance_details(&inst_d); } //Set the tips for(i=0; i<2*tree->n_otu-1; ++i) //taxa+internal nodes { // Print_Tip_Partials(tree, tree->a_nodes[i]); if(tree->a_nodes[i]->tax) { assert(tree->a_nodes[i]->c_seq->len == tree->n_pattern); // number of compacts sites == number of distinct site patterns double* tip = short_to_double(tree->a_nodes[i]->b[0]->p_lk_tip_r, tree->n_pattern*tree->mod->ns); //The tip states are stored on the branch leading to the tip //Recall we store tip partials on the branch leading to the tip, rather than the tip itself. int ret = beagleSetTipPartials(beagle_inst, tree->a_nodes[i]->b[0]->p_lk_tip_idx, tip); if(ret<0){ fprintf(stderr, "beagleSetTipPartials() on instance %i failed:%i\n\n",beagle_inst,ret); Free(tip); return ret; } Free(tip); } } //Set the pattern weights double* pwts = int_to_double(tree->data->wght,tree->n_pattern); //BTW, These weights are absolute counts, and not freqs int ret = beagleSetPatternWeights(beagle_inst, pwts); if(ret<0){ fprintf(stderr, "beagleSetPatternWeights() on instance %i failed:%i\n\n",beagle_inst,ret); Free(pwts); return ret; } Free(pwts); tree->mod->b_inst=beagle_inst; update_beagle_ras(tree->mod); update_beagle_efrqs(tree->mod); return beagle_inst; } /* Update partial likelihood on edge b on the side of b where node d lies. */ void update_beagle_partials(t_tree* tree, t_edge* b, t_node* d) { /* | |<- b | d / \ b1 / \ b2 / \ n_v1 n_v2 */ if(d->tax) //Partial likelihoods are only calculated on internal nodes { PhyML_Printf("\n== t_node %d is a leaf...",d->num); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit("\n"); } //Determine d's "left" and "right" neighbors. t_node *n_v1, *n_v2;//d's "left" and "right" neighbor nodes phydbl *p_lk,*p_lk_v1,*p_lk_v2; phydbl *Pij1,*Pij2; int *sum_scale, *sum_scale_v1, *sum_scale_v2; int *p_lk_loc; int dest_p_idx, child1_p_idx, child2_p_idx, Pij1_idx, Pij2_idx; n_v1 = n_v2 = NULL; p_lk = p_lk_v1 = p_lk_v2 = NULL; Pij1 = Pij2 = NULL; sum_scale_v1 = sum_scale_v2 = NULL; p_lk_loc = NULL; dest_p_idx = child1_p_idx = child2_p_idx = Pij1_idx = Pij2_idx = UNINITIALIZED; Set_All_P_Lk(&n_v1,&n_v2, &p_lk,&sum_scale,&p_lk_loc, &Pij1,&p_lk_v1,&sum_scale_v1, &Pij2,&p_lk_v2,&sum_scale_v2, d,b,tree, &dest_p_idx, &child1_p_idx, &child2_p_idx, &Pij1_idx, &Pij2_idx); // fprintf(stdout, "\nUpdating partials on Branch %d (on the side where Node %d lies)\n",b->num,d->num);fflush(stdout); // double* p_lk_v1_b = (double*)malloc(tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern*sizeof(double));if(NULL==p_lk_v1_b) Warn_And_Exit("Couldnt allocate memory"); // beagleGetPartials(tree->b_inst, child1_p_idx, BEAGLE_OP_NONE, (double*)p_lk_v1_b); // double* p_lk_v2_b = (double*)malloc(tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern*sizeof(double));if(NULL==p_lk_v2_b) Warn_And_Exit("Couldnt allocate memory"); // beagleGetPartials(tree->b_inst, child2_p_idx, BEAGLE_OP_NONE, (double*)p_lk_v2_b); // fprintf(stdout, "Left partials :");fflush(stdout); // Dump_Arr_D(p_lk_v1_b, tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern); // fprintf(stdout, "Right partials:");fflush(stdout); // Dump_Arr_D(p_lk_v2_b, tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern); // Free(p_lk_v1_b); // Free(p_lk_v2_b); //Create the corresponding BEAGLE operation // fprintf(stderr,"%d, %d, %d, ", dest_p_idx, child1_p_idx, child2_p_idx); BeagleOperation operations[1] = {{dest_p_idx, BEAGLE_OP_NONE, BEAGLE_OP_NONE, child1_p_idx, Pij1_idx, child2_p_idx, Pij2_idx}}; //Compute the partials int ret = beagleUpdatePartials(tree->b_inst, operations, 1, BEAGLE_OP_NONE); if(ret<0){ fprintf(stderr, "beagleUpdatePartials() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } //Load the computed/updated partial partials #ifndef CLEAN_BEAGLE_API ret = beagleGetPartials(tree->b_inst, dest_p_idx, BEAGLE_OP_NONE, (double*)p_lk); if(ret<0){ fprintf(stderr, "beagleGetPartials() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } #endif // fprintf(stdout, "Updated partials:");fflush(stdout); // Dump_Arr_D(p_lk, tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern); } int finalize_beagle_instance(t_tree *tree) { if(tree->b_inst >= 0) { int ret = beagleFinalizeInstance(tree->b_inst); if(ret<0) fprintf(stderr, "\nFailed to finalize BEAGLE instance %i: %i\n\n", tree->b_inst, ret); return ret; } return 0; } void update_beagle_ras(t_mod* mod) { assert(UNINITIALIZED != mod->b_inst); int ret=-1; if((sizeof(float)==sizeof(phydbl))) //Do we need to convert? { double* catg_rates = float_to_double(mod->ras->gamma_rr->v, mod->ras->n_catg); ret = beagleSetCategoryRates(mod->b_inst, catg_rates); Free(catg_rates); if(ret<0){ fprintf(stderr, "beagleSetCategoryRates() on instance %i failed:%i\n\n",mod->b_inst,ret); Exit(""); } double* catg_wts = float_to_double(mod->ras->gamma_r_proba->v, mod->ras->n_catg); if(!mod->optimizing_topology) { ret = beagleSetCategoryWeights(mod->b_inst, 0, catg_wts); Free(catg_wts); if(ret<0){ fprintf(stderr, "beagleSetCategoryWeights() on instance %i failed:%i\n\n",mod->b_inst,ret); Exit(""); } } } else { ret = beagleSetCategoryRates(mod->b_inst, mod->ras->gamma_rr->v); if(ret<0){ fprintf(stderr, "beagleSetCategoryRates() on instance %i failed:%i\n\n",mod->b_inst,ret); Exit(""); } if(!mod->optimizing_topology) { ret = beagleSetCategoryWeights(mod->b_inst, 0, mod->ras->gamma_r_proba->v); if(ret<0){ fprintf(stderr, "beagleSetCategoryWeights() on instance %i failed:%i\n\n",mod->b_inst,ret); Exit(""); } } } } void update_beagle_efrqs(t_mod* mod) { assert(UNINITIALIZED != mod->b_inst); int ret=-1; if((sizeof(float)==sizeof(phydbl))) { double* efrqs = float_to_double(mod->e_frq->pi->v, mod->ns); ret = beagleSetStateFrequencies(mod->b_inst, 0, efrqs); Free(efrqs); } else { ret = beagleSetStateFrequencies(mod->b_inst, 0, mod->e_frq->pi->v); } if(ret<0){ fprintf(stderr, "beagleSetStateFrequencies() on instance %i failed:%i\n\n",mod->b_inst,ret); Exit(""); } } void calc_edgelks_beagle(t_edge *b, t_tree *tree) { assert(UNINITIALIZED != tree->b_inst); //Compute the edge likelihood int parents[1] = {b->p_lk_left_idx}; int children[1] = {b->rght->tax?b->p_lk_tip_idx:b->p_lk_rght_idx}; int pmats[1] = {b->Pij_rr_idx}; int other[1] = {0};//Category Weights and State Frequencies both have a single buffer, hence they are both indexed at 0 double lnL[1] = {UNINITIALIZED}; // DUMP_I(parents[0], children[0], pmats[0], b->num, b->rght->tax); int ret=beagleCalculateEdgeLogLikelihoods(tree->b_inst, parents, children, pmats, NULL, NULL, other, other, NULL, 1, lnL, NULL, NULL); int i; if(ret<0){ fprintf(stderr, "beagleCalculateEdgeLogLikelihoods() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } tree->c_lnL = sizeof(phydbl)==sizeof(float)?(float)lnL[0]:lnL[0]; //Retrieve the site likelihoods that were computed during the previous edge likelihood computation ret = beagleGetSiteLogLikelihoods(tree->b_inst,tree->cur_site_lk);//TODO: Handle when cur_site_lk is float if(ret<0){ fprintf(stderr, "beagleGetSiteLogLikelihoods() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } //Transform for(i=0;in_pattern;++i) tree->cur_site_lk[i]=EXP(tree->cur_site_lk[i]); } void update_beagle_eigen(t_mod* mod) { assert(UNINITIALIZED != mod->b_inst); int whichmodel = mod->whichmodel; //We use Eigen Decomposition only for GTR models and AA datasets if((mod->io->datatype == AA || whichmodel==GTR || whichmodel==CUSTOM) && mod->use_m4mod == NO) { //Beagle expects untransformed eigen-values (i.e. recall e_val is EXP() scaled, so we undo that) phydbl* evals = (phydbl*)malloc(mod->ns * sizeof(phydbl)); int i; for(i=0;ins;++i) evals[i]=LOG(mod->eigen->e_val[i]); int ret=-1; if((sizeof(float)==sizeof(phydbl)))//Need to convert to doubles? { double* eigen_vects = float_to_double(mod->eigen->r_e_vect, mod->eigen->size*mod->eigen->size); double* eigen_vects_inv = float_to_double(mod->eigen->l_e_vect, mod->eigen->size*mod->eigen->size); double* eigen_vals = float_to_double(evals,mod->eigen->size); ret = beagleSetEigenDecomposition(mod->b_inst,0,eigen_vects,eigen_vects_inv,eigen_vals); Free(eigen_vects);Free(eigen_vects_inv);Free(eigen_vals); } else { ret = beagleSetEigenDecomposition(mod->b_inst,0,mod->eigen->r_e_vect,mod->eigen->l_e_vect,evals); } if(ret<0){ fprintf(stderr, "beagleSetEigenDecomposition() on instance %i failed:%i\n\n",mod->b_inst,ret); Free(evals); Exit(""); } Free(evals); } } #endif // BEAGLE_UTILS_CPP phyml-3.2.0/src/beagle_utils.h000066400000000000000000000066111263450375500162620ustar00rootroot00000000000000/* * author: Imran Fanaswala */ #ifndef BEAGLE_UTILS_H #define BEAGLE_UTILS_H #include "assert.h" #include "libhmsbeagle/beagle.h" #include "utilities.h" #define UNINITIALIZED -42 /* BEAGLE is a library that abstracts the core computations common to most phylogenetic packages. The following paragraphs serve as a "design document" for the implementation details of how BEAGLE has been integrated with PhyML. The reader is expected to be familiar with phylogenetics, skimmed the BEAGLE API, and seen a couple of its examples. PARTIAL LIKELIHOODS: - For each internal edge, PhyML maintains a vector of partials that lie to the "right" and "left", to faciliate both post-order and pre-order tree traversal. Therefore each t_edge has a `p_lk_right` and `p_lk_left` field - PhyML represents a tip as a vector of partials (where one bit is "1", and the rest are "0"). Therefore, a t_edge connected to a tip has `p_lk_tip` field. Also by convention, the tip always lies to the right of the edge its connected to. In other words, if b->right->tax is True, then b->p_lk_tip holds the tip partials. - Therefore for BEAGLE, we allocate N+(2*num_edges) partial buffers. - Recall that BEAGLE requires each partial buffer to be uniquely indexed. Thus each edge also has an additional `p_lk_rght_idx` and `p_lk_left_idx` field. These fields are used to create a BeagleOperation struct during the call to beagleUpdatePartials(). - In PhyML, Update_P_Lk() updates the partials for a specific edge lieing along a specific "direction". The "direction" depends on which tree-traversal is being employed. In other words, the tree-traversal dictates whether we are computing "up"/"right" or "down"/"left" partials relative to the t_node*. Specifically, Set_All_P_Lk() handles the nitty gritty of determining whether we are computing "right" or "left" partials. Therefore this function has been modified to also set the appropriate BEAGLE indices. P-MATS and EDGELIKELIHOODS: - (1) Observe that PhyML does eigen decomposition for only GTR and AA models and thus the P-matrix is computed using Beagle. This implies the usage of SetEigenDecomposition() and UpdateTransitionMatricies() calls. - (2) On the other hand, in case of simpler models (JC69, F81, etc), the P-Matrix is explicitly set in BEAGLE thus implying the usage of SetTransitionMatrix(). - The choice between (1) and (2) is made in Update_PMat_At_Given_Edge(). BTW, upon reading Update_PMat_At_Given_Edge(), it may appear that the P-Matrix is being computed in PhyML *and* in BEAGLE; afterall because PMat() function in all cases. However, when BEAGLE is enabled, observe that in PMat() essentially does nothing. - Lk_Core() computes the edgelikelihoods, and calc_edgelks_beagle() is the corresponding BEAGLE function that does the same. */ #define TODO_BEAGLE "TODO. This codepath has not been implemented in PhyML-X, please post your usecase on the PhyML discussion list" int create_beagle_instance(t_tree* tree, int quiet, option* io); int finalize_beagle_instance(t_tree* tree); void update_beagle_partials(t_tree* tree, t_edge* b, t_node* d); void update_beagle_ras(t_mod* mod); void update_beagle_efrqs(t_mod* mod); void update_beagle_eigen(t_mod* mod); void calc_edgelks_beagle(t_edge* b, t_tree* tree); double* int_to_double(const int* src, int num_elems); double* short_to_double(const short* src, int num_elems); double* float_to_double(const phydbl *src, int num_elems); #endif // BEAGLE_UTILS_H phyml-3.2.0/src/bionj.c000066400000000000000000000243401263450375500147160ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* The code below is an implementation of the building tree algorithm described in "BIONJ: an improved version of the NJ algorithm based on a simple model of sequence data." (1997) O. Gascuel. Mol Biol Evol. 14:685-95. */ #include "bionj.h" void Bionj(matrix *mat) { int x,y,i; phydbl vxy,lx,ly,lamda,score; Clean_Tree_Connections(mat->tree); For(i,mat->tree->n_otu) mat->tip_node[i] = mat->tree->a_nodes[i]; mat->tree->num_curr_branch_available = 0; while(mat->r > 3) { x = y = 0; vxy = .0; score = .0; Compute_Sx(mat); Best_Pair(mat,&x,&y,&score); vxy=BioNJ_Variance(mat,x,y); lx=Br_Length(mat,x,y); ly=Br_Length(mat,y,x); lamda=Lamda(mat,x,y,vxy); Update_Mat(mat,x,y,lx,ly,vxy,lamda); Update_Tree(mat,x,y,lx,ly,score); } Finish(mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Finish(matrix *mat) { phydbl dxy,dxz,dyz; int x,y,z; t_node *nx,*ny,*nz,*new; int i; dxy = dxz = dyz = -1.; x = y = z = -1; For(i,mat->n_otu) { if(mat->on_off[i]) { if(x < 0) x=i; else if(y < 0) y = i; else if(z < 0) z = i; } } dxy = Dist(mat,x,y); dxz = Dist(mat,x,z); dyz = Dist(mat,y,z); nx = mat->tip_node[x]; ny = mat->tip_node[y]; nz = mat->tip_node[z]; new = mat->tree->a_nodes[mat->curr_int]; new->num = mat->curr_int; new->v[0] = nx; new->v[1] = ny; new->v[2] = nz; nx->v[0] = new; ny->v[0] = new; nz->v[0] = new; Connect_One_Edge_To_Two_Nodes(new,nx,mat->tree->a_edges[mat->tree->num_curr_branch_available],mat->tree); Connect_One_Edge_To_Two_Nodes(new,ny,mat->tree->a_edges[mat->tree->num_curr_branch_available],mat->tree); Connect_One_Edge_To_Two_Nodes(new,nz,mat->tree->a_edges[mat->tree->num_curr_branch_available],mat->tree); nx->b[0]->l->v = .5*(dxy-dyz+dxz); ny->b[0]->l->v = .5*(dyz-dxz+dxy); nz->b[0]->l->v = .5*(dxz-dxy+dyz); new->b[0]->l->v = nx->b[0]->l->v; new->b[1]->l->v = ny->b[0]->l->v; new->b[2]->l->v = nz->b[0]->l->v; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Mat(matrix *mat, int x, int y, phydbl lx, phydbl ly, phydbl vxy, phydbl lamda) { int i; int a,b; a = b = -1; For(i,mat->n_otu) { if((mat->on_off[i]) && (i != x) && (i != y)) { if(x > i) { a=x; b=i; } else { a=i; b=x; } mat->dist[a][b]=Dist_Red(mat,x,lx,y,ly,i,lamda); mat->dist[b][a]=Var_Red(mat,x,y,i,lamda,vxy); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Tree(matrix *mat, int x, int y, phydbl lx, phydbl ly, phydbl score) { t_node *new, *nx, *ny; nx = mat->tip_node[x]; ny = mat->tip_node[y]; new = mat->tree->a_nodes[mat->curr_int]; nx->v[0] = new; ny->v[0] = new; new->v[1] = nx; new->v[2] = ny; new->num = mat->curr_int; Connect_One_Edge_To_Two_Nodes(new,nx,mat->tree->a_edges[mat->tree->num_curr_branch_available],mat->tree); Connect_One_Edge_To_Two_Nodes(new,ny,mat->tree->a_edges[mat->tree->num_curr_branch_available],mat->tree); nx->b[0]->l->v = lx; ny->b[0]->l->v = ly; new->b[1]->l->v = lx; new->b[2]->l->v = ly; new->score[0] = score; nx->l[0] = lx; ny->l[0] = ly; new->l[1] = lx; new->l[2] = ly; mat->tip_node[x] = new; mat->on_off[y] = 0; mat->curr_int++; mat->r--; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Best_Pair(matrix *mat, int *x, int *y,phydbl *score) { int i,j/* ,n_ties */; phydbl Qmin,Qmin2; phydbl *t_Qij; /* int *ties; */ t_Qij = (phydbl *)mCalloc(mat->n_otu * mat->n_otu,sizeof(phydbl )); /* ties = (int *)mCalloc(mat->n_otu * mat->n_otu,sizeof(int )); */ Qmin = 1.e+10; For(i,mat->n_otu) { if(mat->on_off[i]) { for(j=0;jon_off[j]) { t_Qij[mat->n_otu*i+j] = Q_Agglo(mat,i,j); if(t_Qij[mat->n_otu*i+j] < Qmin - 1.E-05) { *x = i; *y = j; Qmin = t_Qij[mat->n_otu*i+j]; } } } } } /* n_ties = 0; */ /* For(i,mat->n_otu) */ /* { */ /* if(mat->on_off[i]) */ /* { */ /* for(j=0;jon_off[j]) */ /* { */ /* if((t_Qij[mat->n_otu*i+j] < Qmin + 1.E-05) && (t_Qij[mat->n_otu*i+j] > Qmin - 1.E-05)) */ /* { */ /* ties[n_ties] = mat->n_otu*i+j; */ /* n_ties++; */ /* } */ /* } */ /* } */ /* } */ /* } */ /* if(!n_ties) */ /* { */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* /\* Useful if some pairwise distances are null *\/ */ /* if(n_ties > 1) */ /* { */ /* int cand; */ /* *x = *y = -1; */ /* cand = (int)RINT(rand()/(phydbl)(RAND_MAX) * (n_ties-1)); */ /* *x = (int)(ties[cand] / mat->n_otu); */ /* *y = (int)(ties[cand] % mat->n_otu); */ /* } */ Qmin2 = 1e+10; For(i,mat->n_otu) { if((i != *y) && (i != *x) && (t_Qij[mat->n_otu*(*x)+i] < Qmin2)) Qmin2 = t_Qij[mat->n_otu*(*x)+i]; } For(i,mat->n_otu) { if((i != *y) && (i != *x) && (t_Qij[mat->n_otu*i+(*y)] < Qmin2)) Qmin2 = t_Qij[mat->n_otu*i+(*y)]; } *score = FABS(Qmin2 - Qmin)/FABS(Qmin); Free(t_Qij); /* Free(ties); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Compute_Sx(matrix *mat) { int i,j; For(i,mat->n_otu) { mat->dist[i][i] = .0; if(mat->on_off[i]) { For(j,mat->n_otu) { if((i != j) && (mat->on_off[j])) { mat->dist[i][i] += Dist(mat,i,j); } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Sum_S(matrix *mat, int i) { return mat->dist[i][i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dist(matrix *mat, int x, int y) { if(x > y) return(mat->dist[x][y]); else return(mat->dist[y][x]); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl BioNJ_Variance(matrix *mat, int x, int y) { if(x > y) { return(mat->dist[y][x]); } else { return(mat->dist[x][y]); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Br_Length(matrix *mat, int x, int y) { return .5*(Dist(mat,x,y)+ (Sum_S(mat,x)-Sum_S(mat,y))/(phydbl)(mat->r-2.)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dist_Red(matrix *mat, int x, phydbl lx, int y, phydbl ly, int i, phydbl lamda) { phydbl Dui; Dui=lamda*(Dist(mat,x,i)-lx) +(1.-lamda)*(Dist(mat,y,i)-ly); return(Dui); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Var_Red(matrix *mat, int x, int y, int i, phydbl lamda, phydbl vxy) { phydbl Vui; Vui=lamda*(BioNJ_Variance(mat,x,i)) +(1.-lamda)*(BioNJ_Variance(mat,y,i)) -lamda*(1.-lamda)*vxy; return(Vui); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Lamda(matrix *mat, int x, int y, phydbl vxy) { phydbl lamda=0.0; int i; if(mat->method == 0) /* NJ (Saitou & Nei, 1987) */ lamda = 0.5; else /* BioNJ (Gascuel, 1997) */ { if(vxy < SMALL && vxy > -SMALL) lamda=0.5; else { For(i,mat->n_otu) { if((x != i) && (y != i) && (mat->on_off[i])) lamda = lamda + BioNJ_Variance(mat,y,i) - BioNJ_Variance(mat,x,i); } lamda = 0.5 + lamda/(2.*(mat->r-2)*vxy); } if(lamda > 1.0) lamda = 0.5;/*1.0;*/ else if(lamda < 0.0) lamda = 0.5;/*0.0;*/ } return(lamda); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Q_Agglo(matrix *mat, int x, int y) { phydbl Qxy; Qxy = .0; Qxy=(mat->r-2.)*Dist(mat,x,y)-Sum_S(mat,x)-Sum_S(mat,y); return(Qxy); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Bionj_Br_Length(matrix *mat) { int x; x = Bionj_Br_Length_Post(mat->tree->a_nodes[0], mat->tree->a_nodes[0]->v[0], mat); mat->tree->a_nodes[0]->b[0]->l->v = Dist(mat,0,x); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Bionj_Br_Length_Post(t_node *a, t_node *d, matrix *mat) { int i; if(d->tax) { return d->num; } else { int d_v1, d_v2; phydbl lx, ly, vxy,lamda; int x,y; d_v1 = d_v2 = -1; For(i,3) if(d->v[i] != a) {(d_v1 < 0)?(d_v1 = i):(d_v2 = i);} x = Bionj_Br_Length_Post(d,d->v[d_v1],mat); y = Bionj_Br_Length_Post(d,d->v[d_v2],mat); vxy = .0; Compute_Sx(mat); vxy=BioNJ_Variance(mat,(x),(y)); lx=Br_Length(mat,(x),(y)); ly=Br_Length(mat,(y),(x)); lamda=Lamda(mat,(x),(y),vxy); Update_Mat(mat,(x),(y),lx,ly,vxy,lamda); d->b[d_v1]->l->v = lx; d->b[d_v2]->l->v = ly; mat->on_off[y] = 0; mat->r--; return x; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/bionj.h000066400000000000000000000024561263450375500147270ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef NJ_H #define NJ_H #include "utilities.h" #include "optimiz.h" #include "free.h" void Bionj(matrix *mat); void Finish(matrix *mat); void Compute_Sx(matrix *mat); phydbl Sum_S(matrix *mat, int i); phydbl Dist(matrix *mat, int x, int y); phydbl Q_Agglo(matrix *mat, int x, int y); phydbl BioNJ_Variance(matrix *mat, int x, int y); phydbl Br_Length(matrix *mat, int x, int y); void Update_Dist(matrix *mat, int x, int y); phydbl Lamda(matrix *mat, int x, int y, phydbl vxy); void Best_Pair(matrix *mat, int *x, int *y, phydbl *score); phydbl Var_Red(matrix *mat, int x, int y, int i, phydbl lamda, phydbl vxy); void Update_Tree(matrix *mat, int x, int y, phydbl lx, phydbl ly, phydbl score); void Update_Mat(matrix *mat, int x, int y, phydbl lx, phydbl ly, phydbl vxy, phydbl lamda); phydbl Dist_Red(matrix *mat, int x, phydbl lx, int y, phydbl ly, int i, phydbl lamda); int Bionj_Br_Length_Post(t_node *a, t_node *d, matrix *mat); void Bionj_Br_Length(matrix *mat); #endif phyml-3.2.0/src/checkpoint.c000066400000000000000000000021311263450375500157360ustar00rootroot00000000000000#include "checkpoint.h" void CHECK_Main(int argc,char **argv) { // Up to you Salva... } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/checkpoint.h000066400000000000000000000002101263450375500157370ustar00rootroot00000000000000#include #ifndef CHECKPOINT_H #define CHECKPOINT_H #include "utilities.h" void CHECK_Main(int argc, char **argv); #endif phyml-3.2.0/src/cl.c000066400000000000000000001147701263450375500142220ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "cl.h" /*********************************************************/ /** * Fill the Option fields, with the argc array */ int Read_Command_Line(option *io, int argc, char **argv) { int c; int idx; int i; int writemode; PhyML_Printf("\n. command-line: "); For(i,argc) PhyML_Printf("%s ",argv[i]); if(argc == 1) Exit("\n. No argument was passed to the program. Please check the documentation. \n"); struct option longopts[] = { {"n_rgrft", required_argument,NULL,0}, {"n_globl", required_argument,NULL,1}, {"max_dist", required_argument,NULL,2}, {"n_optim", required_argument,NULL,3}, {"n_best", required_argument,NULL,4}, {"model", required_argument,NULL,5}, {"search", required_argument,NULL,6}, {"datatype", required_argument,NULL,7}, {"multiple", required_argument,NULL,8}, {"input", required_argument,NULL,9}, {"bootstrap", required_argument,NULL,10}, {"ts/tv", required_argument,NULL,11}, {"nclasses", required_argument,NULL,12}, {"pinv", required_argument,NULL,13}, {"alpha", required_argument,NULL,14}, {"inputtree", required_argument,NULL,15}, {"min_diff_lk_local", required_argument,NULL,16}, {"min_diff_lk_global",required_argument,NULL,17}, {"steph_spr", no_argument,NULL,18}, {"brent_it_max", required_argument,NULL,19}, {"rand_start", no_argument,NULL,20}, {"n_rand_starts", required_argument,NULL,21}, {"sequential", no_argument,NULL,22}, {"inside_opt", no_argument,NULL,23}, {"p_moves", required_argument,NULL,24}, {"fast_nni", no_argument,NULL,25}, {"g_pars", no_argument,NULL,26}, {"r_seed", required_argument,NULL,27}, {"collapse_boot", required_argument,NULL,28}, {"random_boot", required_argument,NULL,29}, {"print_trace", no_argument,NULL,30}, {"print_site_lnl", no_argument,NULL,31}, {"print_site_lk", no_argument,NULL,31}, {"cov", no_argument,NULL,32}, {"cov_delta", required_argument,NULL,33}, {"cov_alpha", required_argument,NULL,34}, {"cov_ncats", required_argument,NULL,35}, {"ps", no_argument,NULL,36}, {"cov_free", no_argument,NULL,37}, {"no_gap", no_argument,NULL,38}, {"n_rr_branch", required_argument,NULL,39}, {"append", no_argument,NULL,40}, {"no_five_branch", no_argument,NULL,41}, {"pars_thresh", required_argument,NULL,42}, {"min_diff_lk_move", required_argument,NULL,43}, {"hybrid", no_argument,NULL,44}, {"use_median", no_argument,NULL,45}, {"run_id", required_argument,NULL,46}, {"pars", no_argument,NULL,47}, {"quiet", no_argument,NULL,48}, {"version", no_argument,NULL,49}, {"calibration_file", required_argument,NULL,50}, {"calibration", required_argument,NULL,50}, {"clade_file", required_argument,NULL,50}, {"boot_progress_every", required_argument,NULL,51}, {"aa_rate_file", required_argument,NULL,52}, {"chain_len", required_argument,NULL,53}, {"sample_freq", required_argument,NULL,54}, {"burnin", required_argument,NULL,55}, {"no_memory_check", no_argument,NULL,56}, {"no_colalias", no_argument,NULL,57}, {"alias_subpatt", no_argument,NULL,58}, {"no_sequences", no_argument,NULL,59}, {"prior", no_argument,NULL,59}, {"fastlk", no_argument,NULL,60}, {"free_rates", no_argument,NULL,61}, {"freerates", no_argument,NULL,61}, {"freerate", no_argument,NULL,61}, {"free_rate", no_argument,NULL,61}, {"is", no_argument,NULL,62}, // no 63 since it corresponds to character '?' {"rate_model", required_argument,NULL,64}, {"ratemodel", required_argument,NULL,64}, {"log_l", no_argument,NULL,65}, {"gamma_lens", no_argument,NULL,66}, {"il", no_argument,NULL,66}, {"codpos", required_argument,NULL,67}, {"constraint_file", required_argument,NULL,68}, {"constraint_tree", required_argument,NULL,68}, {"help", no_argument,NULL,69}, {"mutmap", no_argument,NULL,70}, {"parvals", required_argument,NULL,71}, {"constrained_lens", no_argument,NULL,72}, {"xml", required_argument,NULL,73}, {"l_var", required_argument,NULL,74}, #ifdef BEAGLE {"beagle_resource", required_argument,NULL,75}, #endif {"ancestral", no_argument,NULL,76}, {"anc", no_argument,NULL,76}, {"coord_file", required_argument,NULL,77}, {0,0,0,0} }; io->datatype = UNDEFINED; #ifndef PHYML int open_ps_file = 0; #endif idx=-1; do { c = getopt_long(argc,argv,"qi:d:m:b:n:t:f:zk:v:c:a:u:ho:s:x:g:l:ep",longopts,&idx); switch(c) { case 77: { char *tmp; tmp = (char *)mCalloc(T_MAX_FILE, sizeof(char)); if(strlen(optarg) > T_MAX_FILE -11) { char choix; strcpy (tmp, "\n. The file name'"); strcat (tmp, optarg); strcat (tmp, "' is too long.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else if (!Filexists (optarg)) { char choix; strcpy (tmp, "\n. The file '"); strcat (tmp, optarg); strcat (tmp, "' doesn't exist.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { strcpy(io->in_coord_file, optarg); io->fp_in_coord = Openfile(io->in_coord_file,READ); } Free(tmp); break; } case 76: { io->ancestral = YES; break; } #ifdef BEAGLE case 75: { io->beagle_resource = (int)atoi(optarg); break; } #endif case 74: { io->mod->l_var_sigma = String_To_Dbl(optarg); break; } case 73: { #ifndef INVITEE Free_Optimiz(io->mod->s_opt); M4_Free_M4_Model(io->mod->m4mod); Free_Model_Basic(io->mod); Free_Input(io); PhyML_XML(optarg); return 0; #else Free_Optimiz(io->mod->s_opt); M4_Free_M4_Model(io->mod->m4mod); Free_Model_Basic(io->mod); Free_Input(io); PhyTime_XML(optarg); return 0; #endif break; } case 72: { io->mod->s_opt->constrained_br_len = YES; break; } case 71: { io->mcmc->in_fp_par = fopen(optarg,"r"); io->mcmc->randomize = NO; break; } case 70: { io->mutmap = YES; break; } case 68: { char *tmp; tmp = (char *)mCalloc(T_MAX_FILE, sizeof(char)); if(strlen(optarg) > T_MAX_FILE -11) { char choix; strcpy (tmp, "\n. The file name'"); strcat (tmp, optarg); strcat (tmp, "' is too long.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else if (!Filexists (optarg)) { char choix; strcpy (tmp, "\n. The file '"); strcat (tmp, optarg); strcat (tmp, "' doesn't exist.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { strcpy(io->in_constraint_tree_file, optarg); io->fp_in_constraint_tree = Openfile(io->in_constraint_tree_file,0); } Free(tmp); break; } case 67: { phydbl pos; pos = atof(optarg); io->codpos = (int)pos; if(io->codpos < 1 || io->codpos > 3) { char choix; PhyML_Printf("\n. Coding position must be set to 1, 2 or 3.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; break; } case 66: { io->mod->gamma_mgf_bl = YES; io->mod->s_opt->opt_gamma_br_len = YES; break; } case 65: { io->mod->log_l = YES; break; } case 64: { char *s; int i; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); i = 0; while(optarg[i++]) s[i]=tolower(optarg[i]); if(!strcmp(optarg,"gbd")) io->rates->model = THORNE; else if(!strcmp(optarg,"gbs")) io->rates->model = GUINDON; else if(!strcmp(optarg,"gamma")) io->rates->model = GAMMA; else if(!strcmp(optarg,"clock")) io->rates->model = STRICTCLOCK; else if(!strcmp(optarg,"strictclock")) io->rates->model = STRICTCLOCK; else if(!strcmp(optarg,"strict_clock")) io->rates->model = STRICTCLOCK; else { PhyML_Printf("\n. rate_model should be 'gbs', 'gbd', 'gamma' or 'clock'."); Exit("\n"); } Free(s); break; } case 62: { io->mcmc->is = YES; break; } case 61: { io->mod->ras->free_mixt_rates = YES; io->mod->s_opt->opt_free_mixt_rates = YES; break; } case 60: { io->lk_approx = NORMAL; break; } case 59: { io->mcmc->use_data = NO; break; } case 58: { io->do_alias_subpatt = YES; break; } case 57: { io->colalias = NO; break; } case 56: { io->mem_question = NO; break; } case 55: { phydbl len; len = atof(optarg); io->mcmc->chain_len_burnin = (int)len; if(io->mcmc->chain_len_burnin < 1) { char choix; PhyML_Printf("\n. chain_len_burnin must be an integer greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 54: { phydbl len; len = atof(optarg); io->mcmc->sample_interval = (int)len; if(io->mcmc->sample_interval < 1) { char choix; PhyML_Printf("\n. sample_interval must be an integer greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 53: { phydbl len; len = atof(optarg); io->mcmc->chain_len = (int)len; if(io->mcmc->chain_len < 1) { char choix; PhyML_Printf("\n. chain_len must be an integer greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 52: { char *s; s = (char *)mCalloc(T_MAX_FILE, sizeof(char)); strcpy(s,optarg); io->mod->fp_aa_rate_mat = Openfile(s,0); strcpy(io->mod->aa_rate_mat_file->s,s); Free(s); break; } case 51: { io->boot_prog_every = atoi(optarg); if(io->boot_prog_every < 1) { char choix; PhyML_Printf("\n. boot_progress_every must be an integer greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 50: { strcpy(io->clade_list_file,optarg); break; } case 49: { PhyML_Printf("\n. This is PhyML version %s.\n\n",VERSION); Exit(""); break; } case 48 : { io->quiet = 1; break; } case 'p' : case 47 : { io->in_tree = 1; break; } case 46 : { io->append_run_ID = YES; strcpy(io->run_id_string,optarg); break; } case 45 : { io->mod->ras->gamma_median = 1; break; } case 44 : { io->mod->s_opt->hybrid_thresh = 0; break; } case 43 : { io->mod->s_opt->min_diff_lk_move = atof(optarg); if(io->mod->s_opt->min_diff_lk_move < 0) { char choix; PhyML_Printf("\n. Min_diff_lk_move must be a double greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 42 : { io->mod->s_opt->pars_thresh = (int)atoi(optarg); if(io->mod->s_opt->pars_thresh < 0) { PhyML_Printf("\n. The parsimony threshold must be an integer greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); Exit("\n"); } break; } case 41 : { io->mod->s_opt->opt_five_branch = 0; break; } case 40 : { writemode = 2; break; } case 39 : { break; } case 38 : { io->rm_ambigu = 1; break; } case 37 : { io->mod->s_opt->opt_cov_free_rates = YES; io->mod->m4mod->use_cov_alpha = NO; io->mod->m4mod->use_cov_free = YES; break; } case 36 : { #ifndef PHYML open_ps_file = 1; #endif break; } case 35 : { io->mod->m4mod->n_h = (int)atoi(optarg); if(io->mod->m4mod->n_h < 1) { char choix; PhyML_Printf("\n. The number of classes must be greater than 0.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 34 : { io->mod->m4mod->use_cov_alpha = YES; io->mod->m4mod->use_cov_free = NO; if(!strcmp(optarg,"e") || !strcmp(optarg,"E") || !strcmp(optarg,"estimated") || !strcmp(optarg,"ESTIMATED")) { io->mod->s_opt->opt_cov_alpha = YES; io->mod->m4mod->alpha = 1.0; } else { io->mod->m4mod->alpha = (phydbl)atof(optarg); if(io->mod->m4mod->alpha < 1.E-5) { char choix; PhyML_Printf("\n. The value of alpha must be greater than 1.E-5.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } } break; } case 33 : { if(!strcmp(optarg,"e") || !strcmp(optarg,"E") || !strcmp(optarg,"estimated") || !strcmp(optarg,"ESTIMATED")) { io->mod->s_opt->opt_cov_delta = YES; io->mod->m4mod->delta = 1.0; } else { io->mod->m4mod->delta = (phydbl)atof(optarg); if(atof(optarg) < 1.E-10) { char choix; PhyML_Printf("\n. The value of delta must be larger than 1.E-10.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } } break; } case 32 : { io->mod->use_m4mod = YES; break; } case 31 : { io->print_site_lnl = YES; break; } case 30 : { io->print_trace = YES; break; } case 29 : { io->random_boot_seq_order = (int)atoi(optarg); break; } case 28 : { io->collapse_boot = (int)atoi(optarg); break; } case 27 : { io->r_seed = (int)atoi(optarg); break; } case 26 : { io->mod->s_opt->general_pars = YES; break; } case 25 : { io->mod->s_opt->fast_nni = YES; break; } case 24 : { io->mod->s_opt->p_moves_to_examine = (phydbl)atof(optarg); break; } case 23 : { io->mod->s_opt->wim_inside_opt = 1; break; } case 0 : { io->mod->s_opt->wim_n_rgrft = atoi(optarg); break; } case 1 : { io->mod->s_opt->wim_n_globl = atoi(optarg); break; } case 2 : { io->mod->s_opt->wim_max_dist = atoi(optarg); break; } case 3 : { io->mod->s_opt->wim_n_optim = atoi(optarg); break; } case 4 : { io->mod->s_opt->wim_n_best = atoi(optarg); break; } case 16 : { io->mod->s_opt->min_diff_lk_local = atof(optarg); break; } case 17 : { io->mod->s_opt->min_diff_lk_global = atof(optarg); break; } case 18 : { io->mod->s_opt->steph_spr = 0; io->mod->s_opt->greedy = 1; break; } case 19 : { io->mod->s_opt->brent_it_max = atoi(optarg); break; } case 20 : { io->mod->s_opt->random_input_tree = 1; break; } case 21 : { io->mod->s_opt->random_input_tree = 1; io->mod->s_opt->n_rand_starts = atoi(optarg); if(io->mod->s_opt->n_rand_starts < 1) Exit("\n== Number of random starting trees must be > 0.\n\n"); } case 's':case 6: { if((!strcmp(optarg,"spr")) || (!strcmp(optarg,"SPR"))) { io->mod->s_opt->topo_search = SPR_MOVE; io->mod->s_opt->greedy = (io->mod->s_opt->steph_spr)?(0):(1); } else if((!strcmp(optarg,"nni")) || (!strcmp(optarg,"NNI"))) { io->mod->s_opt->topo_search = NNI_MOVE; io->mod->s_opt->random_input_tree = 0; } else if((!strcmp(optarg,"best")) || (!strcmp(optarg,"BEST"))) { io->mod->s_opt->topo_search = BEST_OF_NNI_AND_SPR; io->mod->s_opt->greedy = (io->mod->s_opt->steph_spr)?(0):(1); } break; } case 'd':case 7: { if(!strcmp(optarg,"nt")) { io->datatype = NT; io->mod->ns = 4; io->mod->m4mod->n_o = 4; if((io->mod->whichmodel == LG) || (io->mod->whichmodel == WAG) || (io->mod->whichmodel == DAYHOFF) || (io->mod->whichmodel == JTT) || (io->mod->whichmodel == BLOSUM62) || (io->mod->whichmodel == MTREV) || (io->mod->whichmodel == RTREV) || (io->mod->whichmodel == CPREV) || (io->mod->whichmodel == DCMUT) || (io->mod->whichmodel == VT) || (io->mod->whichmodel == MTMAM) || (io->mod->whichmodel == MTART) || (io->mod->whichmodel == HIVW) || (io->mod->whichmodel == HIVB) || (io->mod->whichmodel == AB) || (io->mod->whichmodel == CUSTOMAA) ) { io->mod->whichmodel = HKY85; strcpy(io->mod->modelname->s, "HKY85\0"); } } else if (!strcmp(optarg,"aa")) { io->datatype = AA; io->mod->s_opt->opt_kappa = NO; io->mod->ns = 20; io->mod->m4mod->n_o = 20; if( (io->mod->whichmodel == JC69) || (io->mod->whichmodel == K80) || (io->mod->whichmodel == F81) || (io->mod->whichmodel == HKY85) || (io->mod->whichmodel == F84) || (io->mod->whichmodel == TN93) || (io->mod->whichmodel == GTR) || (io->mod->whichmodel == CUSTOM) ) { io->mod->whichmodel = LG; strcpy(io->mod->modelname->s, "LG\0"); } } else if ((!strcmp(optarg,"generic")) || (!strcmp(optarg,"gen"))) { io->datatype = GENERIC; } else { char choix; PhyML_Printf("\n. Unknown argument to -d option: please use `nt' for DNA or `aa' for Amino-Acids\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case 'm': case 5 : { int i; For(i,strlen(optarg)) Uppercase(optarg+i); if(!isalpha(optarg[0])) { strcpy(io->mod->custom_mod_string->s,optarg); if(strlen(io->mod->custom_mod_string->s) != 6) { Warn_And_Exit("\n. The string should be of length 6.\n"); } else { /* Make_Custom_Model(io->mod); */ /* Translate_Custom_Mod_String(io->mod); */ } io->datatype = NT; io->mod->whichmodel = CUSTOM; strcpy(io->mod->modelname->s, "custom"); io->mod->s_opt->opt_kappa = NO; io->mod->s_opt->opt_rr = YES; } else if (strcmp(optarg, "JC69") == 0) { io->datatype = NT; io->mod->whichmodel = JC69; } else if(strcmp(optarg, "K80") == 0) { io->datatype = NT; io->mod->whichmodel = K80; } else if(strcmp(optarg, "F81") == 0) { io->datatype = NT; io->mod->whichmodel = F81; } else if (strcmp(optarg, "HKY85") == 0) { io->datatype = NT; io->mod->whichmodel = HKY85; } else if(strcmp(optarg, "F84") == 0) { io->datatype = NT; io->mod->whichmodel = F84; } else if (strcmp (optarg,"TN93") == 0) { io->datatype = NT; io->mod->whichmodel = TN93; } else if(strcmp (optarg, "GTR") == 0) { io->datatype = NT; io->mod->whichmodel = GTR; } else if(strcmp(optarg, "DAYHOFF") == 0) { io->datatype = AA; io->mod->whichmodel = DAYHOFF; } else if(strcmp (optarg, "JTT") == 0) { io->datatype = AA; io->mod->whichmodel = JTT; } else if(strcmp(optarg, "MTREV") == 0) { io->datatype = AA; io->mod->whichmodel = MTREV; } else if(strcmp (optarg, "LG") == 0) { io->datatype = AA; io->mod->whichmodel = LG; } else if(strcmp (optarg, "WAG") == 0) { io->datatype = AA; io->mod->whichmodel = WAG; } else if(strcmp(optarg, "DCMUT") == 0) { io->datatype = AA; io->mod->whichmodel = DCMUT; } else if(strcmp (optarg, "RTREV") == 0) { io->datatype = AA; io->mod->whichmodel = RTREV; } else if(strcmp(optarg, "CPREV") == 0) { io->datatype = AA; io->mod->whichmodel = CPREV; } else if(strcmp(optarg, "VT") == 0) { io->datatype = AA; io->mod->whichmodel = VT; } else if(strcmp(optarg, "BLOSUM62") == 0) { io->datatype = AA; io->mod->whichmodel = BLOSUM62; } else if(strcmp(optarg, "MTMAM") == 0) { io->datatype = AA; io->mod->whichmodel = MTMAM; } else if (strcmp(optarg,"MTART") == 0) { io->datatype = AA; io->mod->whichmodel = MTART; } else if (strcmp(optarg,"HIVW") == 0) { io->datatype = AA; io->mod->whichmodel = HIVW; } else if(strcmp(optarg, "HIVB") == 0) { io->datatype = AA; io->mod->whichmodel = HIVB; } else if(strcmp(optarg, "AB") == 0) { io->datatype = AA; io->mod->whichmodel = AB; } else if (strcmp(optarg, "CUSTOM") == 0) { io->datatype = AA; io->mod->whichmodel = CUSTOMAA; } else { PhyML_Printf("\n. The model name is incorrect. Please see the documentation.\n"); Exit("\n"); } Set_Model_Name(io->mod); break; } case 'a':case 14 : { if ((strcmp (optarg, "e") == 0) || (strcmp (optarg, "E") == 0) || (strcmp (optarg, "estimated") == 0) || (strcmp (optarg, "ESTIMATED") == 0)) { io->mod->s_opt->opt_alpha = YES; } else if (atof(optarg) < 1.E-10) { char choix; PhyML_Printf("\n. Alpha must be > 1.E-10.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { io->mod->ras->alpha->v = (phydbl)atof(optarg); io->mod->s_opt->opt_alpha = 0; } break; } case 'b':case 10: { if ((int)String_To_Dbl(optarg) < -5) { char choix; PhyML_Printf("\n. Branch test value must be a positive integer for bootstrap, or between -1 and -4 for aLRT branch test\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { if((int)String_To_Dbl(optarg) > 0) { io->ratio_test = 0; io->mod->bootstrap = (int)atoi(optarg); io->print_boot_trees = 1; if(io->n_data_sets > 1) { char choix; PhyML_Printf("\n. Bootstrap option is not allowed with multiple data sets\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } } else if (atoi(optarg)==0) { io->mod->bootstrap = 0; io->ratio_test = 0; } else { io->mod->bootstrap = 0; io->ratio_test = -(int)atoi(optarg); } } break; } case 'c':case 12: { if ((!atoi(optarg)) || (atoi(optarg) < 0)) { char choix; PhyML_Printf("\n. Unknown argument to -c option: the number of rate categories must be a positive integer\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { io->mod->ras->n_catg = atoi(optarg); if(io->mod->ras->n_catg < 1) { PhyML_Printf("\n. The number of rate categories must be a positive integer\n"); Exit("\n"); } } break; } case 'f': { if(!strcmp(optarg,"e")) { if(io->datatype == NT) io->mod->s_opt->opt_state_freq = NO; else if (io->datatype == AA) io->mod->s_opt->opt_state_freq = YES; else { PhyML_Printf("\n. Please define the data type (nt or aa) before setting the -f option\n"); Exit("\n"); } } else if(!strcmp(optarg,"m")) { if (io->datatype == NT) io->mod->s_opt->opt_state_freq = YES; else if (io->datatype == AA) io->mod->s_opt->opt_state_freq = NO; else { PhyML_Printf("\n. Please define the data type (nt or aa) before setting the -f option\n"); Exit("\n"); } } else if(!isalpha(optarg[0])) { phydbl sum; double val1,val2,val3,val4; io->mod->s_opt->opt_state_freq = 0; io->mod->s_opt->user_state_freq = 1; /* sscanf(optarg,"%lf,%lf,%lf,%lf", */ /* io->mod->user_b_freq, */ /* io->mod->user_b_freq+1, */ /* io->mod->user_b_freq+2, */ /* io->mod->user_b_freq+3); */ sscanf(optarg,"%lf,%lf,%lf,%lf",&val1,&val2,&val3,&val4); io->mod->user_b_freq->v[0] = (phydbl)val1; io->mod->user_b_freq->v[1] = (phydbl)val2; io->mod->user_b_freq->v[2] = (phydbl)val3; io->mod->user_b_freq->v[3] = (phydbl)val4; sum = (io->mod->user_b_freq->v[0] + io->mod->user_b_freq->v[1] + io->mod->user_b_freq->v[2] + io->mod->user_b_freq->v[3]); io->mod->user_b_freq->v[0] /= sum; io->mod->user_b_freq->v[1] /= sum; io->mod->user_b_freq->v[2] /= sum; io->mod->user_b_freq->v[3] /= sum; if(io->mod->user_b_freq->v[0] < .0 || io->mod->user_b_freq->v[1] < .0 || io->mod->user_b_freq->v[2] < .0 || io->mod->user_b_freq->v[3] < .0 || io->mod->user_b_freq->v[0] > 1. || io->mod->user_b_freq->v[1] > 1. || io->mod->user_b_freq->v[2] > 1. || io->mod->user_b_freq->v[3] > 1.) { Warn_And_Exit("\n. Invalid base frequencies.\n"); } } break; } case 'h':case 69: { Usage(); break; } case 'i':case 9: { char *tmp; tmp = (char *) mCalloc (T_MAX_FILE, sizeof(char)); if (strlen (optarg) > T_MAX_FILE -16) { char choix; strcpy (tmp, "\n. The file name'"); strcat (tmp, optarg); strcat (tmp, "' is too long.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else if (!Filexists (optarg)) { char choix; strcpy (tmp, "\n. The file '"); strcat (tmp, optarg); strcat (tmp, "' does not exist.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { strcpy(io->in_align_file, optarg); io->fp_in_align = Openfile(io->in_align_file,0); strcpy(io->out_file, optarg); strcpy(io->out_tree_file,optarg); #ifdef PHYML strcat(io->out_tree_file,"_phyml_tree"); #elif M4 strcat(io->out_tree_file,"_m4_tree"); #elif PHYREX strcat(io->out_tree_file,"_phyrex_tree"); #endif strcpy(io->out_stats_file,optarg); #ifdef PHYML strcat(io->out_stats_file,"_phyml_stats"); #elif M4 strcat(io->out_stats_file,"_m4_stats"); #elif PHYREX strcat(io->out_stats_file,"_phyrex_stats"); #endif #ifdef PHYREX strcpy(io->out_summary_file,optarg); strcat(io->out_summary_file,"_phyrex_summary"); #endif } Free (tmp); break; } case 't':case 11: { if ((io->mod->whichmodel != JC69) && (io->mod->whichmodel != F81) && (io->mod->whichmodel != GTR)) { if ((strcmp(optarg, "e") == 0) || (strcmp(optarg, "E") == 0) || (strcmp(optarg, "estimated") == 0) || (strcmp(optarg, "ESTIMATED") == 0)) { io->mod->kappa->v = 4.0; io->mod->s_opt->opt_kappa = YES; if (io->mod->whichmodel == TN93) io->mod->s_opt->opt_lambda = YES; } else { if (atof(optarg) < .0) { char choix; PhyML_Printf("\n. The ts/tv ratio must be a positive number\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { io->mod->kappa->v = (phydbl)atof(optarg); io->mod->s_opt->opt_kappa = 0; io->mod->s_opt->opt_lambda = 0; } } } break; } case 'n':case 8: { if ((!atoi(optarg)) || (atoi(optarg) < 0)) { char choix; PhyML_Printf("\n. The number of alignments must be a positive integer\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else io->n_data_sets = atoi (optarg); break; } case 'q':case 22: { io->interleaved = NO; break; } case 'u':case 15: { char *tmp; tmp = (char *)mCalloc(T_MAX_FILE, sizeof(char)); if(strlen(optarg) > T_MAX_FILE -11) { char choix; strcpy (tmp, "\n. The file name'"); strcat (tmp, optarg); strcat (tmp, "' is too long.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else if (! Filexists (optarg)) { char choix; strcpy (tmp, "\n. The file '"); strcat (tmp, optarg); strcat (tmp, "' doesn't exist.\n"); PhyML_Printf("%s",tmp); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { strcpy(io->in_tree_file, optarg); io->in_tree = 2; io->fp_in_tree = Openfile(io->in_tree_file,READ); } Free(tmp); break; } case 'v':case 13: { if ((strcmp (optarg, "e") == 0) || (strcmp (optarg, "E") == 0) || (strcmp (optarg, "estimated") == 0) || (strcmp (optarg, "ESTIMATED") == 0)) { io->mod->s_opt->opt_pinvar = YES; io->mod->ras->invar = YES; } else if ((atof(optarg) < 0.0) || (atof(optarg) > 1.0)) { char choix; PhyML_Printf("\n. The proportion of invariable site must be a number between 0.0 and 1.0\n"); PhyML_Printf("\n. Type any key to exit."); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } else { io->mod->ras->pinvar->v = (phydbl)atof(optarg); if (io->mod->ras->pinvar->v > 0.0+SMALL) io->mod->ras->invar = 1; else io->mod->ras->invar = 0; io->mod->s_opt->opt_pinvar = 0; } break; } case 'o': { if(!strcmp(optarg,"tlr")) { io->mod->s_opt->opt_topo = YES; io->mod->s_opt->opt_bl = YES; io->mod->s_opt->opt_subst_param = YES; } else if(!strcmp(optarg,"tl")) { io->mod->s_opt->opt_topo = YES; io->mod->s_opt->opt_bl = YES; io->mod->s_opt->opt_subst_param = NO; } else if(!strcmp(optarg,"t")) { Warn_And_Exit("\n. You can't optimize the topology without adjusting branch length too...\n"); } else if(!strcmp(optarg,"lr")) { io->mod->s_opt->opt_topo = NO; io->mod->s_opt->opt_bl = YES; io->mod->s_opt->opt_subst_param = YES; } else if(!strcmp(optarg,"l")) { io->mod->s_opt->opt_topo = NO; io->mod->s_opt->opt_bl = YES; io->mod->s_opt->opt_subst_param = NO; } else if(!strcmp(optarg,"r")) { io->mod->s_opt->opt_topo = NO; io->mod->s_opt->opt_bl = NO; io->mod->s_opt->opt_subst_param = YES; } else if(!strcmp(optarg,"none") || !strcmp(optarg,"n")) { io->mod->s_opt->opt_topo = NO; io->mod->s_opt->opt_bl = NO; io->mod->s_opt->opt_subst_param = NO; } else { char choix; PhyML_Printf ("\n. The optimization parameter must be 'tlr' or 'tl' or 'lr' or 'l' or 'r' or ''."); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } break; } case '?': { Exit("\n"); break; } case -1: { break; } default: { Usage(); break; } } }while(c != -1); /* if((io->mod->whichmodel == K80) || (io->mod->whichmodel == JC69)) */ /* { */ /* if(io->mod->s_opt->opt_state_freq) */ /* { */ /* char c; */ /* PhyML_Printf("\n. WARNING: nucleotide frequencies must be set to 1/4 with this model.\n"); */ /* PhyML_Printf("\n. Type the enter key to resume the analysis.\n"); */ /* scanf("%c",&c); */ /* } */ /* io->mod->s_opt->opt_state_freq = 0; */ /* } */ if(io->mod->s_opt->constrained_br_len == YES) { io->mod->s_opt->opt_topo = NO; /* io->mod->s_opt->opt_bl = NO; */ } #ifndef PHYML if((open_ps_file) || (io->m4_model == YES)) { strcpy(io->out_ps_file,io->in_align_file); strcat(io->out_ps_file, "_mc_tree.ps"); io->fp_out_ps = Openfile(io->out_ps_file,WRITE); } #endif if(io->datatype == UNDEFINED) io->datatype = NT; if((io->mod->s_opt->n_rand_starts) && (io->mod->s_opt->topo_search == NNI_MOVE) && (io->mod->s_opt->random_input_tree)) { Warn_And_Exit("\n== The random starting tree option is only compatible with SPR based search options.\n"); } if ((io->datatype == NT) && (io->mod->whichmodel > 10)) { char choix; PhyML_Printf("\n== Err.: model incompatible with the data type. Please use JC69, K80, F81, HKY, F84, TN93 or GTR\n"); PhyML_Printf("\n== Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Warn_And_Exit("\n"); } else if ((io->datatype == AA) && (io->mod->whichmodel < 11)) { char choix; PhyML_Printf("\n== Err.: model incompatible with the data type. Please use LG, Dayhoff, JTT, MtREV, WAG, DCMut, RtREV, CpREV, VT, Blosum62, MtMam, MtArt, HIVw, HIVb or AB.\n"); PhyML_Printf("\n== Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } if(io->mod->use_m4mod == NO) { io->mod->s_opt->opt_cov_delta = 0; io->mod->s_opt->opt_cov_alpha = 0; io->mod->s_opt->opt_cov_free_rates = 0; } if((io->mod->s_opt->opt_cov_free_rates) && (io->mod->s_opt->opt_cov_alpha)) { io->mod->s_opt->opt_cov_free_rates = 1; io->mod->m4mod->use_cov_alpha = 0; io->mod->m4mod->use_cov_free = 1; } if(io->print_site_lnl) { strcpy(io->out_lk_file,io->in_align_file); strcat(io->out_lk_file, "_phyml_lk"); if(io->append_run_ID) { strcat(io->out_lk_file,"_"); strcat(io->out_lk_file,io->run_id_string); } io->fp_out_lk = Openfile(io->out_lk_file,1); } if(io->print_trace) { strcpy(io->out_trace_file,io->in_align_file); strcat(io->out_trace_file,"_phyml_trace"); if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); } io->fp_out_trace = Openfile(io->out_trace_file,1); } if(io->mod->s_opt->random_input_tree) { strcpy(io->out_trees_file,io->in_align_file); strcat(io->out_trees_file,"_phyml_rand_trees"); if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); } io->fp_out_trees = Openfile(io->out_trees_file,1); } if((io->print_boot_trees) && (io->mod->bootstrap > 0)) { strcpy(io->out_boot_tree_file,io->in_align_file); strcat(io->out_boot_tree_file,"_phyml_boot_trees"); if(io->append_run_ID) { strcat(io->out_boot_tree_file,"_"); strcat(io->out_boot_tree_file,io->run_id_string); } io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1); strcpy(io->out_boot_stats_file,io->in_align_file); strcat(io->out_boot_stats_file,"_phyml_boot_stats"); if(io->append_run_ID) { strcat(io->out_boot_stats_file,"_"); strcat(io->out_boot_stats_file,io->run_id_string); } io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1); } if(io->append_run_ID) { strcat(io->out_tree_file,"_"); strcat(io->out_stats_file,"_"); strcat(io->out_tree_file,io->run_id_string); strcat(io->out_stats_file,io->run_id_string); } if(io->mod->ras->n_catg == 1) io->mod->s_opt->opt_alpha = 0; if(!io->mod->s_opt->opt_subst_param) { io->mod->s_opt->opt_alpha = 0; io->mod->s_opt->opt_kappa = 0; io->mod->s_opt->opt_lambda = 0; io->mod->s_opt->opt_pinvar = 0; io->mod->s_opt->opt_rr = 0; } if(io->mod->whichmodel != K80 && io->mod->whichmodel != HKY85 && io->mod->whichmodel != F84 && io->mod->whichmodel != TN93) { io->mod->s_opt->opt_kappa = 0; } if(io->datatype == AA && io->mod->whichmodel == CUSTOMAA && !io->mod->fp_aa_rate_mat) { PhyML_Printf("\n== Custom model option with amino-acid requires you to specify a rate matrix file through the '--aa_rate_file' option.\n"); Exit("\n"); } #if !defined(PHYTIME) // Make sure you don't erase the input file... if(!strcmp(io->out_tree_file,io->in_align_file) || !strcmp(io->out_stats_file,io->in_align_file)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); writemode = WRITE; io->fp_out_tree = Openfile(io->out_tree_file,writemode); io->fp_out_stats = Openfile(io->out_stats_file,writemode); #endif #if defined(PHYREX) io->fp_out_summary = Openfile(io->out_summary_file,writemode); #endif writemode++; // just to silence a warning message at compilation if(io->mod->whichmodel == GTR) { /* Make_Custom_Model(io->mod); */ io->mod->s_opt->opt_rr = 1; } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/cl.h000066400000000000000000000011071263450375500142140ustar00rootroot00000000000000 /* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef CL_H #define CL_H #include #include #include "utilities.h" #include "help.h" #include "models.h" #include "free.h" #include "interface.h" #include "invitee.h" int Read_Command_Line(option *input, int argc, char **argv); #endif phyml-3.2.0/src/draw.c000066400000000000000000000460771263450375500145650ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "draw.h" void DR_Draw_Tree(char *file_name, t_tree *tree) { FILE *ps_tree; ps_tree = (FILE *)fopen(file_name,"w"); DR_Print_Postscript_Header(1,ps_tree); tree->ps_tree = DR_Make_Tdraw_Struct(tree); DR_Init_Tdraw_Struct(tree->ps_tree); DR_Get_Tree_Box_Width(tree->ps_tree,tree); Dist_To_Root(tree->n_root,tree); tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); DR_Get_X_Coord(NO,tree->ps_tree,tree); DR_Get_Y_Coord(NO,tree->ps_tree,tree); DR_Print_Tree_Postscript(1,NO,ps_tree,tree); DR_Print_Postscript_EOF(ps_tree); fclose(ps_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Tree_Coord(t_tree *tree) { DR_Init_Tdraw_Struct(tree->ps_tree); DR_Get_Tree_Box_Width(tree->ps_tree,tree); if(!tree->n_root) { PhyML_Printf("\n. Adding root before rendering the tree."); Add_Root(tree->a_edges[0],tree); } Dist_To_Root(tree->n_root,tree); tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); DR_Get_X_Coord(NO,tree->ps_tree,tree); DR_Get_Y_Coord(NO,tree->ps_tree,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Print_Postscript_Header(int n_pages, FILE *fp) { if(!fp) { PhyML_Printf("\n== Failed to open the postscript file."); PhyML_Printf("\n== Did you forget the '--ps' option ?."); Exit("\n"); } PhyML_Fprintf(fp,"%%!PS-Adobe-3.0\n"); PhyML_Fprintf(fp,"%%%%BoundingBox: 0 0 595.28 841.89\n"); PhyML_Fprintf(fp,"%%%%DocumentFonts: Times-Roman Times-Roman\n"); PhyML_Fprintf(fp,"%%%%Creator: Stephane Guindon\n"); PhyML_Fprintf(fp,"%%%%Title: tree\n"); PhyML_Fprintf(fp,"%%%%EndComments\n"); PhyML_Fprintf(fp,"%%%%Pages: %d\n",n_pages); PhyML_Fprintf(fp,"/lt {lineto} bind def\n"); PhyML_Fprintf(fp,"/mt {moveto} bind def\n"); PhyML_Fprintf(fp,"/sc {setrgbcolor} bind def\n"); PhyML_Fprintf(fp,"/ct {curveto} bind def\n"); PhyML_Fprintf(fp,"/np {newpath} bind def\n"); PhyML_Fprintf(fp,"/cp {closepath} bind def\n"); PhyML_Fprintf(fp,"/gs {gsave} bind def\n"); PhyML_Fprintf(fp,"/gr {grestore} bind def\n"); PhyML_Fprintf(fp,"/Times-Roman findfont\n"); PhyML_Fprintf(fp,"12 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"/clipbox\n"); PhyML_Fprintf(fp,"{\n"); PhyML_Fprintf(fp,"newpath\n"); PhyML_Fprintf(fp,"20 20 mt\n"); PhyML_Fprintf(fp,"580 20 lt\n"); PhyML_Fprintf(fp,"580 820 lt\n"); PhyML_Fprintf(fp,"20 820 lt\n"); PhyML_Fprintf(fp,"20 20 lt\n"); PhyML_Fprintf(fp,"closepath\n"); PhyML_Fprintf(fp,"clip\n"); PhyML_Fprintf(fp,"} bind def\n"); /* PhyML_Fprintf(fp,"gs\n"); */ /* PhyML_Fprintf(fp,"newpath\n"); */ /* PhyML_Fprintf(fp,"20 20 mt\n"); */ /* PhyML_Fprintf(fp,"580 20 lt\n"); */ /* PhyML_Fprintf(fp,"580 820 lt\n"); */ /* PhyML_Fprintf(fp,"20 820 lt\n"); */ /* PhyML_Fprintf(fp,"20 20 lt\n"); */ /* PhyML_Fprintf(fp,"closepath\n"); */ /* PhyML_Fprintf(fp,"stroke\n"); */ /* PhyML_Fprintf(fp,"gr\n"); */ /* PhyML_Fprintf(fp,"0 0 0 sc\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Print_Postscript_EOF(FILE *fp) { PhyML_Fprintf(fp,"%%%%Trailer\n"); PhyML_Fprintf(fp,"%%%%EOF\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Print_Tree_Postscript(int page_num, int render_name, FILE *fp, t_tree *tree) { tdraw *draw; t_node *n_root; draw = tree->ps_tree; /* DR_Get_Tree_Coord(tree); */ n_root = tree->n_root; /* PhyML_Fprintf(fp,"%%%%Page: %d %d\n",page_num,page_num); */ /* PhyML_Fprintf(fp,"0.001 setlinewidth\n"); */ /* PhyML_Fprintf(fp,"0.5 0.5 0.4 sc\n"); */ /* PhyML_Fprintf(fp,"0 0 0 sc\n"); */ /* PhyML_Fprintf(fp,"clipbox\n"); */ /* PhyML_Fprintf(fp,"stroke\n"); */ PhyML_Fprintf(fp,"20 20 translate\n"); PhyML_Fprintf(fp,"newpath\n"); draw->ycoord[n_root->num] = (draw->ycoord[n_root->v[2]->num] + draw->ycoord[n_root->v[1]->num])/2. + 20; draw->xcoord[n_root->num] = 0.0; DR_Print_Tree_Postscript_Pre(n_root,n_root->v[2],n_root->b[2],render_name,fp,draw,tree); DR_Print_Tree_Postscript_Pre(n_root,n_root->v[1],n_root->b[1],render_name,fp,draw,tree); PhyML_Fprintf(fp,"closepath\n"); PhyML_Fprintf(fp,"0 0 translate\n"); PhyML_Fprintf(fp,"stroke\n"); PhyML_Fprintf(fp,"showpage\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Print_Tree_Postscript_Pre(t_node *a, t_node *d, t_edge *b, int render_name, FILE *fp, tdraw *w, t_tree *tree) { int i; phydbl R, G, B; R = G = B = 0.0; PhyML_Fprintf(fp,"gs\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[a->num],w->ycoord[a->num]); /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[a->num],w->ycoord[d->num]); */ /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]); */ phydbl min,max,step,val; min = 0.0; max = 5.; step = (max-min)/13.; /* val = tree->rates->mean_r[d->num] / (phydbl)(tree->mcmc->run/tree->mcmc->sample_interval+1.); */ /* val = tree->rates->mean_r[d->num]; */ /* val = tree->rates->has_survived[d->num]; */ /* if(val > 0.5) {R=1.; G=.0; B=0.;} */ /* val = tree->geo->ldscape[tree->geo->idx_loc[d->num]*tree->geo->n_dim+0] + 2.5; */ val = tree->geo->coord_loc[tree->geo->idx_loc[d->num]]->lonlat[0] + 2.5; /* val = 0.; */ if(val <= min+1.*step) {R=.0; G=1.; B=1.;} else if(val > min+1.*step && val <= min+2.*step) {R=.0; G=1.; B=.8;} else if(val > min+2.*step && val <= min+3.*step) {R=.0; G=1.; B=.5;} else if(val > min+3.*step && val <= min+4.*step) {R=.0; G=1.; B=.3;} else if(val > min+4.*step && val <= min+5.*step) {R=.0; G=1.; B=.0;} else if(val > min+5.*step && val <= min+6.*step) {R=.25; G=1.; B=0.;} else if(val > min+6.*step && val <= min+7.*step) {R=.5; G=1.; B=0.;} else if(val > min+7.*step && val <= min+8.*step) {R=.75; G=1.; B=.0;} else if(val > min+8.*step && val <= min+9.*step) {R=1.; G=1.; B=.0;} else if(val > min+9.*step && val <= min+10.*step) {R=1.; G=.75; B=.0;} else if(val > min+10.*step && val <= min+11.*step) {R=1.; G=.5; B=.0;} else if(val > min+11.*step && val <= min+12.*step) {R=1.; G=.25; B=.0;} else if(val > min+12.*step) {R=1.; G=.0; B=0.;} /* R = 0.; G = 0.; B = 0.; */ PhyML_Fprintf(fp,"2 setlinewidth\n"); /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[a->num],w->ycoord[d->num]); */ /* PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]); */ phydbl xa = w->xcoord[a->num]; phydbl xd = MIN(w->xcoord[a->num] + 5,w->xcoord[d->num]); phydbl ya = w->ycoord[a->num]; phydbl yd = w->ycoord[d->num]; PhyML_Fprintf(fp,"%.1f %.1f %.1f %.1f %.1f %.1f ct\n", xa + (xd-xa)/2.,(ya+yd)/2., xd - (xd-xa)/5.,yd, xd,yd); PhyML_Fprintf(fp,"%.1f %.1f lt\n",w->xcoord[d->num],w->ycoord[d->num]); /* PhyML_Fprintf(fp,"%.1f %.1f %.1f %.1f %.1f %.1f ct\n", */ /* w->xcoord[a->num], */ /* w->ycoord[d->num], */ /* w->xcoord[d->num], */ /* w->ycoord[d->num], */ /* w->xcoord[d->num], */ /* w->ycoord[d->num]); */ if(tree->rates && tree->rates->has_survived[d->num] == YES) { PhyML_Fprintf(fp," /Helvetica findfont 16 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]-5,w->ycoord[d->num]); PhyML_Fprintf(fp,"0 0 0 sc\n"); PhyML_Fprintf(fp,"(*) show \n"); } PhyML_Fprintf(fp,"%f %f %f sc\n",R,G,B); if(d->tax) { PhyML_Fprintf(fp,"stroke\n"); PhyML_Fprintf(fp,"0 setgray\n"); PhyML_Fprintf(fp,"2 setlinewidth\n"); PhyML_Fprintf(fp,"np %.1f %.1f 1 0 360 arc cp\n",w->xcoord[d->num],w->ycoord[d->num]); PhyML_Fprintf(fp,"%.1f %.1f %.1f sc fill\n",R,G,B); /* PhyML_Fprintf(fp,"%f setgray fill\n",greylevel); */ PhyML_Fprintf(fp,"0 0 0 sc\n"); PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+2,w->ycoord[d->num]-6); /* PhyML_Fprintf(fp,"(%d) show \n",d->num); */ /* PhyML_Fprintf(fp,"(%s) show \n",d->name); */ PhyML_Fprintf(fp," /Helvetica findfont 14 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num] - (w->xcoord[d->num] - w->xcoord[a->num])/2.,w->ycoord[d->num]); PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); #if (defined GEO) /* PhyML_Fprintf(fp,"([%4.4f,%4.4f]) show \n", */ /* tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+0], */ /* tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+1]); */ #endif /* PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+5,w->ycoord[d->num]); */ /* PhyML_Fprintf(fp,"(%.10s) show \n",d->name); */ /* if(render_name) */ /* { */ /* if(tree->io->long_tax_names) */ /* PhyML_Fprintf(fp,"(%s) show \n",tree->io->long_tax_names[d->num]); */ /* else */ /* PhyML_Fprintf(fp,"(%s) show \n",d->name); */ /* } */ PhyML_Fprintf(fp,"stroke\n"); PhyML_Fprintf(fp,"gr\n"); PhyML_Fprintf(fp,"0 0 0 sc\n"); return; } else { PhyML_Fprintf(fp,"stroke\n"); PhyML_Fprintf(fp,"0 setgray\n"); PhyML_Fprintf(fp,"2 setlinewidth\n"); PhyML_Fprintf(fp,"np %.1f %.1f 1 0 360 arc cp\n",w->xcoord[d->num],w->ycoord[d->num]); PhyML_Fprintf(fp,"%.1f %.1f %.1f sc fill\n",R,G,B); /* PhyML_Fprintf(fp,"%f setgray fill\n",greylevel); */ PhyML_Fprintf(fp,"0 0 0 sc\n"); PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num]+2,w->ycoord[d->num]); /* PhyML_Fprintf(fp,"(%d) show \n",b->num); */ PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num],w->ycoord[d->num]); PhyML_Fprintf(fp," /Helvetica findfont 14 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); PhyML_Fprintf(fp,"%.1f %.1f mt\n",w->xcoord[d->num] - (w->xcoord[d->num] - w->xcoord[a->num])/2.,w->ycoord[d->num]); PhyML_Fprintf(fp," /Helvetica findfont 10 scalefont\n"); PhyML_Fprintf(fp,"setfont\n"); #if (defined GEO) /* PhyML_Fprintf(fp,"([%4.4f,%4.4f]) show \n", */ /* tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+0], */ /* tree->geo->ldscape[tree->geo->loc[d->num]*tree->geo->n_dim+1]); */ #endif PhyML_Fprintf(fp,"stroke\n"); PhyML_Fprintf(fp,"gr\n"); PhyML_Fprintf(fp,"0 0 0 sc\n"); For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) DR_Print_Tree_Postscript_Pre(d,d->v[i],d->b[i],render_name,fp,w,tree); } return; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_X_Coord_Pre(t_node *a, t_node *d, t_edge *b, tdraw *w, int fixed_tips, t_tree *tree) { int i; if(!(d->tax && fixed_tips == YES)) w->xcoord[d->num] = d->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root; if(d->tax) return; else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) DR_Get_X_Coord_Pre(d,d->v[i],d->b[i],w,fixed_tips,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_X_Coord(int fixed_tips, tdraw *w, t_tree *tree) { if(!(tree->n_root->v[2]->tax && fixed_tips == YES)) w->xcoord[tree->n_root->v[2]->num] = tree->n_root->v[2]->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root; if(!(tree->n_root->v[1]->tax && fixed_tips == YES)) w->xcoord[tree->n_root->v[1]->num] = tree->n_root->v[1]->dist_to_root * (phydbl)w->tree_box_width/w->max_dist_to_root; DR_Get_X_Coord_Pre(tree->n_root,tree->n_root->v[2],NULL,w,fixed_tips,tree); DR_Get_X_Coord_Pre(tree->n_root,tree->n_root->v[1],NULL,w,fixed_tips,tree); w->xcoord[tree->n_root->num] = 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Y_Coord(int fixed_tips, tdraw *w, t_tree *tree) { int next_y_slot; next_y_slot = 0; DR_Get_Y_Coord_Post(tree->n_root,tree->n_root->v[2],NULL,&next_y_slot,fixed_tips,w,tree); DR_Get_Y_Coord_Post(tree->n_root,tree->n_root->v[1],NULL,&next_y_slot,fixed_tips,w,tree); w->ycoord[tree->n_root->num] = (int)((w->ycoord[tree->n_root->v[2]->num] + w->ycoord[tree->n_root->v[2]->num]) / 2.) + 20; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Y_Coord_Post(t_node *a, t_node *d, t_edge *b, int *next_y_slot, int fixed_tips, tdraw *w, t_tree *tree) { int i; if(d->tax) { if(!fixed_tips) { /* w->ycoord[d->num] = *next_y_slot + (int)(w->page_height / (2.*tree->n_otu)); */ w->ycoord[d->num] = *next_y_slot + 20; (*next_y_slot) += (int)(w->page_height / (tree->n_otu-1)); printf("\n. %s %f",d->name,w->ycoord[d->num]); } } else { int d1, d2; d1 = d2 = -1; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { DR_Get_Y_Coord_Post(d,d->v[i],d->b[i],next_y_slot,fixed_tips,w,tree); if(d1<0) d1 = i; else d2 = i; } } w->ycoord[d->num] = (w->ycoord[d->v[d1]->num] + w->ycoord[d->v[d2]->num])/2.; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// tdraw *DR_Make_Tdraw_Struct(t_tree *tree) { tdraw *w; w = (tdraw *)mCalloc(1,sizeof(tdraw)); w->xcoord = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); w->ycoord = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); w->xcoord_s = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); w->ycoord_s = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); w->cdf_mat = (int *)mCalloc((2*tree->n_otu-2)*(2*tree->n_otu-2),sizeof(int)); w->cdf_mat_x = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); w->cdf_mat_y = (phydbl *)mCalloc(2*tree->n_otu-1,sizeof(phydbl)); return w; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Init_Tdraw_Struct(tdraw *w) { w->page_width = 580-20; w->page_height = 820-20; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Tree_Box_Width(tdraw *w, t_tree *tree) { int i; int max_name_len, curr_len; max_name_len = curr_len = 0; For(i,tree->n_otu) { curr_len = (int)strlen(tree->a_nodes[i]->name); if(curr_len > max_name_len) max_name_len = curr_len; } w->tree_box_width = w->page_width - max_name_len * 8.66667; /* w->tree_box_width = w->page_width - max_name_len * 10.; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl DR_Get_Max_Dist_To_Root(t_tree *tree) { phydbl mx; int i; mx = .0; For(i,tree->n_otu) { if(tree->a_nodes[i]->dist_to_root > mx) { mx = tree->a_nodes[i]->dist_to_root; } } return mx; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Tree_Coord_Scaled(tdraw *w, t_tree *tree) { int i; int max_x,min_x; int max_y,min_y; max_x = -INT_MAX; min_x = INT_MAX; For(i,2*tree->n_otu-1) { if(w->xcoord[i] > max_x) max_x = w->xcoord[i]; if(w->xcoord[i] < min_x) min_x = w->xcoord[i]; } max_y = -INT_MAX; min_y = INT_MAX; For(i,2*tree->n_otu-1) { if(w->ycoord[i] > max_y) max_y = w->ycoord[i]; if(w->ycoord[i] < min_y) min_y = w->ycoord[i]; } For(i,2*tree->n_otu-1) { w->xcoord_s[i] = (phydbl)(w->xcoord[i] - min_x) / (max_x - min_x); w->ycoord_s[i] = (phydbl)(w->ycoord[i] - min_y) / (max_y - min_y); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void DR_Get_Cdf_Mat(t_tree *tree) { int i,j,k; phydbl min_x,max_x,y; phydbl x_mat,y_mat; t_node *d, *a; phydbl eps; eps = 1.E-6; For(i,2*tree->n_otu-1) tree->ps_tree->cdf_mat_x[i] = tree->ps_tree->xcoord_s[i]; For(i,2*tree->n_otu-1) tree->ps_tree->cdf_mat_y[i] = tree->ps_tree->ycoord_s[i]; Qksort(tree->ps_tree->cdf_mat_x,NULL,0,2*tree->n_otu-2); Qksort(tree->ps_tree->cdf_mat_y,NULL,0,2*tree->n_otu-2); For(i,2*tree->n_otu-2) /* x coordinates */ { For(j,2*tree->n_otu-2) /* y coordinates */ { For(k,2*tree->n_otu-2) /* all nodes in the tree */ { d = tree->a_nodes[k]; a = tree->a_nodes[k]->anc; min_x = tree->ps_tree->xcoord_s[a->num]; max_x = tree->ps_tree->xcoord_s[d->num]; y = tree->ps_tree->ycoord_s[d->num]; x_mat = tree->ps_tree->cdf_mat_x[i]; y_mat = tree->ps_tree->cdf_mat_y[j]; /* printf("\n. x_mat=%.1f ymat=%.1f min=%.1f max=%.1f y=%.1f", */ /* x_mat,y_mat,min_x,max_x,y); */ if((min_x < x_mat + eps) && (max_x > x_mat) && (y > y_mat)) { tree->ps_tree->cdf_mat[j*(2*tree->n_otu-2)+i] += 1; /* PhyML_Printf("\n. Add 1 to [%.1f,%.1f]", */ /* tree->ps_tree->cdf_mat_x[i], */ /* tree->ps_tree->cdf_mat_y[j]); */ } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/draw.h000066400000000000000000000022641263450375500145600ustar00rootroot00000000000000#include #ifndef DRAW_H #define DRAW_H #include "utilities.h" void DR_Dist_To_Root_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void DR_Dist_To_Root(t_node *n_root, t_tree *tree); void DR_Get_X_Coord_Pre(t_node *a, t_node *d, t_edge *b, tdraw *w, int fixed_tips, t_tree *tree); void DR_Get_X_Coord(int fixed_tips, tdraw *w, t_tree *tree); tdraw *DR_Make_Tdraw_Struct(t_tree *tree); void DR_Init_Tdraw_Struct(tdraw *d); void DR_Get_Tree_Box_Width(tdraw *w, t_tree *tree); void DR_Get_Y_Coord_Post(t_node *a, t_node *d, t_edge *b, int *next_y_slot, int fixed_tips, tdraw *w, t_tree *tree); void DR_Get_Y_Coord(int fixed_tips, tdraw *w, t_tree *tree); void DR_Get_Tree_Coord(t_tree *tree); phydbl DR_Get_Max_Dist_To_Root(t_tree *tree); void DR_Print_Tree_Postscript(int tree_num, int render_name,FILE *fp, t_tree *tree); void DR_Print_Tree_Postscript_Pre(t_node *a, t_node *d, t_edge *b, int render_name, FILE *fp, tdraw *w, t_tree *tree); void DR_Print_Postscript_EOF(FILE *fp); void DR_Print_Postscript_Header(int n_pages, FILE *fp); void DR_Get_Tree_Coord_Scaled(tdraw *w, t_tree *tree); void DR_Get_Cdf_Mat(t_tree *tree); void DR_Draw_Tree(char *file_name, t_tree *tree); #endif phyml-3.2.0/src/eigen.c000066400000000000000000000634341263450375500147130ustar00rootroot00000000000000/*********************************************************** * This eigen() routine works for eigenvalue/vector analysis * for real general square matrix A * A will be destroyed * rr,ri are vectors containing eigenvalues * vr,vi are matrices containing (right) eigenvectors * * A*[vr+vi*i] = [vr+vi*i] * diag{rr+ri*i} * * Algorithm: Handbook for Automatic Computation, vol 2 * by Wilkinson and Reinsch, 1971 * most of source codes were taken from a public domain * solftware called MATCALC. * Credits: to the authors of MATCALC * * return -1 not converged * 0 no complex eigenvalues/vectors * 1 complex eigenvalues/vectors * Tianlin Wang at University of Illinois * Thu May 6 15:22:31 CDT 1993 ***************************************************************/ #include "eigen.h" #define BASE 2 /* base of floating point arithmetic */ /* no. of digits to the base BASE in the fraction */ #define DIGITS 40 /* #define DIGITS 53 */ #define MAXITER 30 /* max2. no. of iterations to converge */ #define pos(i,j,n) ((i)*(n)+(j)) /* rr/vr : real parts of eigen values/vectors */ /* ri/vi : imaginary part s of eigen values/vectors */ int Eigen(int job, phydbl *A, int n, phydbl *rr, phydbl *ri, phydbl *vr, phydbl *vi, phydbl *work) { /* job=0: eigen values only 1: both eigen values and eigen vectors phydbl w[n*2]: work space */ int low,hi,i,j,k, it, istate=0; phydbl tiny, t; /* tiny=SQRT(POW((phydbl)BASE,(phydbl)(1-(int)DIGITS))); */ tiny=FLT_MIN; balance(A,n,&low,&hi,work); elemhess(job,A,n,low,hi,vr,vi, (int*)(work+n)); if (-1 == realeig(job,A,n,low,hi,rr,ri,vr,vi)) return (-1); if (job) unbalance(n,vr,vi,low,hi,work); /* sort, added by Z. Yang */ for (i=0; itiny) istate=1; } return (istate) ; } /* complex funcctions */ complex compl (phydbl re,phydbl im) { complex r; r.re = re; r.im = im; return(r); } complex _conj (complex a) { a.im = -a.im; return(a); } complex cplus (complex a, complex b) { complex c; c.re = a.re+b.re; c.im = a.im+b.im; return (c); } complex cminus (complex a, complex b) { complex c; c.re = a.re-b.re; c.im = a.im-b.im; return (c); } complex cby (complex a, complex b) { complex c; c.re = a.re*b.re-a.im*b.im ; c.im = a.re*b.im+a.im*b.re ; return (c); } complex cdiv (complex a,complex b) { phydbl ratio, den; complex c; if (FABS(b.re) <= FABS(b.im)) { ratio = b.re / b.im; den = b.im * (1 + ratio * ratio); c.re = (a.re * ratio + a.im) / den; c.im = (a.im * ratio - a.re) / den; } else { ratio = b.im / b.re; den = b.re * (1 + ratio * ratio); c.re = (a.re + a.im * ratio) / den; c.im = (a.im - a.re * ratio) / den; } return(c); } /* complex local_cexp (complex a) */ /* { */ /* complex c; */ /* c.re = EXP(a.re); */ /* if (FABS(a.im)==0) c.im = 0; */ /* else { c.im = c.re*sin(a.im); c.re*=cos(a.im); } */ /* return (c); */ /* } */ complex cfactor (complex x, phydbl a) { complex c; c.re = a*x.re; c.im = a*x.im; return (c); } int cxtoy (complex *x, complex *y, int n) { int i; For (i,n) y[i]=x[i]; return (0); } int cmatby (complex *a, complex *b, complex *c, int n,int m,int k) /* a[n*m], b[m*k], c[n*k] ...... c = a*b */ { int i,j,i1; complex t; For (i,n) For(j,k) { for (i1=0,t=compl(0,0); i1=n */ int i,j,k, *irow=(int*) space; phydbl xmaxsize, ee=1e-20; complex t,t1; For(i,n) { xmaxsize = 0.; for (j=i; j=0; i--) { if (irow[i] == i) continue; For(j,n) { t = x[j*m+i]; x[j*m+i] = x[j*m+irow[i]]; x[ j*m+irow[i]] = t; } } return (0); } void balance(phydbl *mat, int n,int *low, int *hi, phydbl *scale) { /* Balance a matrix for calculation of eigenvalues and eigenvectors */ phydbl c,f,g,r,s; int i,j,k,l,done; /* search for rows isolating an eigenvalue and push them down */ for (k = n - 1; k >= 0; k--) { for (j = k; j >= 0; j--) { for (i = 0; i <= k; i++) { if (i != j && FABS(mat[pos(j,i,n)]) > SMALL) break; } if (i > k) { scale[k] = j; if (j != k) { for (i = 0; i <= k; i++) { c = mat[pos(i,j,n)]; mat[pos(i,j,n)] = mat[pos(i,k,n)]; mat[pos(i,k,n)] = c; } for (i = 0; i < n; i++) { c = mat[pos(j,i,n)]; mat[pos(j,i,n)] = mat[pos(k,i,n)]; mat[pos(k,i,n)] = c; } } break; } } if (j < 0) break; } /* search for columns isolating an eigenvalue and push them left */ for (l = 0; l <= k; l++) { for (j = l; j <= k; j++) { for (i = l; i <= k; i++) { if (i != j && FABS(mat[pos(i,j,n)]) > SMALL) break; } if (i > k) { scale[l] = j; if (j != l) { for (i = 0; i <= k; i++) { c = mat[pos(i,j,n)]; mat[pos(i,j,n)] = mat[pos(i,l,n)]; mat[pos(i,l,n)] = c; } for (i = l; i < n; i++) { c = mat[pos(j,i,n)]; mat[pos(j,i,n)] = mat[pos(l,i,n)]; mat[pos(l,i,n)] = c; } } break; } } if (j > k) break; } *hi = k; *low = l; /* balance the submatrix in rows l through k */ for (i = l; i <= k; i++) { scale[i] = 1; } do { for (done = 1,i = l; i <= k; i++) { for (c = 0,r = 0,j = l; j <= k; j++) { if (j != i) { c += FABS(mat[pos(j,i,n)]); r += FABS(mat[pos(i,j,n)]); } } /* if (c != 0 && r != 0) { */ if (FABS(c) > SMALL && FABS(r) > SMALL) { g = r / BASE; f = 1; s = c + r; while (c < g) { f *= BASE; c *= BASE * BASE; } g = r * BASE; while (c >= g) { f /= BASE; c /= BASE * BASE; } if ((c + r) / f < 0.95 * s) { done = 0; g = 1 / f; scale[i] *= f; for (j = l; j < n; j++) { mat[pos(i,j,n)] *= g; } for (j = 0; j <= k; j++) { mat[pos(j,i,n)] *= f; } } } } } while (!done); } /* * Transform back eigenvectors of a balanced matrix * into the eigenvectors of the original matrix */ void unbalance(int n,phydbl *vr,phydbl *vi, int low, int hi, phydbl *scale) { int i,j,k; phydbl tmp; for (i = low; i <= hi; i++) { for (j = 0; j < n; j++) { vr[pos(i,j,n)] *= scale[i]; vi[pos(i,j,n)] *= scale[i]; } } for (i = low - 1; i >= 0; i--) { if ((k = (int)scale[i]) != i) { for (j = 0; j < n; j++) { tmp = vr[pos(i,j,n)]; vr[pos(i,j,n)] = vr[pos(k,j,n)]; vr[pos(k,j,n)] = tmp; tmp = vi[pos(i,j,n)]; vi[pos(i,j,n)] = vi[pos(k,j,n)]; vi[pos(k,j,n)] = tmp; } } } for (i = hi + 1; i < n; i++) { if ((k = (int)scale[i]) != i) { for (j = 0; j < n; j++) { tmp = vr[pos(i,j,n)]; vr[pos(i,j,n)] = vr[pos(k,j,n)]; vr[pos(k,j,n)] = tmp; tmp = vi[pos(i,j,n)]; vi[pos(i,j,n)] = vi[pos(k,j,n)]; vi[pos(k,j,n)] = tmp; } } } } /* * Reduce the submatrix in rows and columns low through hi of real matrix mat to * Hessenberg form by elementary similarity transformations */ void elemhess(int job,phydbl *mat,int n,int low,int hi, phydbl *vr, phydbl *vi, int *work) { /* work[n] */ int i,j,m; phydbl x,y; for (m = low + 1; m < hi; m++) { for (x = 0,i = m,j = m; j <= hi; j++) { if (FABS(mat[pos(j,m-1,n)]) > FABS(x)) { x = mat[pos(j,m-1,n)]; i = j; } } if ((work[m] = i) != m) { for (j = m - 1; j < n; j++) { y = mat[pos(i,j,n)]; mat[pos(i,j,n)] = mat[pos(m,j,n)]; mat[pos(m,j,n)] = y; } for (j = 0; j <= hi; j++) { y = mat[pos(j,i,n)]; mat[pos(j,i,n)] = mat[pos(j,m,n)]; mat[pos(j,m,n)] = y; } } if (FABS(x) > SMALL) { for (i = m + 1; i <= hi; i++) { if (FABS(y = mat[pos(i,m-1,n)]) > SMALL) { y = mat[pos(i,m-1,n)] = y / x; for (j = m; j < n; j++) { mat[pos(i,j,n)] -= y * mat[pos(m,j,n)]; } for (j = 0; j <= hi; j++) { mat[pos(j,m,n)] += y * mat[pos(j,i,n)]; } } } } } if (job) { for (i=0; i low; m--) { for (i = m + 1; i <= hi; i++) { vr[pos(i,m,n)] = mat[pos(i,m-1,n)]; } if ((i = work[m]) != m) { for (j = m; j <= hi; j++) { vr[pos(m,j,n)] = vr[pos(i,j,n)]; vr[pos(i,j,n)] = 0.0; } vr[pos(i,m,n)] = 1.0; } } } } /* * Calculate eigenvalues and eigenvectors of a real upper Hessenberg matrix * Return 1 if converges successfully and 0 otherwise */ int realeig(int job,phydbl *mat,int n,int low, int hi, phydbl *valr, phydbl *vali, phydbl *vr,phydbl *vi) { complex v; phydbl p=.0,q=.0,r=.0,s=.0,t,w,x,y,z=0,ra,sa,norm,eps; int niter,en,i,j,k,l,m; phydbl precision = POW((phydbl)BASE,(phydbl)(1-(int)DIGITS)); eps = precision; for (i=0; i hi) valr[i] = mat[pos(i,i,n)]; } t = 0; en = hi; while (en >= low) { niter = 0; for (;;) { /* look for single small subdiagonal element */ for (l = en; l > low; l--) { s = FABS(mat[pos(l-1,l-1,n)]) + FABS(mat[pos(l,l,n)]); if (FABS(s) < SMALL) s = norm; if (FABS(mat[pos(l,l-1,n)]) <= eps * s) break; } /* form shift */ x = mat[pos(en,en,n)]; if (l == en) { /* one root found */ valr[en] = x + t; if (job) mat[pos(en,en,n)] = x + t; en--; break; } y = mat[pos(en-1,en-1,n)]; w = mat[pos(en,en-1,n)] * mat[pos(en-1,en,n)]; if (l == en - 1) { /* two roots found */ p = (y - x) / 2; q = p * p + w; z = SQRT(FABS(q)); x += t; if (job) { mat[pos(en,en,n)] = x; mat[pos(en-1,en-1,n)] = y + t; } if (q < 0) { /* complex pair */ valr[en-1] = x+p; vali[en-1] = z; valr[en] = x+p; vali[en] = -z; } else { /* real pair */ z = (p < 0) ? p - z : p + z; valr[en-1] = x + z; valr[en] = (FABS(z) < SMALL) ? x + z : x - w / z; if (job) { x = mat[pos(en,en-1,n)]; s = FABS(x) + FABS(z); p = x / s; q = z / s; r = SQRT(p*p+q*q); p /= r; q /= r; for (j = en - 1; j < n; j++) { z = mat[pos(en-1,j,n)]; mat[pos(en-1,j,n)] = q * z + p * mat[pos(en,j,n)]; mat[pos(en,j,n)] = q * mat[pos(en,j,n)] - p*z; } for (i = 0; i <= en; i++) { z = mat[pos(i,en-1,n)]; mat[pos(i,en-1,n)] = q * z + p * mat[pos(i,en,n)]; mat[pos(i,en,n)] = q * mat[pos(i,en,n)] - p*z; } for (i = low; i <= hi; i++) { z = vr[pos(i,en-1,n)]; vr[pos(i,en-1,n)] = q*z + p*vr[pos(i,en,n)]; vr[pos(i,en,n)] = q*vr[pos(i,en,n)] - p*z; } } } en -= 2; break; } if (niter == MAXITER) return(-1); if (niter != 0 && niter % 10 == 0) { t += x; for (i = low; i <= en; i++) mat[pos(i,i,n)] -= x; s = FABS(mat[pos(en,en-1,n)]) + FABS(mat[pos(en-1,en-2,n)]); x = y = 0.75 * s; w = -0.4375 * s * s; } niter++; /* look for two consecutive small subdiagonal elements */ for (m = en - 2; m >= l; m--) { z = mat[pos(m,m,n)]; r = x - z; s = y - z; p = (r * s - w) / mat[pos(m+1,m,n)] + mat[pos(m,m+1,n)]; q = mat[pos(m+1,m+1,n)] - z - r - s; r = mat[pos(m+2,m+1,n)]; s = FABS(p) + FABS(q) + FABS(r); p /= s; q /= s; r /= s; if (m == l || FABS(mat[pos(m,m-1,n)]) * (FABS(q)+FABS(r)) <= eps * (FABS(mat[pos(m-1,m-1,n)]) + FABS(z) + FABS(mat[pos(m+1,m+1,n)])) * FABS(p)) break; } for (i = m + 2; i <= en; i++) mat[pos(i,i-2,n)] = 0; for (i = m + 3; i <= en; i++) mat[pos(i,i-3,n)] = 0; /* phydbl QR step involving rows l to en and columns m to en */ for (k = m; k < en; k++) { if (k != m) { p = mat[pos(k,k-1,n)]; q = mat[pos(k+1,k-1,n)]; r = (k == en - 1) ? 0 : mat[pos(k+2,k-1,n)]; if (FABS(x = FABS(p) + FABS(q) + FABS(r)) < SMALL) continue; p /= x; q /= x; r /= x; } s = SQRT(p*p+q*q+r*r); if (p < 0) s = -s; if (k != m) { mat[pos(k,k-1,n)] = -s * x; } else if (l != m) { mat[pos(k,k-1,n)] = -mat[pos(k,k-1,n)]; } p += s; x = p / s; y = q / s; z = r / s; q /= p; r /= p; /* row modification */ for (j = k; j <= (!job ? en : n-1); j++){ p = mat[pos(k,j,n)] + q * mat[pos(k+1,j,n)]; if (k != en - 1) { p += r * mat[pos(k+2,j,n)]; mat[pos(k+2,j,n)] -= p * z; } mat[pos(k+1,j,n)] -= p * y; mat[pos(k,j,n)] -= p * x; } j = MIN(en,k+3); /* column modification */ for (i = (!job ? l : 0); i <= j; i++) { p = x * mat[pos(i,k,n)] + y * mat[pos(i,k+1,n)]; if (k != en - 1) { p += z * mat[pos(i,k+2,n)]; mat[pos(i,k+2,n)] -= p*r; } mat[pos(i,k+1,n)] -= p*q; mat[pos(i,k,n)] -= p; } if (job) { /* accumulate transformations */ for (i = low; i <= hi; i++) { p = x * vr[pos(i,k,n)] + y * vr[pos(i,k+1,n)]; if (k != en - 1) { p += z * vr[pos(i,k+2,n)]; vr[pos(i,k+2,n)] -= p*r; } vr[pos(i,k+1,n)] -= p*q; vr[pos(i,k,n)] -= p; } } } } } if (!job) return(0); if (FABS(norm) > SMALL) { /* back substitute to find vectors of upper triangular form */ for (en = n-1; en >= 0; en--) { p = valr[en]; if ((q = vali[en]) < 0) { /* complex vector */ m = en - 1; if (FABS(mat[pos(en,en-1,n)]) > FABS(mat[pos(en-1,en,n)])) { mat[pos(en-1,en-1,n)] = q / mat[pos(en,en-1,n)]; mat[pos(en-1,en,n)] = (p - mat[pos(en,en,n)]) / mat[pos(en,en-1,n)]; } else { v = cdiv(compl(0.0,-mat[pos(en-1,en,n)]), compl(mat[pos(en-1,en-1,n)]-p,q)); mat[pos(en-1,en-1,n)] = v.re; mat[pos(en-1,en,n)] = v.im; } mat[pos(en,en-1,n)] = 0; mat[pos(en,en,n)] = 1; for (i = en - 2; i >= 0; i--) { w = mat[pos(i,i,n)] - p; ra = 0; sa = mat[pos(i,en,n)]; for (j = m; j < en; j++) { ra += mat[pos(i,j,n)] * mat[pos(j,en-1,n)]; sa += mat[pos(i,j,n)] * mat[pos(j,en,n)]; } if (vali[i] < 0) { z = w; r = ra; s = sa; } else { m = i; if (FABS(vali[i]) < SMALL) { v = cdiv(compl(-ra,-sa),compl(w,q)); mat[pos(i,en-1,n)] = v.re; mat[pos(i,en,n)] = v.im; } else { /* solve complex equations */ x = mat[pos(i,i+1,n)]; y = mat[pos(i+1,i,n)]; v.re = (valr[i]- p)*(valr[i]-p) + vali[i]*vali[i] - q*q; v.im = (valr[i] - p)*2*q; if (FABS(v.re) + FABS(v.im) < SMALL) { v.re = eps * norm * (FABS(w) + FABS(q) + FABS(x) + FABS(y) + FABS(z)); } v = cdiv(compl(x*r-z*ra+q*sa,x*s-z*sa-q*ra),v); mat[pos(i,en-1,n)] = v.re; mat[pos(i,en,n)] = v.im; if (FABS(x) > FABS(z) + FABS(q)) { mat[pos(i+1,en-1,n)] = (-ra - w * mat[pos(i,en-1,n)] + q * mat[pos(i,en,n)]) / x; mat[pos(i+1,en,n)] = (-sa - w * mat[pos(i,en,n)] - q * mat[pos(i,en-1,n)]) / x; } else { v = cdiv(compl(-r-y*mat[pos(i,en-1,n)], -s-y*mat[pos(i,en,n)]),compl(z,q)); mat[pos(i+1,en-1,n)] = v.re; mat[pos(i+1,en,n)] = v.im; } } } } } else if (FABS(q) < SMALL) { /* real vector */ m = en; mat[pos(en,en,n)] = 1; for (i = en - 1; i >= 0; i--) { w = mat[pos(i,i,n)] - p; r = mat[pos(i,en,n)]; for (j = m; j < en; j++) { r += mat[pos(i,j,n)] * mat[pos(j,en,n)]; } if (vali[i] < 0) { z = w; s = r; } else { m = i; if (FABS(vali[i]) < SMALL) { if (FABS(t = w) < SMALL) t = eps * norm; mat[pos(i,en,n)] = -r / t; } else { /* solve real equations */ x = mat[pos(i,i+1,n)]; y = mat[pos(i+1,i,n)]; q = (valr[i] - p) * (valr[i] - p) + vali[i]*vali[i]; t = (x * s - z * r) / q; mat[pos(i,en,n)] = t; if (FABS(x) <= FABS(z)) { mat[pos(i+1,en,n)] = (-s - y * t) / z; } else { mat[pos(i+1,en,n)] = (-r - w * t) / x; } } } } } } /* vectors of isolated roots */ for (i = 0; i < n; i++) { if (i < low || i > hi) { for (j = i; j < n; j++) { vr[pos(i,j,n)] = mat[pos(i,j,n)]; } } } /* multiply by transformation matrix */ for (j = n-1; j >= low; j--) { m = MIN(j,hi); for (i = low; i <= hi; i++) { for (z = 0,k = low; k <= m; k++) { z += vr[pos(i,k,n)] * mat[pos(k,j,n)]; } vr[pos(i,j,n)] = z; } } } /* rearrange complex eigenvectors */ for (j = 0; j < n; j++) { if (FABS(vali[j]) > SMALL) { for (i = 0; i < n; i++) { vi[pos(i,j,n)] = vr[pos(i,j+1,n)]; vr[pos(i,j+1,n)] = vr[pos(i,j,n)]; vi[pos(i,j+1,n)] = -vi[pos(i,j,n)]; } j++; } } return(0); } #define LUDCMP_TINY 1.0e-20; int ludcmp(phydbl **a, int n, phydbl *d) { int i,imax,j,k; phydbl big,dum,sum,temp; phydbl *vv; imax = 0; vv = (phydbl *)mCalloc(n,sizeof(phydbl)); *d=1.0; for (i=0;i big) big=temp; if (FABS(big) < SMALL) Exit("\n. Singular matrix in routine LUDCMP"); vv[i]=1.0/big; } for (j=0;j= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k big) big=temp; if (FABS(big) < SMALL) Exit("\n. Singular matrix in routine LUDCMP"); vv[i]=1.0/big; } for (j=0;j= big) { big=dum; imax=i; } } if (j != imax) { for (k=0;k #ifndef EIGEN_H #define EIGEN_H #include "utilities.h" #include "free.h" #ifdef RWRAPPER #include #endif int ludcmp_1D(phydbl *a, int n, phydbl *d); void det_1D(phydbl *a, int n, phydbl *d); int Eigen(int job, phydbl *A, int n, phydbl *rr, phydbl *ri, phydbl *vr, phydbl *vi, phydbl *w); void balance(phydbl *mat, int n, int *low, int *hi, phydbl *scale); void unbalance(int n, phydbl *vr, phydbl *vi, int low, int hi, phydbl *scale); int realeig(int job, phydbl *mat, int n,int low, int hi, phydbl *valr, phydbl *vali, phydbl *vr, phydbl *vi); void elemhess(int job, phydbl *mat, int n, int low, int hi, phydbl *vr, phydbl *vi, int *work); int ludcmp(phydbl **a, int n, phydbl *d); void det(phydbl **a, int n, phydbl *d); /* complex functions */ typedef struct { phydbl re, im; } complex; #define csize(a) (FABS(a.re)+FABS(a.im)) complex compl (phydbl re,phydbl im); complex _conj (complex a); complex cplus (complex a, complex b); complex cminus (complex a, complex b); complex cby (complex a, complex b); complex cdiv (complex a,complex b); /* complex local_cexp (complex a); */ complex cfactor (complex x, phydbl a); int cxtoy (complex *x, complex *y, int n); int cmatby (complex *a, complex *b, complex *c, int n,int m,int k); int cmatout (FILE * fout, complex *x, int n, int m); int cmatinv( complex *x, int n, int m, phydbl *space); phydbl *Cholesky_Decomp(phydbl *A, int dim); #endif phyml-3.2.0/src/free.c000066400000000000000000000667771263450375500145620ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phyLOGenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "free.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_All_Nodes_Light(t_tree *mixt_tree) { int i; t_tree *tree; tree = mixt_tree; do { For(i,2*tree->n_otu-1) Free_Node(tree->a_nodes[i]); Free(tree->a_nodes); tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_All_Edges_Light(t_tree *mixt_tree) { int i; t_tree *tree; tree = mixt_tree; For(i,2*tree->n_otu-1) { Free_Scalar_Dbl(tree->a_edges[i]->l); Free_Scalar_Dbl(tree->a_edges[i]->l_old); Free_Scalar_Dbl(tree->a_edges[i]->l_var); Free_Scalar_Dbl(tree->a_edges[i]->l_var_old); } do { For(i,2*tree->n_otu-1) Free_Edge(tree->a_edges[i]); Free(tree->a_edges); tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Labels(t_edge *b) { int i; if(b->labels) { For(i,b->n_labels-(b->n_labels%BLOCK_LABELS)+BLOCK_LABELS) Free(b->labels[i]); Free(b->labels); b->labels = NULL; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge(t_edge *b) { Free_Edge_Labels(b); Free_Edge_Core(b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Core(t_edge *b) { Free(b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Node(t_node *n) { Free(n->b); Free(n->v); Free(n->l); Free(n->score); Free(n->s_ingrp); Free(n->s_outgrp); if(n->c_seq_anc != NULL) { Free(n->c_seq_anc->state); Free(n->c_seq_anc); } if(n->ori_name) { Free(n->ori_name); n->ori_name = NULL; } /* if(n->name) { Free(n->name); n->name = NULL; } */ /* Don't do that: see Copy_Tax_Names_To_Tip_Labels tree->a_nodes[i]->ori_name = tree->a_nodes[i]->name; */ Free(n); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Mat(matrix *mat) { int i; For(i,mat->n_otu) { Free(mat->P[i]); Free(mat->Q[i]); Free(mat->dist[i]); Free(mat->name[i]); } Free(mat->P); Free(mat->Q); Free(mat->dist); Free(mat->name); Free(mat->tip_node); Free(mat->on_off); Free(mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Partial_Lk(phydbl *p_lk, int len, int n_catg) { Free(p_lk); /* int i,j; */ /* For(i,len) */ /* { */ /* For(j,n_catg) Free((*p_lk)[i][j]); */ /* Free((*p_lk)[i]); */ /* } */ /* Free((*p_lk)); */ /* (*p_lk) = NULL; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Tree(t_tree *mixt_tree) { t_tree *tree; t_tree *next; tree = mixt_tree; do { if(tree->mat) Free_Mat(tree->mat); Free(tree->t_dir); if(tree->short_l) Free(tree->short_l); if(tree->mutmap) Free(tree->mutmap); Free_Bip(tree); Free(tree->curr_path); tree = tree->next; } while(tree); Free_All_Edges_Light(mixt_tree); Free_All_Nodes_Light(mixt_tree); tree = mixt_tree; next = mixt_tree->next; do { Free(tree); tree = next; if(!tree) break; next = next->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Bip(t_tree *tree) { int i,j; if(tree->has_bip) { For(i,2*tree->n_otu-2) { Free(tree->a_nodes[i]->bip_size); For(j,3) Free(tree->a_nodes[i]->bip_node[j]); Free(tree->a_nodes[i]->bip_node); } } tree->has_bip = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Cseq(calign *data) { int i; Free(data->invar); Free(data->wght); Free(data->ambigu); Free(data->b_frq); Free(data->sitepatt); For(i,data->n_otu) { Free(data->c_seq[i]->name); if(data->c_seq[i]->state) { Free(data->c_seq[i]->state); Free(data->c_seq[i]->d_state); if(data->c_seq[i]->is_ambigu) Free(data->c_seq[i]->is_ambigu); } Free(data->c_seq[i]); } Free(data->c_seq); Free(data); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Seq(align **d, int n_otu) { int i; For(i,n_otu) { Free(d[i]->name); Free(d[i]->state); Free(d[i]->d_state); if(d[i]->is_ambigu) Free(d[i]->is_ambigu); Free(d[i]); } Free(d); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_All(align **d, calign *cdata, t_tree *tree) { Free_Cseq(cdata); Free_Seq(d,tree->n_otu); Free_Tree(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_SubTree(t_edge *b_fcus, t_node *a, t_node *d, t_tree *tree) { int i; if(d->tax) return; else { For(i,3) { if(d->v[i] != a) { Free_SubTree(d->b[i],d,d->v[i],tree); Free_Edge(d->b[i]); Free_Node(d->v[i]); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Tree_Ins_Tar(t_tree *tree) { return; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Tree_Pars(t_tree *mixt_tree) { int i; t_tree *tree; tree = mixt_tree; do { Free(tree->step_mat); Free(tree->site_pars); For(i,2*tree->n_otu-3) { /* printf("\n. FREE b->num: %d %p %p",tree->a_edges[i]->num,tree->a_edges[i]->pars_l,tree->a_edges[i]->pars_r); */ Free_Edge_Pars(tree->a_edges[i]); } if(tree->n_root) { /* printf("\n. FREE b1->num: %d %p %p",tree->n_root->b[1]->num,tree->n_root->b[1]->pars_l,tree->n_root->b[1]->pars_r); */ Free_Edge_Pars_Left(tree->n_root->b[1]); Free_Edge_Pars_Left(tree->n_root->b[2]); /* if(tree->n_root->b[1]->pars_r) Free_Edge_Pars_Rght(tree->n_root->b[1]); */ /* if(tree->n_root->b[2]->pars_r) Free_Edge_Pars_Rght(tree->n_root->b[2]); */ } else { Free_Edge_Pars(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Pars(tree->a_edges[2*tree->n_otu-2]); } tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Pars_Left(t_edge *b) { if(b->pars_l) Free(b->pars_l); if(b->ui_l) Free(b->ui_l); if(b->p_pars_l) Free(b->p_pars_l); if(b->n_diff_states_l) Free(b->n_diff_states_l); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Pars_Rght(t_edge *b) { if(b->pars_r) Free(b->pars_r); if(b->ui_r) Free(b->ui_r); if(b->p_pars_r) Free(b->p_pars_r); if(b->n_diff_states_r) Free(b->n_diff_states_r); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Pars(t_edge *b) { Free_Edge_Pars_Left(b); Free_Edge_Pars_Rght(b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Tree_Lk(t_tree *mixt_tree) { int i; t_tree *tree; tree = mixt_tree; do { Free(tree->c_lnL_sorted); Free(tree->cur_site_lk); Free(tree->old_site_lk); Free(tree->site_lk_cat); Free(tree->fact_sum_scale); For(i,3) Free(tree->log_lks_aLRT[i]); Free(tree->log_lks_aLRT); Free(tree->unscaled_site_lk_cat); For(i,2*tree->n_otu-3) Free_Edge_Lk(tree->a_edges[i]); if(tree->n_root) { Free(tree->n_root->b[1]->nni); Free(tree->n_root->b[2]->nni); Free(tree->n_root->b[1]->Pij_rr); Free(tree->n_root->b[2]->Pij_rr); Free_Edge_Lk_Left(tree->n_root->b[1]); Free_Edge_Lk_Left(tree->n_root->b[2]); /* if(tree->n_root->b[1]->p_lk_rght) Free_Edge_Lk_Rght(tree->n_root->b[1]); */ /* if(tree->n_root->b[2]->p_lk_rght) Free_Edge_Lk_Rght(tree->n_root->b[2]); */ } else { Free_Edge_Lk(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Lk(tree->a_edges[2*tree->n_otu-2]); } tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Node_Lk(t_node *n) { /* Free(n->n_ex_nodes); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Lk_Rght(t_edge *b) { Free(b->div_post_pred_rght); if(b->p_lk_rght) { Free(b->p_lk_rght); if(b->sum_scale_rght) Free(b->sum_scale_rght); } if(b->p_lk_tip_r) Free(b->p_lk_tip_r); Free(b->sum_scale_rght_cat); Free(b->patt_id_rght); Free(b->p_lk_loc_rght); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Lk_Left(t_edge *b) { Free(b->div_post_pred_left); if(b->p_lk_left) { Free(b->p_lk_left); if(b->sum_scale_left) Free(b->sum_scale_left); } if(b->p_lk_tip_l) Free(b->p_lk_tip_l); Free(b->sum_scale_left_cat); Free(b->patt_id_left); Free(b->p_lk_loc_left); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Edge_Lk(t_edge *b) { Free(b->nni); Free(b->Pij_rr); Free_Edge_Lk_Left(b); Free_Edge_Lk_Rght(b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Model_Complete(t_mod *mixt_mod) { Free_Eigen(mixt_mod->eigen); Free_Rmat(mixt_mod->r_mat); Free_Efrq(mixt_mod->e_frq); Free_Vect_Dbl(mixt_mod->Pij_rr); mixt_mod->r_mat = NULL; mixt_mod->e_frq = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Model_Basic(t_mod *mixt_mod) { t_mod *mod; Free_RAS(mixt_mod->ras); Free_Vect_Dbl(mixt_mod->user_b_freq); Free_Scalar_Dbl(mixt_mod->mr); Free_Scalar_Dbl(mixt_mod->kappa); Free_Scalar_Dbl(mixt_mod->lambda); Free_Scalar_Dbl(mixt_mod->br_len_mult); Free_Scalar_Dbl(mixt_mod->br_len_mult_unscaled); Free_Scalar_Dbl(mixt_mod->e_frq_weight); Free_Scalar_Dbl(mixt_mod->r_mat_weight); Free_String(mixt_mod->modelname); Free_String(mixt_mod->custom_mod_string); Free_String(mixt_mod->aa_rate_mat_file); mod = mixt_mod; do { if(mod->next) { mod = mod->next; Free(mod->prev); } else { Free(mod); break; } } while(mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Vect_Dbl(vect_dbl *v) { vect_dbl *next; next = v->next; do { Free(v->v); Free(v); v = next; if(v) next = v->next; } while(v); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Scalar_Dbl(scalar_dbl *v) { scalar_dbl *next; next = v->next; do { Free(v); v = next; if(v) next = v->next; } while(v); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_String(t_string *ts) { t_string *next; next = ts->next; do { Free(ts->s); Free(ts); ts = next; if(ts) next = ts->next; } while(ts); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Custom_Model(t_mod *mod) { } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Efrq(t_efrq *e_frq) { Free(e_frq->pi->v); Free(e_frq->pi); Free(e_frq->pi_unscaled->v); Free(e_frq->pi_unscaled); if(e_frq->next) Free_Efrq(e_frq->next); Free(e_frq); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Rmat(t_rmat *r_mat) { Free(r_mat->rr->v); Free(r_mat->rr); Free(r_mat->rr_num->v); Free(r_mat->rr_val->v); Free(r_mat->rr_val); Free(r_mat->n_rr_per_cat->v); Free(r_mat->n_rr_per_cat); Free(r_mat->rr_num); Free(r_mat->qmat->v); Free(r_mat->qmat); Free(r_mat->qmat_buff->v); Free(r_mat->qmat_buff); if(r_mat->next) Free_Rmat(r_mat->next); Free(r_mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_RAS(t_ras *ras) { if(ras->gamma_r_proba->v) { Free(ras->gamma_r_proba->v); Free(ras->gamma_r_proba_unscaled->v); Free(ras->gamma_rr->v); Free(ras->gamma_rr_unscaled->v); } Free(ras->gamma_r_proba); Free(ras->skip_rate_cat); Free(ras->gamma_r_proba_unscaled); Free(ras->gamma_rr); Free(ras->gamma_rr_unscaled); Free_Scalar_Dbl(ras->pinvar); Free_Scalar_Dbl(ras->alpha); Free_Scalar_Dbl(ras->free_rate_mr); if(ras->next) Free_RAS(ras->next); Free(ras); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Model(t_mod *mod) { Free_Custom_Model(mod); Free_Model_Complete(mod); if(mod->m4mod) M4_Free_M4_Model(mod->m4mod); Free_Model_Basic(mod); /* Free(mod); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free(void *p) { free(p); p = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Input(option *io) { int i; do { RATES_Free_Rates(io->rates); MCMC_Free_MCMC(io->mcmc); Free(io->in_align_file); Free(io->in_tree_file); Free(io->in_constraint_tree_file); Free(io->in_coord_file); Free(io->out_file); Free(io->out_tree_file); Free(io->out_trees_file); Free(io->out_boot_tree_file); Free(io->out_boot_stats_file); Free(io->out_stats_file); Free(io->out_lk_file); Free(io->out_summary_file); Free(io->out_ps_file); Free(io->out_trace_file); Free(io->out_ancestral_file); Free(io->nt_or_cd); Free(io->run_id_string); Free(io->clade_list_file); For(i,T_MAX_ALPHABET) Free(io->alphabet[i]); Free(io->alphabet); if(io->short_tax_names) { For(i,io->size_tax_names) { Free(io->short_tax_names[i]); Free(io->long_tax_names[i]); } Free(io->long_tax_names); Free(io->short_tax_names); } Free_Tree_List(io->treelist); if(io->lon) Free(io->lon); if(io->lat) Free(io->lat); if(io->next) { io = io->next; Free(io->prev); } else { Free(io); break; } }while(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Tree_List(t_treelist *list) { Free(list->tree); Free(list); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_St(supert_tree *st) { int i; For(i,2*st->tree->n_otu-1) Free(st->tree->a_edges[i]->nni); For(i,st->n_part) Free(st->match_st_node_in_gt[i]); Free(st->match_st_node_in_gt); Free_Tree(st->tree); Free(st); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Eigen(eigen *eigen_struct) { Free(eigen_struct->space_int); Free(eigen_struct->space); Free(eigen_struct->e_val); Free(eigen_struct->e_val_im); Free(eigen_struct->r_e_vect); Free(eigen_struct->r_e_vect_im); Free(eigen_struct->l_e_vect); Free(eigen_struct->q); if(eigen_struct->next) Free_Eigen(eigen_struct->next); Free(eigen_struct); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_One_Spr(t_spr *this_spr) { Free(this_spr->path); Free(this_spr); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Spr_List(t_tree *mixt_tree) { int i; t_tree *tree; tree = mixt_tree; do { For(i,tree->size_spr_list+1) Free_One_Spr(tree->spr_list[i]); Free(tree->spr_list); Free_One_Spr(tree->best_spr); tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Triplet(triplet *t) { int i,j,k; Free(t->F_bc); Free(t->F_cd); Free(t->F_bd); Free(t->pi_bc); Free(t->pi_cd); Free(t->pi_bd); For(k,t->mod->ras->n_catg) { For(i,t->size) { For(j,t->size) Free(t->core[k][i][j]); Free(t->core[k][i]); } Free(t->core[k]); } Free(t->core); For(i,t->size) { For(j,t->size) Free(t->p_one_site[i][j]); Free(t->p_one_site[i]); } Free(t->p_one_site); For(i,t->size) { For(j,t->size) Free(t->sum_p_one_site[i][j]); Free(t->sum_p_one_site[i]); } Free(t->sum_p_one_site); Free_Eigen(t->eigen_struct); if(t->next) Free_Triplet(t->next); Free(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Actual_CSeq(calign *data) { int i; For(i,data->n_otu) { Free(data->c_seq[i]->state); Free(data->c_seq[i]->d_state); data->c_seq[i]->state = NULL; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Prefix_Tree(pnode *n, int size) { int i; For(i,size) { if(n->next[i]) { Free_Prefix_Tree(n->next[i],size); } } Free_Pnode(n); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Pnode(pnode *n) { Free(n->next); Free(n); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Optimiz(t_opt *s_opt) { Free(s_opt); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Nexus(option *io) { int i,j; For(i,N_MAX_NEX_COM) { For(j,io->nex_com_list[i]->nparm) Free_Nexus_Parm(io->nex_com_list[i]->parm[j]); Free(io->nex_com_list[i]->parm); Free(io->nex_com_list[i]->name); Free(io->nex_com_list[i]); } Free(io->nex_com_list); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Nexus_Com(nexcom **com) { int i; For(i,N_MAX_NEX_COM) { Free(com[i]->parm); Free(com[i]->name); Free(com[i]); } Free(com); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Nexus_Parm(nexparm *parm) { Free(parm->value); Free(parm->name); Free(parm); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Free_XML_Tree(xml_node *node) { if(node->child) XML_Free_XML_Tree(node->child); if(node->next) XML_Free_XML_Tree(node->next); XML_Free_XML_Node(node); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Free_XML_Node(xml_node *node) { Free(node->id); Free(node->name); Free(node->value); XML_Free_XML_Ds(node->ds); XML_Free_XML_Attr(node->attr); Free(node); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Free_XML_Attr(xml_attr *attr) { if(attr) { Free(attr->name); Free(attr->value); if(attr->next) XML_Free_XML_Attr(attr->next); Free(attr); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Free_XML_Ds(t_ds *ds) { if(ds->next) XML_Free_XML_Ds(ds->next); Free(ds); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Free_MCMC(t_mcmc *mcmc) { int i; Free(mcmc->move_type); Free(mcmc->adjust_tuning); Free(mcmc->out_filename); Free(mcmc->move_weight); Free(mcmc->acc_move); Free(mcmc->run_move); Free(mcmc->prev_acc_move); Free(mcmc->prev_run_move); Free(mcmc->acc_rate); Free(mcmc->tune_move); For(i,mcmc->n_moves) Free(mcmc->move_name[i]); Free(mcmc->move_name); Free(mcmc->ess_run); Free(mcmc->start_ess); Free(mcmc->ess); Free(mcmc->sampled_val); Free(mcmc->mode); Free(mcmc); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Free_M4_Model(m4 *m4mod) { int i; if(m4mod->o_mats) { For(i,m4mod->n_h) Free(m4mod->o_mats[i]); Free(m4mod->o_mats); Free(m4mod->h_mat); Free(m4mod->o_rr); Free(m4mod->h_rr); Free(m4mod->o_fq); Free(m4mod->h_fq); Free(m4mod->multipl); Free(m4mod->multipl_unscaled); Free(m4mod->h_fq_unscaled); } Free(m4mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Free_Rates(t_rate *rates) { if(rates->is_allocated == YES) { Free(rates->nd_r); Free(rates->br_r); Free(rates->buff_r); Free(rates->true_r); Free(rates->buff_t); Free(rates->nd_t); Free(rates->true_t); Free(rates->t_prior); Free(rates->t_mean); Free(rates->t_prior_min); Free(rates->t_prior_max); Free(rates->t_floor); Free(rates->t_has_prior); Free(rates->t_rank); Free(rates->dens); Free(rates->triplet); Free(rates->n_jps); Free(rates->t_jps); Free(rates->cond_var); Free(rates->invcov); Free(rates->ml_l); Free(rates->cur_l); Free(rates->u_ml_l); Free(rates->u_cur_l); Free(rates->cov_r); Free(rates->lca); Free(rates->trip_cond_cov); Free(rates->trip_reg_coeff); Free(rates->_2n_vect1); Free(rates->_2n_vect2); Free(rates->_2n_vect3); Free(rates->_2n_vect4); Free(rates->_2n_vect5); Free(rates->_2n2n_vect1); Free(rates->_2n2n_vect2); Free(rates->cov_l); Free(rates->mean_l); Free(rates->mean_r); Free(rates->mean_t); Free(rates->grad_l); Free(rates->reg_coeff); Free(rates->br_do_updt); Free(rates->cur_gamma_prior_mean); Free(rates->cur_gamma_prior_var); Free(rates->n_tips_below); Free(rates->time_slice_lims); Free(rates->n_time_slice_spans); Free(rates->curr_slice); Free(rates->has_survived); Free(rates->survival_rank); Free(rates->survival_dur); Free(rates->calib_prob); Free(rates->node_height_dens_log_norm_const_update); Free(rates->curr_nd_for_cal); Free(rates->t_prior_min_ori); Free(rates->t_prior_max_ori); Free(rates->times_partial_proba); Free(rates->numb_calib_chosen); } Free_Calib(rates->calib); Free(rates); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Calib(t_cal *cal) { if(!cal) return; else Free_Calib(cal->next); Free(cal); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Free_Geo(t_geo *t) { int i; Free(t->f_mat); Free(t->r_mat); Free(t->occup); Free(t->idx_loc); Free(t->sorted_nd); Free(t->cov); Free(t->idx_loc_beneath); For(i,t->ldscape_sz) Free_Geo_Coord(t->coord_loc[i]); Free(t->coord_loc); Free(t); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Free_Geo_Coord(t_geo_coord *t) { Free(t->cpy->lonlat); Free(t->cpy->id); Free(t->cpy); Free(t->lonlat); Free(t->id); Free(t); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Free_Disk(t_dsk *t) { Free_Geo_Coord(t->centr); Free(t->ldsk_a); Free(t->id); Free(t); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Free_Ldisk(t_ldsk *t) { if(t == NULL) return; else { Free(t->next); Free_Geo_Coord(t->coord); /* if(t->min_coord) Free_Geo_Coord(t->min_coord); */ /* if(t->max_coord) Free_Geo_Coord(t->max_coord); */ if(t->cpy_coord) Free_Geo_Coord(t->cpy_coord); Free(t); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Poly(t_poly *p) { int i; For(i,p->n_poly_vert) Free_Geo_Coord(p->poly_vert[i]); Free(p->poly_vert); Free(p); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Free_Mmod(t_phyrex_mod *mmod) { Free_Geo_Coord(mmod->lim); Free(mmod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/free.h000066400000000000000000000047251263450375500145500ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef FREE_H #define FREE_H #include "utilities.h" void Free_All_Nodes_Light(t_tree *tree); void Free_All_Edges_Light(t_tree *tree); void Free_Mat(matrix *mat); void Free_Partial_Lk(phydbl *p_lk,int len,int n_catg); void Free_Tree(t_tree *tree); void Free_Bip(t_tree *tree); void Free_Edge_Labels(t_edge *b); void Free_Edge(t_edge *b); void Free_Node(t_node *n); void Free_Cseq(calign *data); void Free_Seq(align **d,int n_otu); void Free_All(align **d,calign *cdata,t_tree *tree); void Free_SubTree(t_edge *b_fcus,t_node *a,t_node *d,t_tree *tree); void Free_Tree_Ins_Tar(t_tree *tree); void Free_Tree_Pars(t_tree *tree); void Free_Edge_Pars(t_edge *b); void Free_Edge_Pars_Left(t_edge *b); void Free_Edge_Pars_Rght(t_edge *b); void Free_Tree_Lk(t_tree *tree); void Free_Node_Lk(t_node *n); void Free_Edge_Lk(t_edge *b); void Free_Model_Complete(t_mod *mod); void Free_Model_Basic(t_mod *mod); void Free_Custom_Model(t_mod *mod); void Free_Efrq(t_efrq *e_frq); void Free_Rmat(t_rmat *r_mat); void Free_Model(t_mod *mod); void Free(void *p); void Free_Input(option *io); void Free_Tree_List(t_treelist *list); void Free_St(supert_tree *st); void Free_Eigen(eigen *eigen_struct); void Free_One_Spr(t_spr *this_spr); void Free_Spr_List(t_tree *tree); void Free_Triplet(triplet *t); void Free_Actual_CSeq(calign *data); void Free_Prefix_Tree(pnode *n,int size); void Free_Pnode(pnode *n); void Free_Optimiz(t_opt *s_opt); void Free_Nexus(option *io); void Free_Nexus_Com(nexcom **com); void Free_Nexus_Parm(nexparm *parm); void Free_RAS(t_ras *ras); void XML_Free_XML_Tree(xml_node *node); void XML_Free_XML_Node(xml_node *node); void XML_Free_XML_Attr(xml_attr *attr); void XML_Free_XML_Ds(t_ds *ds); void Free_String(t_string *ts); void Free_Vect_Dbl(vect_dbl *v); void Free_Scalar_Dbl(scalar_dbl *v); void Free_Edge_Core(t_edge *b); void M4_Free_M4_Model(m4 *m4mod); void RATES_Free_Rates(t_rate *rates); void Free_Calib(t_cal *cal); void Free_Edge_Lk_Left(t_edge *b); void Free_Edge_Lk_Rght(t_edge *b); void Free_Geo(t_geo *t); void Free_Geo_Coord(t_geo_coord *t); void Free_Disk(t_dsk *t); void Free_Ldisk(t_ldsk *t); void Free_Poly(t_poly *p); void Free_Mmod(t_phyrex_mod *mmod); #endif phyml-3.2.0/src/geo.c000066400000000000000000001651141263450375500143740ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "geo.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int GEO_Main(int argc, char **argv) { /* GEO_Simulate_Estimate(argc,argv); */ GEO_Estimate(argc,argv); return(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int GEO_Estimate(int argc, char **argv) { t_geo *t; int seed; FILE *fp; t_tree *tree; phydbl *ldscp; int *loc_hash; int i,j; phydbl *probs; phydbl sum; // geo ./ban seed = getpid(); /* seed = 28224; */ /* seed = 21249; */ /* seed = 21596; */ printf("\n. Seed = %d",seed); srand(seed); t = GEO_Make_Geo_Basic(); GEO_Init_Geo_Struct(t); fp = Openfile(argv[1],0); /* Open tree file */ tree = Read_Tree_File_Phylip(fp); /* Read it */ Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,NULL,tree->n_otu); Branch_To_Time(tree); tree->geo = t; GEO_Read_In_Landscape(argv[2],t,&ldscp,&loc_hash,tree); GEO_Make_Geo_Complete(t->ldscape_sz,t->n_dim,tree->n_otu,t); j = 0; For(i,t->ldscape_sz) { t->coord_loc[i]->lonlat[0] = ldscp[j]; t->coord_loc[i]->lonlat[1] = ldscp[j+1]; PhyML_Printf("\n. Location %d: %13f %13f",i+1,t->coord_loc[i]->lonlat[0],t->coord_loc[i]->lonlat[1]); j+=2; } For(i,tree->n_otu) t->idx_loc[i] = loc_hash[i]; t->cov[0*t->n_dim+0] = t->sigma; t->cov[1*t->n_dim+1] = t->sigma; t->cov[0*t->n_dim+1] = 0.0; t->cov[1*t->n_dim+0] = 0.0; GEO_Get_Sigma_Max(t); t->max_sigma = t->sigma_thresh * 2.; PhyML_Printf("\n. Sigma max: %f",t->sigma_thresh); GEO_Get_Locations_Beneath(t,tree); probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl)); sum = 0.0; For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]; For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum; tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz); Free(probs); GEO_Randomize_Locations(tree->n_root,t,tree); GEO_Update_Occup(t,tree); GEO_Lk(t,tree); PhyML_Printf("\n. Init loglk: %f",tree->geo->c_lnL); /* DR_Draw_Tree("essai.ps",tree); */ GEO_MCMC(tree); fclose(fp); Free(ldscp); Free(loc_hash); return(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int GEO_Simulate_Estimate(int argc, char **argv) { t_geo *t; int n_tax; t_tree *tree,*ori_tree; int seed; phydbl *res; FILE *fp; int pid; char *s; int rand_loc; phydbl *probs,sum; int i; phydbl mantel_p_val; phydbl rf; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(s,"geo.out"); pid = getpid(); sprintf(s+strlen(s),".%d",pid); fp = fopen(s,"w"); seed = getpid(); /* seed = 15520; */ /* seed = 5023; */ printf("\n. Seed = %d",seed); srand(seed); t = GEO_Make_Geo_Basic(); GEO_Init_Geo_Struct(t); /* t->tau = 3.0; */ /* t->lbda = 0.02; */ /* t->sigma = 10.; */ t->ldscape_sz = (int)atoi(argv[1]); t->n_dim = 2; n_tax = (int)atoi(argv[2]); GEO_Make_Geo_Complete(t->ldscape_sz,t->n_dim,n_tax,t); t->cov[0*t->n_dim+0] = t->sigma; t->cov[1*t->n_dim+1] = t->sigma; t->cov[0*t->n_dim+1] = 0.0; t->cov[1*t->n_dim+0] = 0.0; GEO_Simulate_Coordinates(t->ldscape_sz,t); GEO_Get_Sigma_Max(t); t->max_sigma = t->sigma_thresh * 2.; PhyML_Printf("\n. sigma max: %f threshold: %f",t->max_sigma,t->sigma_thresh); /* t->tau = Uni()*(t->max_tau/100.-t->min_tau*10.) + t->min_tau*10.; */ /* t->lbda = EXP(Uni()*(LOG(t->max_lbda/100.)-LOG(t->min_lbda*10.)) + LOG(t->min_lbda*10.)); */ /* t->sigma = Uni()*(t->max_sigma-t->min_sigma) + t->min_sigma; */ t->lbda = 1.; t->sigma = 0.3; t->tau = 1.; PhyML_Fprintf(fp,"\n# SigmaTrue\t SigmaThresh\t LbdaTrue\t TauTrue\txTrue\t yTrue\t xRand\t yRand\t RF\t Sigma5\t Sigma50\t Sigma95\t ProbSigmaInfThresh\t Lbda5\t Lbda50\t Lbda95\t ProbLbdaInf1\t Tau5\t Tau50\t Tau95\t X5\t X50\t X95\t Y5\t Y50\t Y95\t RandX5\t RandX50\t RandX95\t RandY5\t RandY50\t RandY95\t Mantel\t"); PhyML_Fprintf(fp,"\n"); tree = GEO_Simulate(t,n_tax); ori_tree = Make_Tree_From_Scratch(tree->n_otu,NULL); Copy_Tree(tree,ori_tree); Random_SPRs_On_Rooted_Tree(tree); Free_Bip(ori_tree); Alloc_Bip(ori_tree); Get_Bip(ori_tree->a_nodes[0],ori_tree->a_nodes[0]->v[0],ori_tree); Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); Match_Tip_Numbers(tree,ori_tree); rf = (phydbl)Compare_Bip(ori_tree,tree,NO)/(tree->n_otu-3); PhyML_Printf("\n. rf: %f",rf); phydbl scale; scale = EXP(Rnorm(0,0.2)); PhyML_Printf("\n. Scale: %f",scale); For(i,2*tree->n_otu-1) tree->rates->nd_t[i] *= scale; phydbl *tree_dist,*geo_dist; int j; Time_To_Branch(tree); tree_dist = Dist_Btw_Tips(tree); geo_dist = (phydbl *)mCalloc(tree->n_otu*tree->n_otu,sizeof(phydbl)); For(i,tree->n_otu) { For(j,tree->n_otu) { /* geo_dist[i*tree->n_otu+j] = */ /* FABS(t->ldscape[t->idx_loc[i]*t->n_dim+0] - */ /* t->ldscape[t->idx_loc[j]*t->n_dim+0])+ */ /* FABS(t->ldscape[t->idx_loc[i]*t->n_dim+1] - */ /* t->ldscape[t->idx_loc[j]*t->n_dim+1]); */ geo_dist[i*tree->n_otu+j] = FABS(t->coord_loc[t->idx_loc[i]]->lonlat[0] - t->coord_loc[t->idx_loc[j]]->lonlat[0])+ FABS(t->coord_loc[t->idx_loc[i]]->lonlat[1] - t->coord_loc[t->idx_loc[j]]->lonlat[1]); } } printf("\n. tau: %f lbda: %f sigma: %f",t->tau,t->lbda,t->sigma); mantel_p_val = Mantel(tree_dist,geo_dist,tree->n_otu,tree->n_otu); printf("\n. Mantel test p-value: %f",mantel_p_val); Free(tree_dist); Free(geo_dist); rand_loc = Rand_Int(0,t->ldscape_sz-1); PhyML_Printf("\n. sigma: %f\t lbda: %f\t tau:%f\t x:%f\t y:%f rand.x:%f\t rand.y:%f\t", t->sigma, t->lbda, t->tau, /* t->ldscape[t->idx_loc[tree->n_root->num]*t->n_dim+0], */ /* t->ldscape[t->idx_loc[tree->n_root->num]*t->n_dim+1], */ /* t->ldscape[rand_loc*t->n_dim+0], */ /* t->ldscape[rand_loc*t->n_dim+1]); */ t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[0], t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[1], t->coord_loc[rand_loc]->lonlat[0], t->coord_loc[rand_loc]->lonlat[1]); PhyML_Fprintf(fp,"%f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t", t->sigma, t->sigma_thresh, t->lbda, t->tau, t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[0], t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[1], t->coord_loc[rand_loc]->lonlat[0], t->coord_loc[rand_loc]->lonlat[1], rf); GEO_Get_Locations_Beneath(t,tree); probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl)); sum = 0.0; For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]; For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum; tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz); Free(probs); GEO_Randomize_Locations(tree->n_root,tree->geo,tree); GEO_Update_Occup(t,tree); GEO_Lk(t,tree); PhyML_Printf("\n. Init loglk: %f",tree->geo->c_lnL); res = GEO_MCMC(tree); PhyML_Fprintf(fp,"%f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f \n", /* Sigma5 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* Sigma50*/ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* Sigma95*/ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* ProbInfThesh */ Prob(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval,t->sigma_thresh), /* Lbda5 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* Lbda50 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* Lbda95 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* ProbInf1 */ Prob(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval,1.0), /* Tau5 */ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* Tau50 */ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* Tau 95 */ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* X5 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* X50 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* X95 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* Y5 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* Y50 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* Y95 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* RandX5 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* RandX50*/ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* RandX95*/ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), /* RandY5 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.025), /* RandY50*/ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.50), /* RandY95*/ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval,tree->mcmc->run / tree->mcmc->sample_interval+1,0.975), mantel_p_val ); fflush(NULL); Free(s); Free(res); fclose(fp); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *GEO_MCMC(t_tree *tree) { phydbl *res; int n_vars; int rand_loc; t_geo *t; t = tree->geo; tree->mcmc = MCMC_Make_MCMC_Struct(); MCMC_Complete_MCMC(tree->mcmc,tree); tree->mcmc->io = NULL; tree->mcmc->is = NO; tree->mcmc->use_data = YES; tree->mcmc->run = 0; tree->mcmc->sample_interval = 1E+3; tree->mcmc->chain_len = 1E+6; tree->mcmc->chain_len_burnin = 1E+5; tree->mcmc->randomize = YES; tree->mcmc->norm_freq = 1E+3; tree->mcmc->max_tune = 1.E+20; tree->mcmc->min_tune = 1.E-10; tree->mcmc->print_every = 2; tree->mcmc->is_burnin = NO; tree->mcmc->nd_t_digits = 1; t->tau = 1.0; t->lbda = 1.0; t->sigma = 1.0; t->dum = 1.0; tree->mcmc->chain_len = 1.E+8; tree->mcmc->sample_interval = 50; MCMC_Complete_MCMC(tree->mcmc,tree); GEO_Update_Occup(t,tree); GEO_Lk(t,tree); tree->mcmc->start_ess[tree->mcmc->num_move_geo_sigma] = YES; tree->mcmc->start_ess[tree->mcmc->num_move_geo_lambda] = YES; tree->mcmc->start_ess[tree->mcmc->num_move_geo_tau] = YES; tree->mcmc->start_ess[tree->mcmc->num_move_geo_dum] = YES; n_vars = 10; res = (phydbl *)mCalloc(tree->mcmc->chain_len / tree->mcmc->sample_interval * n_vars,sizeof(phydbl)); PhyML_Printf("\n. Run Sigma [ESS] Lambda [ESS] Tau [ESS] Dummy [ESS] LogLk"); tree->mcmc->run = 0; do { MCMC_GEO_Lbda(tree); MCMC_GEO_Tau(tree); /* MCMC_Geo_Dum(tree); */ MCMC_GEO_Loc(tree); t->update_fmat = YES; MCMC_GEO_Sigma(tree); t->update_fmat = NO; /* t->update_fmat = YES; */ /* MCMC_Geo_Updown_Lbda_Sigma(tree); */ /* t->update_fmat = NO; */ /* MCMC_Geo_Updown_Tau_Lbda(tree); */ /* MCMC_Geo_Updown_Tau_Lbda(tree); */ /* MCMC_Geo_Updown_Tau_Lbda(tree); */ /* printf("\n"); */ /* int i; */ /* For(i,2*tree->n_otu-1) */ /* { */ /* if(tree->a_nodes[i]->tax == NO) */ /* { */ /* printf("%2d ",tree->geo->idx_loc[i]); */ /* } */ /* } */ if(tree->mcmc->run%tree->mcmc->sample_interval == 0) { MCMC_Copy_To_New_Param_Val(tree->mcmc,tree); MCMC_Update_Effective_Sample_Size(tree->mcmc->num_move_geo_lambda,tree->mcmc,tree); MCMC_Update_Effective_Sample_Size(tree->mcmc->num_move_geo_sigma,tree->mcmc,tree); MCMC_Update_Effective_Sample_Size(tree->mcmc->num_move_geo_tau,tree->mcmc,tree); /* printf("\n. lbda:%f,%f tau:%f,%f sigma:%f,%f", */ /* tree->mcmc->acc_rate[tree->mcmc->num_move_geo_lambda], */ /* tree->mcmc->tune_move[tree->mcmc->num_move_geo_lambda], */ /* tree->mcmc->acc_rate[tree->mcmc->num_move_geo_tau], */ /* tree->mcmc->tune_move[tree->mcmc->num_move_geo_tau], */ /* tree->mcmc->acc_rate[tree->mcmc->num_move_geo_sigma], */ /* tree->mcmc->tune_move[tree->mcmc->num_move_geo_sigma]); */ PhyML_Printf("\n. %6d %12f %4.0f %12f %4.0f %12f %4.0f %12f %4.0f %12f", tree->mcmc->run, t->sigma, tree->mcmc->ess[tree->mcmc->num_move_geo_sigma], t->lbda, tree->mcmc->ess[tree->mcmc->num_move_geo_lambda], t->tau, tree->mcmc->ess[tree->mcmc->num_move_geo_tau], t->dum, tree->mcmc->ess[tree->mcmc->num_move_geo_dum], t->c_lnL); /* PhyML_Printf("\n%12f %12f %12f %12f", */ /* t->sigma, */ /* t->lbda, */ /* t->tau, */ /* t->dum); */ rand_loc = Rand_Int(0,t->ldscape_sz-1); res[0 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->sigma; res[1 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->lbda; res[2 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->tau; res[3 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->c_lnL; /* res[4 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->ldscape[t->idx_loc[tree->n_root->num]*t->n_dim+0]; */ /* res[5 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->ldscape[t->idx_loc[tree->n_root->num]*t->n_dim+1]; */ res[4 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[0]; res[5 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->coord_loc[t->idx_loc[tree->n_root->num]]->lonlat[1]; /* res[6 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->ldscape[rand_loc*t->n_dim+0]; */ /* res[7 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->ldscape[rand_loc*t->n_dim+1]; */ res[6 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->coord_loc[rand_loc]->lonlat[0]; res[7 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = t->coord_loc[rand_loc]->lonlat[1]; } tree->mcmc->run++; if(tree->mcmc->ess[tree->mcmc->num_move_geo_sigma] > 200.) tree->mcmc->adjust_tuning[tree->mcmc->num_move_geo_sigma] = NO; if(tree->mcmc->ess[tree->mcmc->num_move_geo_tau] > 200.) tree->mcmc->adjust_tuning[tree->mcmc->num_move_geo_tau] = NO; if(tree->mcmc->ess[tree->mcmc->num_move_geo_lambda]> 200.) tree->mcmc->adjust_tuning[tree->mcmc->num_move_geo_lambda] = NO; MCMC_Get_Acc_Rates(tree->mcmc); if(tree->mcmc->ess[tree->mcmc->num_move_geo_sigma] > 1000. && tree->mcmc->ess[tree->mcmc->num_move_geo_tau] > 1000. && tree->mcmc->ess[tree->mcmc->num_move_geo_lambda]> 1000.) break; } while(tree->mcmc->run < tree->mcmc->chain_len); return(res); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Update F matrix. Assume a diagonal covariance matrix. void GEO_Update_Fmat(t_geo *t) { phydbl *loc1, *loc2; int i,j,k; int err; phydbl lognloc; For(i,t->n_dim) t->cov[i*t->n_dim+i] = t->sigma; // Diagonal covariance matrix. Same variance in every direction lognloc = LOG(t->ldscape_sz); // Fill in F matrix; for(i=0;ildscape_sz;i++) { loc1 = t->coord_loc[i]->lonlat; for(j=i;jldscape_sz;j++) { loc2 = t->coord_loc[j]->lonlat; t->f_mat[i*t->ldscape_sz+j] = .0; // Calculate log(f(l_i,l_j)) - log(f(l_i,l_i) - log(m) For(k,t->n_dim) t->f_mat[i*t->ldscape_sz+j] += Log_Dnorm(loc2[k],loc1[k],t->cov[k*t->n_dim+k],&err); t->f_mat[i*t->ldscape_sz+j] -= lognloc; For(k,t->n_dim) t->f_mat[i*t->ldscape_sz+j] -= Log_Dnorm(loc1[k],loc1[k],t->cov[k*t->n_dim+k],&err); // Take the exponential t->f_mat[i*t->ldscape_sz+j] = EXP(t->f_mat[i*t->ldscape_sz+j]); // Matrix is symmetric t->f_mat[j*t->ldscape_sz+i] = t->f_mat[i*t->ldscape_sz+j]; /* printf("\n. f[%d,%d] = %f (1:[%f;%f] 2:[%f;%f]) sigma=%f",i,j,t->f_mat[i*t->ldscape_sz+j],loc1[0],loc1[1],loc2[0],loc2[1],SQRT(t->cov[0*t->n_dim+0])); */ } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Sort node heights from oldest to youngest age. void GEO_Update_Sorted_Nd(t_geo *t, t_tree *tree) { int i; int swap; t_node *buff; buff = NULL; For(i,2*tree->n_otu-1) t->sorted_nd[i] = tree->a_nodes[i]; // Bubble sort of the node heights do { swap = NO; For(i,2*tree->n_otu-2) { if(tree->rates->nd_t[t->sorted_nd[i+1]->num] < tree->rates->nd_t[t->sorted_nd[i]->num]) { buff = t->sorted_nd[i]; t->sorted_nd[i] = t->sorted_nd[i+1]; t->sorted_nd[i+1] = buff; swap = YES; } } } while(swap == YES); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Update the set of vectors of occupation along the tree void GEO_Update_Occup(t_geo *t, t_tree *tree) { int i,j; t_node *v1, *v2; GEO_Update_Sorted_Nd(t,tree); For(i,t->ldscape_sz*(2*tree->n_otu-1)) t->occup[i] = 0; t->occup[tree->n_root->num*t->ldscape_sz + t->idx_loc[tree->n_root->num]] = 1; for(i=1;i<2*tree->n_otu-1;i++) { For(j,t->ldscape_sz) { t->occup[t->sorted_nd[i]->num*t->ldscape_sz + j] = t->occup[t->sorted_nd[i-1]->num*t->ldscape_sz + j]; } if(t->sorted_nd[i-1]->tax == NO) { v1 = v2 = NULL; if(t->sorted_nd[i-1] == tree->n_root) { v1 = tree->n_root->v[1]; v2 = tree->n_root->v[2]; } else { For(j,3) { if(t->sorted_nd[i-1]->v[j] != t->sorted_nd[i-1]->anc && t->sorted_nd[i-1]->b[j] != tree->e_root) { if(!v1) v1 = t->sorted_nd[i-1]->v[j]; else v2 = t->sorted_nd[i-1]->v[j]; } } } if(t->idx_loc[v1->num] != t->idx_loc[t->sorted_nd[i-1]->num]) { t->occup[t->sorted_nd[i]->num * t->ldscape_sz + t->idx_loc[v1->num]]++; } else { t->occup[t->sorted_nd[i]->num * t->ldscape_sz + t->idx_loc[v2->num]]++; } } } /* printf("\n"); */ /* For(i,2*tree->n_otu-1) */ /* { */ /* printf("\n. Node %3d: ",t->sorted_nd[i]->num); */ /* For(j,t->ldscape_sz) */ /* { */ /* /\* printf("%3d [%12f;%12f] ", *\/ */ /* /\* t->occup[t->sorted_nd[i]->num*t->ldscape_sz + j], *\/ */ /* /\* t->ldscape[j*t->n_dim+0],t->ldscape[j*t->n_dim+1]); *\/ */ /* /\* printf("%3d ", *\/ */ /* /\* t->occup[t->sorted_nd[i]->num*t->ldscape_sz + j]); *\/ */ /* } */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Calculate R mat at node n void GEO_Update_Rmat(t_node *n, t_geo *t, t_tree *tree) { int i,j; phydbl lbda_j; For(i,t->ldscape_sz) { For(j,t->ldscape_sz) { lbda_j = ((t->occup[n->num*t->ldscape_sz + j]==0) ? (1.0) : (t->lbda)); t->r_mat[i*t->ldscape_sz+j] = t->f_mat[i*t->ldscape_sz+j] * lbda_j * t->tau * t->dum; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl GEO_Lk(t_geo *t, t_tree *tree) { int i,j; phydbl loglk; phydbl R; int dep,arr; // departure and arrival location indices; t_node *curr_n,*prev_n,*v1,*v2; phydbl sum; GEO_Update_Occup(t,tree); // Same here. if(t->update_fmat == YES) GEO_Update_Fmat(t); prev_n = NULL; curr_n = NULL; loglk = .0; for(i=1;in_otu-1;i++) // Consider all the time slices, from oldest to youngest. // Start at first node below root { prev_n = t->sorted_nd[i-1]; // node just above curr_n = t->sorted_nd[i]; // current node GEO_Update_Rmat(curr_n,t,tree); // NOTE: don't need to do that every time. Add check later. R = GEO_Total_Migration_Rate(curr_n,t); // Total migration rate calculated at node n /* if(i < 2) */ /* { */ /* printf("\n. t0: %f t1: %f R: %f tau: %f sigma: %f lbda: %f x1: %f y1: %f x2: %f y2: %f log0: %d loc1: %d rij: %G fij: %G", */ /* tree->rates->nd_t[t->sorted_nd[i-1]->num], */ /* tree->rates->nd_t[t->sorted_nd[i]->num], */ /* R, */ /* t->tau, */ /* t->lbda, */ /* t->sigma, */ /* t->ldscape[t->idx_loc[tree->geo->sorted_nd[i-1]->num]*t->n_dim+0], */ /* t->ldscape[t->idx_loc[tree->geo->sorted_nd[i-1]->num]*t->n_dim+1], */ /* t->ldscape[t->idx_loc[tree->geo->sorted_nd[i]->num]*t->n_dim+0], */ /* t->ldscape[t->idx_loc[tree->geo->sorted_nd[i]->num]*t->n_dim+1], */ /* t->idx_loc[tree->geo->sorted_nd[i-1]->num], */ /* t->idx_loc[tree->geo->sorted_nd[i]->num], */ /* t->r_mat[t->idx_loc[tree->geo->sorted_nd[i-1]->num] * t->ldscape_sz + t->idx_loc[tree->geo->sorted_nd[i]->num]], */ /* t->f_mat[t->idx_loc[tree->geo->sorted_nd[i-1]->num] * t->ldscape_sz + t->idx_loc[tree->geo->sorted_nd[i]->num]] */ /* ); */ /* printf("\n >> "); */ /* int j; */ /* For(j,t->ldscape_sz) */ /* if(t->occup[t->sorted_nd[i]->num * t->ldscape_sz + j] > 0) */ /* printf("%f %f -- ", */ /* t->ldscape[j*t->n_dim+0], */ /* t->ldscape[j*t->n_dim+1]); */ /* } */ /* printf("\n. %d %d (%d) %f %p %p \n",i,curr_n->num,curr_n->tax,tree->rates->nd_t[curr_n->num],curr_n->v[1],curr_n->v[2]); */ v1 = v2 = NULL; For(j,3) if(curr_n->v[j] != curr_n->anc && curr_n->b[j] != tree->e_root) { if(!v1) v1 = curr_n->v[j]; else v2 = curr_n->v[j]; } dep = t->idx_loc[curr_n->num]; // departure location arr = // arrival location (t->idx_loc[v1->num] == t->idx_loc[curr_n->num] ? t->idx_loc[v2->num] : t->idx_loc[v1->num]); /* printf("\n%f\t%f", */ /* t->ldscape[arr*t->n_dim+0]-t->ldscape[dep*t->n_dim+0], */ /* t->ldscape[arr*t->n_dim+1]-t->ldscape[dep*t->n_dim+1]); */ loglk -= R * FABS(tree->rates->nd_t[curr_n->num] - tree->rates->nd_t[prev_n->num]); loglk += LOG(t->r_mat[dep * t->ldscape_sz + arr]); /* printf("\n <> %d %f %f %d %d v1:%d v2:%d anc:%d %d %d %d", */ /* curr_n->num, */ /* R * FABS(tree->rates->nd_t[curr_n->num] - tree->rates->nd_t[prev_n->num]), */ /* LOG(t->r_mat[dep * t->ldscape_sz + arr]), */ /* dep,arr,v1->num,v2->num,curr_n->anc->num,curr_n->v[0]->num,curr_n->v[1]->num,curr_n->v[2]->num); */ /* if(i<2) */ /* { */ /* printf("\n. R = %f r_mat = %f f_mat = %f dt = %f loglk = %f", */ /* R, */ /* t->r_mat[dep * t->ldscape_sz + arr], */ /* t->f_mat[dep * t->ldscape_sz + arr], */ /* FABS(t->sorted_nd[i] - t->sorted_nd[i-1]),loglk); */ /* Exit("\n"); */ /* } */ } // Likelihood for the first 'slice' (i.e., the part just below the root down to // the next node) GEO_Update_Rmat(tree->n_root,t,tree); loglk -= LOG(t->ldscape_sz); dep = t->idx_loc[tree->n_root->num]; arr = (t->idx_loc[tree->n_root->num] != t->idx_loc[tree->n_root->v[1]->num] ? t->idx_loc[tree->n_root->v[1]->num] : t->idx_loc[tree->n_root->v[2]->num]); /* printf("\n %f %f",t->ldscape[dep],t->ldscape[arr]); */ loglk += LOG(t->r_mat[dep * t->ldscape_sz + arr]); sum = .0; For(i,t->ldscape_sz) sum += t->r_mat[dep * t->ldscape_sz + i]; loglk -= LOG(sum); tree->geo->c_lnL = loglk; return loglk; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Init_Tloc_Tips(t_geo *t, t_tree *tree) { int i; // TO DO For(i,tree->n_otu) { t->idx_loc[i] = i; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Do not forget to call GEO_Update_Rmat (with node n) before calling this function phydbl GEO_Total_Migration_Rate(t_node *n, t_geo *t) { phydbl R; int i,j; R = .0; For(i,t->ldscape_sz) { For(j,t->ldscape_sz) { R += t->r_mat[i * t->ldscape_sz + j] * t->occup[n->num * t->ldscape_sz + i]; } } return R; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Find the arrival location for the migration leaving from n int GEO_Get_Arrival_Location(t_node *n, t_geo *t, t_tree *tree) { int i; t_node *v1, *v2; // the two daughters of n v1 = v2 = NULL; For(i,3) { if(n->v[i] && n->v[i] != n->anc) { if(!v1) v1 = n->v[i]; else v2 = n->v[i]; } } if(t->idx_loc[v1->num] == t->idx_loc[v2->num]) // Migrated to the same location as that of n { if(t->idx_loc[n->num] != t->idx_loc[v1->num]) { PhyML_Printf("\n== Error detected in location labeling."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } else return t->idx_loc[n->num]; } else // Migrated to a different spot { if((t->idx_loc[v1->num] != t->idx_loc[n->num]) && (t->idx_loc[v2->num] != t->idx_loc[n->num])) { PhyML_Printf("\n== Error detected in location labeling."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } else { if(t->idx_loc[v1->num] == t->idx_loc[n->num]) return t->idx_loc[v2->num]; // v2 gets the new location, v1 inheritates from n else return t->idx_loc[v1->num]; // v1 gets the new location, v2 inheritates from n } } return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *GEO_Simulate(t_geo *t, int n_otu) { t_tree *tree; int n_branching_nodes; t_node **branching_nodes; // vector of nodes available for branching out phydbl *p_branch; // p_branch[i]: proba that the i-th node in branching_nodes branches out (p_x vector in the article) phydbl *p_mig; // p_branch[i]: proba of migrating to location i from the location of the edge branching out (q_i vector in the article) int hit; phydbl time; int dep, arr; int i,j; phydbl sum; phydbl R; int *occup; // occupation vector. Updated as we move down the tree int nd_idx; t_node *buff_nd; phydbl buff_t; int buff_l; int swap; tree = Make_Tree_From_Scratch(n_otu,NULL); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,NULL,tree->n_otu); tree->n_root = tree->a_nodes[2*tree->n_otu-2]; // Set the root node to the last element in the list of nodes tree->geo = t; For(i,2*tree->n_otu-2) tree->rates->nd_t[i] = -1.; occup = (int *)mCalloc(t->ldscape_sz,sizeof(int)); GEO_Update_Fmat(t); branching_nodes = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); branching_nodes[0] = tree->n_root; n_branching_nodes = 1; nd_idx = 0; p_branch = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl )); p_branch[0] = 1.0; p_mig = (phydbl *)mCalloc(t->ldscape_sz,sizeof(phydbl )); time = 0.0; // Time at the root node (this will be changed afterward) // Sample a location uniformly for the root t->idx_loc[tree->n_root->num] = Rand_Int(0,t->ldscape_sz-1); // Update the occupancy vector occup[t->idx_loc[tree->n_root->num]] = 1; dep = arr = -1; // total migration rate R = 0.0; For(i,t->ldscape_sz) { R += t->f_mat[t->idx_loc[tree->n_root->num]*t->ldscape_sz+i] * ((occup[i] == 0) ? (1.0) : (t->lbda)) * t->tau * t->dum; } do { // Select the node that branches out hit = Sample_i_With_Proba_pi(p_branch,n_branching_nodes); /* printf("\n. [%d] Select node %d (location %d)",n_branching_nodes,branching_nodes[hit]->num,t->idx_loc[branching_nodes[hit]->num]); */ // Set the time for the branching node tree->rates->nd_t[branching_nodes[hit]->num] = time; /* printf("\n. Set its time to %f",time); */ // Select the destination location dep = t->idx_loc[branching_nodes[hit]->num]; // Departure point sum = .0; For(i,t->ldscape_sz) // Total rate of migration out of departure point { p_mig[i] = t->f_mat[dep*t->ldscape_sz+i] * ((occup[i] == 0) ? (1.0) : (t->lbda)) * t->tau * t->dum; sum += p_mig[i]; } For(i,t->ldscape_sz) p_mig[i] /= sum; arr = Sample_i_With_Proba_pi(p_mig,t->ldscape_sz); /* printf("\n. Migrate from %d [%5.2f,%5.2f] to %d [%5.2f,%5.2f]", */ /* dep, */ /* t->ldscape[dep*t->n_dim+0], */ /* t->ldscape[dep*t->n_dim+1], */ /* arr, */ /* t->ldscape[arr*t->n_dim+0], */ /* t->ldscape[arr*t->n_dim+1]); */ /* printf("\n%f\t%f", */ /* t->ldscape[arr*t->n_dim+0]-t->ldscape[dep*t->n_dim+0], */ /* t->ldscape[arr*t->n_dim+1]-t->ldscape[dep*t->n_dim+1]); */ // Update vector of occupation occup[arr]++; /* printf("\n. Remove %d. Add %d and %d",branching_nodes[hit]->num,tree->a_nodes[nd_idx]->num,tree->a_nodes[nd_idx+1]->num); */ // Connect two new nodes to the node undergoing a branching event tree->a_nodes[nd_idx]->v[0] = branching_nodes[hit]; tree->a_nodes[nd_idx+1]->v[0] = branching_nodes[hit]; branching_nodes[hit]->v[1] = tree->a_nodes[nd_idx]; branching_nodes[hit]->v[2] = tree->a_nodes[nd_idx+1]; // update branching_nodes vector. Element 'hit' is being replaced so that the corresponding node can no longer branch out branching_nodes[hit] = tree->a_nodes[nd_idx]; branching_nodes[n_branching_nodes] = tree->a_nodes[nd_idx+1]; // Update t_loc vector. t->idx_loc[tree->a_nodes[nd_idx]->num] = dep; t->idx_loc[tree->a_nodes[nd_idx+1]->num] = arr; // Update total migration rate R = .0; For(i,t->ldscape_sz) { if(occup[i] > 0) { For(j,t->ldscape_sz) { R += occup[i] * t->f_mat[i*t->ldscape_sz+j] * ((occup[j] == 0) ? (1.0) : (t->lbda)) * t->tau * t->dum; } } } // Set the time until next branching event time = time + Rexp(R); // Update p_branch vector For(i,n_branching_nodes+1) { dep = t->idx_loc[branching_nodes[i]->num]; p_branch[i] = 0.0; For(j,t->ldscape_sz) { p_branch[i] += t->f_mat[dep*t->ldscape_sz+j] * ((occup[j] == 0) ? (1.0) : (t->lbda)) * t->tau * t->dum / R; /* printf("\n. %f %f %f %f", */ /* R, */ /* t->f_mat[dep*t->ldscape_sz+j], */ /* ((occup[j]>0) ? (t->lbda) : (1.0)), */ /* t->tau); */ } /* printf("\n. %f ",p_branch[i]); */ } // Increase the number of branching nodes by one (you just added 2 new and removed 1 old) n_branching_nodes++; nd_idx += 2; } while(n_branching_nodes < n_otu); // Set the times at the tips For(i,2*tree->n_otu-1) if(tree->rates->nd_t[i] < 0.0) tree->rates->nd_t[i] = time; // Reverse time scale For(i,2*tree->n_otu-1) tree->rates->nd_t[i] -= time; /* For(i,2*tree->n_otu-1) tree->rates->nd_t[i] = FABS(tree->rates->nd_t[i]); */ // Bubble sort to put all the tips at the top of the tree->a_nodes array do { swap = NO; For(i,2*tree->n_otu-2) { if(!tree->a_nodes[i+1]->v[1] && tree->a_nodes[i]->v[1]) { buff_nd = tree->a_nodes[i+1]; tree->a_nodes[i+1] = tree->a_nodes[i]; tree->a_nodes[i] = buff_nd; buff_t = tree->rates->nd_t[i+1]; tree->rates->nd_t[i+1] = tree->rates->nd_t[i]; tree->rates->nd_t[i] = buff_t; buff_l = t->idx_loc[i+1]; t->idx_loc[i+1] = t->idx_loc[i]; t->idx_loc[i] = buff_l; swap = YES; } } } while(swap == YES); // The rest below is just bookeeping... For(i,2*tree->n_otu-1) tree->a_nodes[i]->num = i; For(i,2*tree->n_otu-1) { if(i < tree->n_otu) tree->a_nodes[i]->tax = YES; else tree->a_nodes[i]->tax = NO; } /* printf("\n++++++++++++++++++\n"); */ /* For(i,2*tree->n_otu-1) */ /* { */ /* printf("\n. Node %3d [%p] anc:%3d v1:%3d v2:%3d time: %f", */ /* tree->a_nodes[i]->num, */ /* (void *)tree->a_nodes[i], */ /* tree->a_nodes[i]->v[0] ? tree->a_nodes[i]->v[0]->num : -1, */ /* tree->a_nodes[i]->v[1] ? tree->a_nodes[i]->v[1]->num : -1, */ /* tree->a_nodes[i]->v[2] ? tree->a_nodes[i]->v[2]->num : -1, */ /* tree->rates->nd_t[i]); */ /* } */ For(i,tree->n_otu) { if(!tree->a_nodes[i]->name) tree->a_nodes[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(tree->a_nodes[i]->name,"x"); sprintf(tree->a_nodes[i]->name+1,"%d",i); } tree->n_root->v[1]->v[0] = tree->n_root->v[2]; tree->n_root->v[2]->v[0] = tree->n_root->v[1]; tree->num_curr_branch_available = 0; Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); tree->e_root = tree->n_root->v[1]->b[0]; For(i,2*tree->n_otu-3) { tree->a_edges[i]->l->v = FABS(tree->rates->nd_t[tree->a_edges[i]->left->num] - tree->rates->nd_t[tree->a_edges[i]->rght->num]); } tree->e_root->l->v = FABS(tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]) + FABS(tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]); tree->n_root->l[1] = FABS(tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]); tree->n_root->l[2] = FABS(tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]); tree->n_root_pos = FABS(tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]) / tree->e_root->l->v; /* printf("\n. %s ",Write_Tree(tree,NO)); */ DR_Draw_Tree("essai.ps",tree); /* For(i,tree->n_otu) */ /* printf("\n. %4s %4d [%5.2f %5.2f]",tree->a_nodes[i]->name, */ /* t->idx_loc[i], */ /* t->ldscape[t->idx_loc[i]*t->n_dim+0], */ /* t->ldscape[t->idx_loc[i]*t->n_dim+1]); */ Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); Free(branching_nodes); Free(p_branch); Free(p_mig); return(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Simualte n coordinates (in 2D) void GEO_Simulate_Coordinates(int n, t_geo *t) { int i; phydbl width; width = 5.; For(i,n) { /* t->ldscape[i*t->n_dim+0] = -width/2. + Uni()*width; */ /* t->ldscape[i*t->n_dim+1] = width/2.; */ t->coord_loc[i]->lonlat[0] = -width/2. + Uni()*width; t->coord_loc[i]->lonlat[1] = width/2.; } /* t->ldscape[0*t->n_dim+0] = 0.0; */ /* t->ldscape[0*t->n_dim+1] = 0.0; */ /* t->ldscape[1*t->n_dim+0] = 0.1; */ /* t->ldscape[1*t->n_dim+1] = 0.1; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Optimize_Sigma(t_geo *t, t_tree *tree) { Generic_Brent_Lk(&(t->sigma), t->min_sigma, t->max_sigma, 1.E-5, 1000, NO, GEO_Wrap_Lk,NULL,tree,NULL,NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Optimize_Lambda(t_geo *t, t_tree *tree) { Generic_Brent_Lk(&(t->lbda), t->min_lbda, t->max_lbda, 1.E-5, 1000, NO, GEO_Wrap_Lk,NULL,tree,NULL,NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Optimize_Tau(t_geo *t, t_tree *tree) { Generic_Brent_Lk(&(t->tau), t->min_tau, t->max_tau, 1.E-5, 1000, NO, GEO_Wrap_Lk,NULL,tree,NULL,NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl GEO_Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree) { return GEO_Lk(tree->geo,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Init_Geo_Struct(t_geo *t) { t->c_lnL = UNLIKELY; t->sigma = 1.0; t->min_sigma = 1.E-3; t->max_sigma = 1.E+3; t->sigma_thresh = t->max_sigma; t->lbda = 1.0; t->min_lbda = 1.E-3; t->max_lbda = 1.E+3; t->tau = 1.0; t->min_tau = 1.E-3; t->max_tau = 1.E+3; t->dum = 1.0; t->min_dum = 1.E-3; t->max_dum = 1.E+3; t->n_dim = 2; t->ldscape_sz = 1; t->update_fmat = YES; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree) { if(n->tax == YES) return; else { t_node *v1, *v2; int i; phydbl *probs; // vector of probability of picking each location phydbl sum; phydbl u; probs = (phydbl *)mCalloc(t->ldscape_sz,sizeof(phydbl)); v1 = v2 = NULL; For(i,3) { if(n->v[i] != n->anc && n->b[i] != tree->e_root) { if(!v1) v1 = n->v[i]; else v2 = n->v[i]; } } if(v1->tax && v2->tax) { Free(probs); return; } else if(v1->tax && !v2->tax && t->idx_loc[v1->num] != t->idx_loc[n->num]) { t->idx_loc[v2->num] = t->idx_loc[n->num]; } else if(v2->tax && !v1->tax && t->idx_loc[v2->num] != t->idx_loc[n->num]) { t->idx_loc[v1->num] = t->idx_loc[n->num]; } else if(v1->tax && !v2->tax && t->idx_loc[v1->num] == t->idx_loc[n->num]) { sum = 0.0; For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i]; For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum; t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz); } else if(v2->tax && !v1->tax && t->idx_loc[v2->num] == t->idx_loc[n->num]) { sum = 0.0; For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i]; For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum; t->idx_loc[v1->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz); } else { int n_v1, n_v2; phydbl p; n_v1 = t->idx_loc_beneath[v1->num * t->ldscape_sz + t->idx_loc[n->num]]; n_v2 = t->idx_loc_beneath[v2->num * t->ldscape_sz + t->idx_loc[n->num]]; if(n_v1 + n_v2 < 1) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } p = n_v1 / (n_v1 + n_v2); u = Uni(); if(u < p) { sum = 0.0; For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i]; For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum; t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz); t->idx_loc[v1->num] = t->idx_loc[n->num]; } else { if(t->idx_loc_beneath[v2->num * t->ldscape_sz + t->idx_loc[n->num]] > 0) { sum = 0.0; For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v1->num * t->ldscape_sz + i]; For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v1->num * t->ldscape_sz + i]/sum; t->idx_loc[v1->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz); t->idx_loc[v2->num] = t->idx_loc[n->num]; } else { sum = 0.0; For(i,t->ldscape_sz) sum += t->idx_loc_beneath[v2->num * t->ldscape_sz + i]; For(i,t->ldscape_sz) probs[i] = t->idx_loc_beneath[v2->num * t->ldscape_sz + i]/sum; t->idx_loc[v2->num] = Sample_i_With_Proba_pi(probs,t->ldscape_sz); t->idx_loc[v1->num] = t->idx_loc[n->num]; } } if(t->idx_loc[v1->num] != t->idx_loc[n->num] && t->idx_loc[v2->num] != t->idx_loc[n->num]) { PhyML_Printf("\n. %d %d %d",t->idx_loc[v1->num],t->idx_loc[v2->num],t->idx_loc[n->num]); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(t->idx_loc_beneath[v1->num * t->ldscape_sz + t->idx_loc[v1->num]] < 1) { PhyML_Printf("\n. %d %d %d",t->idx_loc[v1->num],t->idx_loc[v2->num],t->idx_loc[n->num]); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(t->idx_loc_beneath[v2->num * t->ldscape_sz + t->idx_loc[v2->num]] < 1) { PhyML_Printf("\n. %d %d %d",t->idx_loc[v1->num],t->idx_loc[v2->num],t->idx_loc[n->num]); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } Free(probs); For(i,3) if(n->v[i] != n->anc && n->b[i] != tree->e_root) GEO_Randomize_Locations(n->v[i],t,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Get_Locations_Beneath(t_geo *t, t_tree *tree) { int i; GEO_Get_Locations_Beneath_Post(tree->n_root,tree->n_root->v[1],t,tree); GEO_Get_Locations_Beneath_Post(tree->n_root,tree->n_root->v[2],t,tree); For(i,t->ldscape_sz) { t->idx_loc_beneath[tree->n_root->num*t->ldscape_sz+i] = t->idx_loc_beneath[tree->n_root->v[1]->num*t->ldscape_sz+i] + t->idx_loc_beneath[tree->n_root->v[2]->num*t->ldscape_sz+i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Get_Locations_Beneath_Post(t_node *a, t_node *d, t_geo *t, t_tree *tree) { if(d->tax) { t->idx_loc_beneath[d->num*t->ldscape_sz+t->idx_loc[d->num]] = 1; return; } else { int i; t_node *v1, *v2; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { GEO_Get_Locations_Beneath_Post(d,d->v[i],t,tree); } } v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } } For(i,t->ldscape_sz) { t->idx_loc_beneath[ d->num*t->ldscape_sz+i] = t->idx_loc_beneath[v1->num*t->ldscape_sz+i] + t->idx_loc_beneath[v2->num*t->ldscape_sz+i] ; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Get_Sigma_Max(t_geo *t) { int i,j; phydbl mean_dist,inv_mean_dist; phydbl sigma_a, sigma_b, sigma_c; phydbl overlap_a, overlap_b, overlap_c; phydbl d_intersect; phydbl overlap_target; phydbl eps; int n_iter,n_iter_max; eps = 1.E-6; overlap_target = 0.95; n_iter_max = 100; mean_dist = -1.; inv_mean_dist = -1.; For(i,t->ldscape_sz-1) { for(j=i+1;jldscape_sz;j++) { /* dist = POW(t->ldscape[i*t->n_dim+0] - t->ldscape[j*t->n_dim+0],1); */ /* if(dist > mean_dist) mean_dist = dist; */ /* dist = POW(t->ldscape[i*t->n_dim+1] - t->ldscape[j*t->n_dim+1],1); */ /* if(dist > mean_dist) mean_dist = dist; */ /* mean_dist += FABS(t->ldscape[i*t->n_dim+0] - t->ldscape[j*t->n_dim+0]); */ /* mean_dist += FABS(t->ldscape[i*t->n_dim+1] - t->ldscape[j*t->n_dim+1]); */ mean_dist += FABS(t->coord_loc[i]->lonlat[0] - t->coord_loc[j]->lonlat[0]); mean_dist += FABS(t->coord_loc[i]->lonlat[1] - t->coord_loc[j]->lonlat[1]); } } mean_dist /= t->ldscape_sz*(t->ldscape_sz-1)/2.; inv_mean_dist = 1./mean_dist; PhyML_Printf("\n. Mean distance between locations: %f",mean_dist); sigma_a = t->min_sigma; sigma_b = 1.0; sigma_c = t->max_sigma; /* sigma_a = t->min_sigma; sigma_b = 1.0; sigma_c = 10.; */ n_iter = 0; do { d_intersect = Inverse_Truncated_Normal(inv_mean_dist,0.0,sigma_a,0.0,mean_dist); overlap_a = (Pnorm(mean_dist,0.0,sigma_a) - Pnorm(d_intersect,0.0,sigma_a))/ (Pnorm(mean_dist,0.0,sigma_a) - Pnorm(0.0,0.0,sigma_a)) + d_intersect / mean_dist; /* printf("\n. inter: %f %f [%f]",d_intersect,mean_dist,d_intersect / mean_dist); */ d_intersect = Inverse_Truncated_Normal(inv_mean_dist,0.0,sigma_b,0.0,mean_dist); overlap_b = (Pnorm(mean_dist,0.0,sigma_b) - Pnorm(d_intersect,0.0,sigma_b))/ (Pnorm(mean_dist,0.0,sigma_b) - Pnorm(0.0,0.0,sigma_b)) + d_intersect / mean_dist; /* printf("\n. inter: %f %f [%f]",d_intersect,mean_dist,d_intersect / mean_dist); */ d_intersect = Inverse_Truncated_Normal(inv_mean_dist,0.0,sigma_c,0.0,mean_dist); overlap_c = (Pnorm(mean_dist,0.0,sigma_c) - Pnorm(d_intersect,0.0,sigma_c))/ (Pnorm(mean_dist,0.0,sigma_c) - Pnorm(0.0,0.0,sigma_c)) + d_intersect / mean_dist; /* printf("\n. inter: %f %f [%f]",d_intersect,mean_dist,d_intersect / mean_dist); */ /* printf("\n. sigma_a:%f overlap_a:%f sigma_b:%f overlap_b:%f sigma_c:%f overlap_c:%f", */ /* sigma_a,overlap_a, */ /* sigma_b,overlap_b, */ /* sigma_c,overlap_c); */ if(overlap_target > overlap_a && overlap_target < overlap_b) { sigma_c = sigma_b; sigma_b = sigma_a + (sigma_c - sigma_a)/2.; } else if(overlap_target > overlap_b && overlap_target < overlap_c) { sigma_a = sigma_b; sigma_b = sigma_a + (sigma_c - sigma_a)/2.; } else if(overlap_target < overlap_a) { sigma_a /= 2.; } else if(overlap_target > overlap_c) { sigma_c *= 2.; } n_iter++; } while(sigma_c - sigma_a > eps && n_iter < n_iter_max); /* if(sigma_c - sigma_a > eps) */ /* { */ /* PhyML_Printf("\n== Error detected in getting maximum value of sigma."); */ /* PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ /* } */ /* else */ /* { */ /* PhyML_Printf("\n== Threshold for sigma: %f",sigma_b); */ /* } */ t->sigma_thresh = sigma_b; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Geo_Updown_Tau_Lbda(t_tree *tree) { phydbl K,mult,u,alpha,ratio; phydbl cur_lnL,new_lnL; phydbl cur_tau,new_tau; phydbl cur_lbda,new_lbda; K = tree->mcmc->tune_move[tree->mcmc->num_move_geo_updown_tau_lbda]; cur_lnL = tree->geo->c_lnL; new_lnL = tree->geo->c_lnL; cur_tau = tree->geo->tau; new_tau = tree->geo->tau; cur_lbda = tree->geo->lbda; new_lbda = tree->geo->lbda; u = Uni(); mult = EXP(K*(u-0.5)); /* Multiply tau by K */ new_tau = cur_tau * K; /* Divide lbda by same amount */ new_lbda = cur_lbda / K; if( new_lbda < tree->geo->min_lbda || new_lbda > tree->geo->max_lbda || new_tau < tree->geo->min_tau || new_tau > tree->geo->max_tau ) { tree->mcmc->run_move[tree->mcmc->num_move_geo_updown_tau_lbda]++; return; } tree->geo->tau = new_tau; tree->geo->lbda = new_lbda; if(tree->mcmc->use_data) new_lnL = GEO_Lk(tree->geo,tree); ratio = 0.0; /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */ ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */ /* Likelihood density ratio */ ratio += (new_lnL - cur_lnL); /* printf("\n. new_tau: %f new_lbda:%f cur_lnL:%f new_lnL:%f",new_tau,new_lbda,cur_lnL,new_lnL); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->geo->tau = cur_tau; tree->geo->lbda = cur_lbda; tree->geo->c_lnL = cur_lnL; } else { tree->mcmc->acc_move[tree->mcmc->num_move_geo_updown_tau_lbda]++; } tree->mcmc->run_move[tree->mcmc->num_move_geo_updown_tau_lbda]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Geo_Updown_Lbda_Sigma(t_tree *tree) { phydbl K,mult,u,alpha,ratio; phydbl cur_lnL,new_lnL; phydbl cur_lbda,new_lbda; phydbl cur_sigma,new_sigma; K = tree->mcmc->tune_move[tree->mcmc->num_move_geo_updown_lbda_sigma]; cur_lnL = tree->geo->c_lnL; new_lnL = tree->geo->c_lnL; cur_lbda = tree->geo->lbda; new_lbda = tree->geo->lbda; cur_sigma = tree->geo->sigma; new_sigma = tree->geo->sigma; u = Uni(); mult = EXP(K*(u-0.5)); /* Multiply lbda by K */ new_lbda = cur_lbda * K; /* Divide sigma by same amount */ new_sigma = cur_sigma / K; if( new_sigma < tree->geo->min_sigma || new_sigma > tree->geo->max_sigma || new_lbda < tree->geo->min_lbda || new_lbda > tree->geo->max_lbda ) { tree->mcmc->run_move[tree->mcmc->num_move_geo_updown_lbda_sigma]++; return; } tree->geo->lbda = new_lbda; tree->geo->sigma = new_sigma; if(tree->mcmc->use_data) new_lnL = GEO_Lk(tree->geo,tree); ratio = 0.0; /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */ ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */ /* Likelihood density ratio */ ratio += (new_lnL - cur_lnL); /* printf("\n. new_lbda: %f new_sigma:%f cur_lnL:%f new_lnL:%f",new_lbda,new_sigma,cur_lnL,new_lnL); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->geo->lbda = cur_lbda; tree->geo->sigma = cur_sigma; tree->geo->c_lnL = cur_lnL; } else { tree->mcmc->acc_move[tree->mcmc->num_move_geo_updown_lbda_sigma]++; } tree->mcmc->run_move[tree->mcmc->num_move_geo_updown_lbda_sigma]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Read_In_Landscape(char *file_name, t_geo *t, phydbl **ldscape, int **loc_hash, t_tree *tree) { FILE *fp; char *s; phydbl longitude, lattitude; int tax,loc; PhyML_Printf("\n"); PhyML_Printf("\n. Reading landscape file '%s'.\n",file_name); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); (*ldscape) = (phydbl *)mCalloc(10*t->n_dim,sizeof(phydbl)); (*loc_hash) = (int *)mCalloc(tree->n_otu,sizeof(int)); fp = Openfile(file_name,0); tax = loc = -1; t->ldscape_sz = 0; do { if(fscanf(fp,"%s",s) == EOF) break; if(strlen(s) > 0) For(tax,tree->n_otu) if(!strcmp(tree->a_nodes[tax]->name,s)) break; if(tax == tree->n_otu) { PhyML_Printf("\n== Could not find a taxon with name '%s' in the tree provided.",s); /* PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ continue; } /* sscanf(line+pos,"%lf %lf",&longitude,&lattitude); */ if(fscanf(fp,"%lf",&longitude) == EOF) break; if(fscanf(fp,"%lf",&lattitude) == EOF) break; /* printf("\n. s: %s %f %f",s,longitude,lattitude); */ For(loc,t->ldscape_sz) { if(FABS(longitude-(*ldscape)[loc*t->n_dim+0]) < 1.E-10 && FABS(lattitude-(*ldscape)[loc*t->n_dim+1]) < 1.E-10) { break; } } if(loc == t->ldscape_sz) { t->ldscape_sz++; (*ldscape)[(t->ldscape_sz-1)*t->n_dim+0] = longitude; (*ldscape)[(t->ldscape_sz-1)*t->n_dim+1] = lattitude; if(!(t->ldscape_sz%10)) { (*ldscape) = (phydbl *)mRealloc((*ldscape),(t->ldscape_sz+10)*t->n_dim,sizeof(phydbl)); } } (*loc_hash)[tax] = loc; } while(1); For(tax,tree->n_otu) PhyML_Printf("\n. Taxon %30s, longitude: %12f, lattitude: %12f [%4d]", tree->a_nodes[tax]->name, (*ldscape)[(*loc_hash)[tax]*t->n_dim+0], (*ldscape)[(*loc_hash)[tax]*t->n_dim+1], (*loc_hash)[tax]); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/geo.h000066400000000000000000000034011263450375500143670ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef GEO_H #define GEO_H #include "utilities.h" int GEO_Main(int argc, char **argv); void Free_Geo(t_geo *t); void GEO_Update_Fmat(t_geo *t); void GEO_Update_Sorted_Nd(t_geo *t,t_tree *tree); void GEO_Update_Occup(t_geo *t,t_tree *tree); void GEO_Update_Rmat(t_node *n,t_geo *t,t_tree *tree); phydbl GEO_Lk(t_geo *t,t_tree *tree); void GEO_Init_Tloc_Tips(t_geo *t,t_tree *tree); phydbl GEO_Total_Migration_Rate(t_node *n,t_geo *t); int GEO_Get_Arrival_Location(t_node *n,t_geo *t,t_tree *tree); void GEO_Simulate_Coordinates(int n, t_geo *t); t_tree *GEO_Simulate(t_geo *t, int n_otu); void GEO_Optimize_Sigma(t_geo *t, t_tree *tree); phydbl GEO_Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree); void GEO_Optimize_Lambda(t_geo *t, t_tree *tree); void GEO_Init_Geo_Struct(t_geo *t); void GEO_Optimize_Tau(t_geo *t, t_tree *tree); void GEO_Get_Locations_Beneath(t_geo *t, t_tree *tree); void GEO_Get_Locations_Beneath_Post(t_node *a, t_node *d, t_geo *t, t_tree *tree); void GEO_Randomize_Locations_Pre(t_node *n, t_geo *t, t_tree *tree); void GEO_Randomize_Locations(t_node *n, t_geo *t, t_tree *tree); void GEO_Get_Sigma_Max(t_geo *t); void MCMC_Geo_Updown_Tau_Lbda(t_tree *tree); void MCMC_Geo_Updown_Lbda_Sigma(t_tree *tree); int GEO_Simulate_Estimate(int argc, char **argv); void GEO_Read_In_Landscape(char *file_name, t_geo *t, phydbl **ldscape, int **loc_hash, t_tree *tree); int GEO_Estimate(int argc, char **argv); phydbl *GEO_MCMC(t_tree *tree); #endif phyml-3.2.0/src/help.c000066400000000000000000000361441263450375500145520ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "help.h" /* int T_MAX_FILE; */ /* phydbl SMALL; */ /* phydbl UNLIKELY; */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Usage() { char *BOLD=(char *)mCalloc(10,sizeof(char)); char *FLAT=(char *)mCalloc(10,sizeof(char)); char *LINE=(char *)mCalloc(10,sizeof(char)); char *cha; cha =getenv("OS"); if(cha!=NULL) { strcpy(BOLD, ""); strcpy(FLAT, ""); strcpy(LINE, ""); } else { strcpy(BOLD, "\033[00;01m"); strcpy(FLAT, "\033[00;00m"); strcpy(LINE, "\033[00;04m"); } #ifdef PHYML PhyML_Printf("%sNAME\n" "%s\t- PhyML %s - \n\n" "%s\t\''A simple, fast, and accurate algorithm to estimate\n" "%s\tlarge phylogenies by maximum likelihood\''\n\n" "%s\tStephane Guindon and Olivier Gascuel,\n" "%s\tSystematic Biology 52(5):696-704, 2003.\n\n" "%s\tPlease cite this paper if you use this software in your publications.\n",BOLD,FLAT,VERSION,FLAT,FLAT,FLAT,FLAT,FLAT); #endif #ifdef PHYTIME PhyML_Printf("%sNAME\n" "%s\t- PhyTime %s - \n\n" "%s\t'Bayesian estimation of divergence times from large sequence alignments.'\n" "%s\tStephane Guindon,\n" "%s\tMolecular Biology and Evolution 27(8):1768-81, 2010.\n\n" "%s\tPlease cite this paper if you use this software in your publications.\n",BOLD,FLAT,VERSION,FLAT,FLAT,FLAT,FLAT,FLAT); #endif #ifdef PHYML PhyML_Printf("%s\nSYNOPSIS:\n\n" "%s\tphyml %s[command args]\n",BOLD,BOLD,BOLD); #endif #ifdef PHYTIME PhyML_Printf("%s\nSYNOPSIS:\n\n" "%s\tphytime %s[command args]\n",BOLD,BOLD,BOLD); #endif #ifdef PHYML PhyML_Printf("%s\n\tAll the options below are optional (except '%s-i%s' if you want to use the command-line interface).\n\n",FLAT,BOLD,FLAT); #endif #ifdef PHYTIME PhyML_Printf("%s\n\tAll the options below are optional except '%s-i%s','%s-u%s' and '%s--calibration%s'.\n\n",FLAT,BOLD,FLAT,BOLD,FLAT,BOLD,FLAT); #endif PhyML_Printf("%s\nCommand options:\n%s",BOLD,FLAT); PhyML_Printf("\n\t%s-i (or --input) %sseq_file_name%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sseq_file_name%s is the name of the nucleotide or amino-acid sequence file in PHYLIP format.\n",LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t-d (or --datatype) ""%sdata_type%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sdata_type%s is 'nt' for nucleotide (default), 'aa' for amino-acid sequences, or 'generic',\n",LINE,FLAT); PhyML_Printf("\t\t(use NEXUS file format and the 'symbols' parameter here).\n"); PhyML_Printf("\n"); PhyML_Printf("%s\n\t-q (or --sequential)\n",BOLD); PhyML_Printf("%s\t\tChanges interleaved format (default) to sequential format.\n",FLAT); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t-n (or --multiple) ""%snb_data_sets%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%snb_data_sets%s is an integer corresponding to the number of data sets to analyse.\n",LINE,FLAT); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t-p (or --pars)%s\n",BOLD,FLAT); PhyML_Printf("%s\t\tUse a minimum parsimony starting tree. This option is taken into account when the '-u' option\n",FLAT); PhyML_Printf("%s\t\tis absent and when tree topology modifications are to be done.\n",FLAT); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t-b (or --bootstrap) %sint%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sint%s > 0: %sint%s is the number of bootstrap replicates.\n",LINE,FLAT,LINE,FLAT); PhyML_Printf("\t\t%sint%s = 0: neither approximate likelihood ratio test nor bootstrap values are computed.\n",LINE,FLAT); PhyML_Printf("\t\t%sint%s = -1: approximate likelihood ratio test returning aLRT statistics.\n",LINE,FLAT); PhyML_Printf("\t\t%sint%s = -2: approximate likelihood ratio test returning Chi2-based parametric branch supports.\n",LINE,FLAT); /* PhyML_Printf("\t\t%sint%s = -3 : minimum of Chi2-based parametric and SH-like branch supports.\n",LINE,FLAT); */ PhyML_Printf("\t\t%sint%s = -4: SH-like branch supports alone.\n",LINE,FLAT); PhyML_Printf("\t\t%sint%s = -5: (default) approximate Bayes branch supports.\n",LINE,FLAT); PhyML_Printf("\n"); #endif PhyML_Printf("%s\n\t-m (or --model) %smodel%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tmodel%s : substitution model name.\n",FLAT); PhyML_Printf("\t\t%s- %sNucleotide%s-based models : %sHKY85%s (default) | %sJC69%s | %sK80%s | %sF81%s | %sF84%s | %sTN93%s | %sGTR%s | %scustom (*)%s\n", FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT,LINE,FLAT); PhyML_Printf("\t\t(*) : for the custom option, a string of six digits identifies the model. For instance, 000000\n"); PhyML_Printf("\t\t corresponds to F81 (or JC69 provided the distribution of nucleotide frequencies is uniform).\n"); PhyML_Printf("\t\t 012345 corresponds to GTR. This option can be used for encoding any model that is a nested within GTR.\n"); PhyML_Printf("\n"); PhyML_Printf("\t\t%s- %sAmino-acid%s based models : %sLG%s (default) | %sWAG%s | %sJTT%s | %sMtREV%s | %sDayhoff%s | %sDCMut%s | %sRtREV%s | %sCpREV%s | %sVT%s | %sAB%s\n",FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT); PhyML_Printf("\t\t %sBlosum62%s | %sMtMam%s | %sMtArt%s | %sHIVw%s | %sHIVb%s | %scustom%s\n", LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT, LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t--aa_rate_file %sfilename%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sfilename%s is the name of the file that provides the amino acid substitution rate matrix in PAML format.\n",LINE,FLAT); PhyML_Printf("\t\tIt is compulsory to use this option when analysing amino acid sequences with the `custom' model.\n"); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t-f %se%s, %sm%s, or %sfA,fC,fG,fT%s\n",BOLD,LINE,BOLD,LINE,BOLD,LINE,FLAT); PhyML_Printf("\t\t%se%s : the character frequencies are determined as follows : \n",LINE,FLAT); PhyML_Printf("%s\t\t- %sNucleotide%s sequences: (Empirical) the equilibrium base frequencies are estimated by counting\n" "\t\t the occurence of the different bases in the alignment.\n",FLAT,LINE,FLAT); PhyML_Printf("%s\t\t- %sAmino-acid%s sequences: (Empirical) the equilibrium amino-acid frequencies are estimated by counting\n" "\t\t the occurence of the different amino-acids in the alignment.\n",FLAT,LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("\t\t%sm%s : the character frequencies are determined as follows : \n",LINE,FLAT); PhyML_Printf("%s\t\t- %sNucleotide%s sequences: (ML) the equilibrium base frequencies are estimated using maximum likelihood \n",FLAT,LINE,FLAT); PhyML_Printf("%s\t\t- %sAmino-acid%s sequences: (Model) the equilibrium amino-acid frequencies are estimated using\n" "\t\t the frequencies defined by the substitution model.\n",FLAT,LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("\t\t%s\"fA,fC,fG,fT\"%s : only valid for nucleotide-based models. fA, fC, fG and fT are floating numbers that \n",LINE,FLAT); PhyML_Printf("\t\t correspond to the frequencies of A, C, G and T respectively (WARNING: do not use any blank space between\n"); PhyML_Printf("\t\t your values of nucleotide frequencies, only commas!)\n"); PhyML_Printf("\n"); #endif #ifdef PHYTIME PhyML_Printf("%s\n\t--calibration %sfilename%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sfilename%s is the name of the calibration file that provides a priori defined boundaries for node ages.\n",LINE,FLAT); PhyML_Printf("\t\tPlease read the manual for more information about the format of this file.\n"); PhyML_Printf("\n"); #endif PhyML_Printf("%s\n\t-t (or --ts/tv) %sts/tv_ratio%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tts/tv_ratio%s : transition/transversion ratio. DNA sequences only.\n",FLAT); PhyML_Printf("\t\tCan be a fixed positive value (ex:4.0) or %se%s to get the maximum likelihood estimate.\n",LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t-v (or --pinv) %sprop_invar%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tprop_invar%s : proportion of invariable sites.\n",FLAT); PhyML_Printf("\t\tCan be a fixed value in the [0,1] range or %se%s to get the maximum likelihood estimate.\n",LINE,FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t-c (or --nclasses) %snb_subst_cat%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tnb_subst_cat%s : number of relative substitution rate categories. Default : %snb_subst_cat%s=4.\n", FLAT,LINE,FLAT); PhyML_Printf("\t\tMust be a positive integer.\n"); PhyML_Printf("\n"); PhyML_Printf("%s\n\t--freerates (or --free_rates or --freerate or --free_rate)\n",BOLD); PhyML_Printf("\t\t%s FreeRate model of substitution rate variation across sites.\n",FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t-a (or --alpha) %sgamma%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tgamma%s : distribution of the gamma distribution shape parameter.\n",FLAT); PhyML_Printf("\t\tCan be a fixed positive value or %se%s to get the maximum likelihood estimate.\n",LINE,FLAT); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t-s (or --search) %smove%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tTree topology search operation option.\n"); PhyML_Printf("\t\tCan be either %sNNI%s (default, fast) or %sSPR%s (a bit slower than NNI) or %sBEST%s (best of NNI and SPR search).\n",LINE,FLAT,LINE,FLAT,LINE,FLAT); PhyML_Printf("\n"); #endif PhyML_Printf("%s\n\t-u (or --inputtree) %suser_tree_file%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tuser_tree_file%s : starting tree filename. The tree must be in Newick format.\n",FLAT); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t-o %sparams%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tThis option focuses on specific parameter optimisation.\n"); PhyML_Printf("\t\t%sparams%s=tlr : tree topology (t), branch length (l) and rate parameters (r) are optimised.\n",LINE,FLAT); PhyML_Printf("\t\t%sparams%s=tl : tree topology and branch length are optimised.\n",LINE,FLAT); PhyML_Printf("\t\t%sparams%s=lr : branch length and rate parameters are optimised.\n",LINE,FLAT); PhyML_Printf("\t\t%sparams%s=l : branch length are optimised.\n",LINE,FLAT); PhyML_Printf("\t\t%sparams%s=r : rate parameters are optimised.\n",LINE,FLAT); PhyML_Printf("\t\t%sparams%s=n : no parameter is optimised.\n",LINE,FLAT); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t--rand_start%s\n",BOLD,FLAT); PhyML_Printf("\t\tThis option sets the initial tree to random.\n"); PhyML_Printf("\t\tIt is only valid if SPR searches are to be performed.\n"); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t--n_rand_starts %snum%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tnum%s is the number of initial random trees to be used.\n",FLAT); PhyML_Printf("\t\tIt is only valid if SPR searches are to be performed.\n"); PhyML_Printf("\n"); #endif PhyML_Printf("%s\n\t--r_seed %snum%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tnum%s is the seed used to initiate the random number generator.\n",FLAT); PhyML_Printf("\t\tMust be an integer.\n"); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t--print_site_lnl%s\n",BOLD,FLAT); PhyML_Printf("\t\t%sPrint the likelihood for each site in file *_phyml_lk.txt.\n",FLAT); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t--print_trace%s\n",BOLD,FLAT); PhyML_Printf("\t\t%sPrint each phylogeny explored during the tree search process\n",FLAT); PhyML_Printf("\t\t%sin file *_phyml_trace.txt.\n",FLAT); PhyML_Printf("\n"); #endif PhyML_Printf("%s\n\t--run_id %sID_string%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%sAppend the string %sID_string%s at the end of each PhyML output file.\n",FLAT,LINE,FLAT); PhyML_Printf("\t\t%sThis option may be useful when running simulations involving PhyML.\n",FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t--quiet%s\n",BOLD,FLAT); PhyML_Printf("\t\t%sNo interactive question (for running in batch mode) and quiet output.\n",FLAT); PhyML_Printf("\n"); PhyML_Printf("%s\n\t--no_memory_check%s\n",BOLD,FLAT); PhyML_Printf("\t\t%sNo interactive question for memory usage (for running in batch mode). Normal output otherwise.\n",FLAT); PhyML_Printf("\n"); #ifndef PHYTIME PhyML_Printf("%s\n\t--alias_subpatt%s\n",BOLD,FLAT); PhyML_Printf("\t\t%sSite aliasing is generalized at the subtree level. Sometimes lead to faster calculations.\n",FLAT); PhyML_Printf("\t\t%sSee Kosakovsky Pond SL, Muse SV, Sytematic Biology (2004) for an example.\n",FLAT); PhyML_Printf("\n"); #endif #ifndef PHYTIME PhyML_Printf("%s\n\t--boot_progress_display %snum%s (default=20)\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%snum%s is the frequency at which the bootstrap progress bar will be updated.\n",LINE,FLAT); PhyML_Printf("\t\tMust be an integer.\n"); PhyML_Printf("\n"); #endif #ifdef PHYTIME PhyML_Printf("%s\n\t--chain_len %snum%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\t%snum%s is the number of generations or runs of the Markov Chain Monte Carlo. Set to 1E+6 by default. \n",LINE,FLAT); PhyML_Printf("\t\tMust be an integer.\n"); PhyML_Printf("\n"); #endif /* #ifdef PHYTIME */ /* PhyML_Printf("%s\n\t--burnin %snum%s\n",BOLD,LINE,FLAT); */ /* PhyML_Printf("\t\t%snum%s is the number of generations of runs of the Markov Chain Monte Carlo during the 'burnin' period.\n",LINE,FLAT); */ /* PhyML_Printf("\t\t%sSet to 1E+5 by default. Must be an integer. \n",FLAT); */ /* PhyML_Printf("\n"); */ /* #endif */ #ifdef PHYTIME PhyML_Printf("%s\n\t--sample_freq %snum%s\n",BOLD,LINE,FLAT); PhyML_Printf("\t\tThe chain is sampled every %snum%s generations. Set to 1E+3 by default. \n",LINE,FLAT); PhyML_Printf("\t\tMust be an integer.\n"); PhyML_Printf("\n"); #endif #ifdef PHYTIME PhyML_Printf("%s\n\t--no_sequences%s\n",BOLD,FLAT); PhyML_Printf("\t\tUse this option to run the sampler without sequence data.\n"); PhyML_Printf("\n"); #endif #ifdef PHYTIME PhyML_Printf("%s\n\t--fastlk%s\n",BOLD,FLAT); PhyML_Printf("\t\tUse the multivariate normal approximation to the likelihood and speed up calculations\n"); PhyML_Printf("\n"); #endif #ifdef PHYML PhyML_Printf("%sPHYLIP-LIKE INTERFACE\n""%s\n\tYou can also use PhyML with no argument, in this case change the value of\n",BOLD,FLAT); PhyML_Printf("%s\ta parameter by typing its corresponding character as shown on screen.\n\n",FLAT); #endif #ifdef PHYML PhyML_Printf("%sEXAMPLES\n\n" "%s\tDNA interleaved sequence file, default parameters : ""%s ./phyml -i seqs1" "%s\n\tAA interleaved sequence file, default parameters : ""%s ./phyml -i seqs2 -d aa" "%s\n\tAA sequential sequence file, with customization : ""%s ./phyml -i seqs3 -q -d aa -m JTT -c 4 -a e%s\n",BOLD,FLAT,BOLD,FLAT,BOLD,FLAT,BOLD,FLAT); #endif Exit(""); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/help.h000066400000000000000000000007351263450375500145540ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef OPTIONS_H #define OPTIONS_H #include "utilities.h" #include "cl.h" #include "models.h" #include "free.h" #include "interface.h" void Usage(); #endif phyml-3.2.0/src/init.c000066400000000000000000005436741263450375500146000ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "init.h" #ifdef BEAGLE #include "beagle_utils.h" #endif void Init_Eigen_Struct(eigen *this) { this->next = NULL; this->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Scalar_Dbl(scalar_dbl *p) { p->v = -1.; p->onoff = ON; p->next = NULL; p->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Scalar_Int(scalar_int *p) { p->v = -1.; p->next = NULL; p->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Vect_Dbl(int len, vect_dbl *p) { p->len = len; p->next = NULL; p->prev = NULL; p->v = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Vect_Int(int len, vect_int *p) { p->len = len; p->next = NULL; p->prev = NULL; p->v = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_String(t_string *ts) { ts->len = -1.; ts->next = NULL; ts->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Triplet_Struct(triplet *t) { t->next = NULL; t->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Efrq(t_efrq *f) { f->next = NULL; f->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tree(t_tree *tree, int n_otu) { tree->n_otu = n_otu; tree->mat = NULL; tree->n_root = NULL; tree->e_root = NULL; tree->ps_tree = NULL; tree->short_l = NULL; tree->mutmap = NULL; tree->next = NULL; tree->prev = NULL; tree->next = NULL; tree->prev = NULL; tree->mixt_tree = NULL; tree->geo = NULL; tree->is_mixt_tree = NO; tree->tree_num = 0; tree->depth_curr_path = 0; tree->has_bip = NO; tree->n_moves = 0; tree->n_improvements = 0; tree->bl_from_node_stamps = 0; tree->lock_topo = NO; tree->ps_page_number = 0; tree->init_lnL = UNLIKELY; tree->best_lnL = UNLIKELY; tree->old_lnL = UNLIKELY; tree->c_lnL = UNLIKELY; tree->sum_min_sum_scale = .0; tree->n_swap = 0; tree->best_pars = 1E+5; tree->n_pattern = -1; tree->n_root_pos = -1.; tree->write_labels = YES; tree->write_br_lens = YES; tree->print_boot_val = 0; tree->print_alrt_val = 0; tree->num_curr_branch_available = 0; tree->tip_order_score = .0; tree->write_tax_names = YES; tree->update_alias_subpatt = NO; tree->bl_ndigits = 8; tree->n_short_l = 100; tree->norm_scale = 0.0; tree->br_len_recorded = NO; tree->max_spr_depth = 0; tree->apply_lk_scaling = YES; tree->dp = 0; tree->ignore_root = YES; tree->annealing_temp = 0.; tree->both_sides = NO; #ifdef BEAGLE tree->b_inst = UNINITIALIZED; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Edge_Light(t_edge *b, int num) { b->num = num; b->bip_score = 0; b->dist_btw_edges = .0; b->topo_dist_btw_edges = 0; b->has_zero_br_len = NO; b->n_jumps = 0; b->l_var->v = -1.; b->does_exist = YES; b->l->v = -1.; b->bin_cod_num = -1.; b->l->onoff = ON; b->next = NULL; b->prev = NULL; b->next_mixt = NULL; b->prev_mixt = NULL; b->p_lk_left = NULL; b->p_lk_rght = NULL; b->p_lk_loc_left = NULL; b->p_lk_loc_rght = NULL; b->Pij_rr = NULL; b->labels = NULL; b->pars_l = NULL; b->pars_r = NULL; b->ui_l = NULL; b->ui_r = NULL; b->p_pars_l = NULL; b->p_pars_r = NULL; b->n_diff_states_l = NULL; b->n_diff_states_r = NULL; #ifdef BEAGLE b->p_lk_left_idx = num; b->p_lk_rght_idx = UNINITIALIZED; //Will be initialized later when the total number of branches is known (i.e. in Make_Tree_From_Scratch()) b->Pij_rr_idx = num; b->p_lk_tip_idx = UNINITIALIZED; //Will be initialized later only if this branch is connected to a tip #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Node_Light(t_node *n, int num) { n->num = num; n->tax = -1; n->dist_to_root = .0; n->common = 1; n->ext_node = NULL; n->name = NULL; n->ori_name = NULL; n->c_seq = NULL; n->c_seq_anc = NULL; n->y_rank = 0.; n->y_rank_ori = 0.; n->y_rank_max = 0.; n->y_rank_min = 0.; n->anc = NULL; n->rank = 0; n->match_node = NULL; n->id_rank = 0; n->next = NULL; n->prev = NULL; /* n->next = NULL; */ /* n->prev = NULL; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_NNI(nni *a_nni) { a_nni->left = NULL; a_nni->rght = NULL; a_nni->b = NULL; a_nni->init_l = -1.; a_nni->init_lk = .0; a_nni->score = +1.0; a_nni->best_l = -1.; a_nni->swap_node_v1 = NULL; a_nni->swap_node_v2 = NULL; a_nni->swap_node_v3 = NULL; a_nni->swap_node_v4 = NULL; a_nni->lk0 = UNLIKELY; a_nni->lk1 = UNLIKELY; a_nni->lk2 = UNLIKELY; a_nni->l0 = -1.0; a_nni->l1 = -1.0; a_nni->l2 = -1.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Nexus_Format(nexcom **com) { /*****************************/ strcpy(com[0]->name,"dimensions"); com[0]->nparm = 2; com[0]->nxt_token_t = NEXUS_PARM; com[0]->cur_token_t = NEXUS_COM; com[0]->parm[0] = Make_Nexus_Parm(); strcpy(com[0]->parm[0]->name,"ntax"); com[0]->parm[0]->fp = Read_Nexus_Dimensions; com[0]->parm[0]->com = com[0]; com[0]->parm[0]->nxt_token_t = NEXUS_EQUAL; com[0]->parm[0]->cur_token_t = NEXUS_PARM; com[0]->parm[1] = Make_Nexus_Parm(); strcpy(com[0]->parm[1]->name,"nchar"); com[0]->parm[1]->fp = Read_Nexus_Dimensions; com[0]->parm[1]->com = com[0]; com[0]->parm[1]->nxt_token_t = NEXUS_EQUAL; com[0]->parm[1]->cur_token_t = NEXUS_PARM; /*****************************/ strcpy(com[1]->name,"format"); com[1]->nparm = 11; com[1]->nxt_token_t = NEXUS_PARM; com[1]->cur_token_t = NEXUS_COM; com[1]->parm[0] = Make_Nexus_Parm(); strcpy(com[1]->parm[0]->name,"datatype"); com[1]->parm[0]->fp = Read_Nexus_Format; com[1]->parm[0]->com = com[1]; com[1]->parm[0]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[0]->cur_token_t = NEXUS_PARM; com[1]->parm[1] = Make_Nexus_Parm(); strcpy(com[1]->parm[1]->name,"respectcase"); com[1]->parm[1]->fp = Read_Nexus_Format; com[1]->parm[1]->com = com[1]; com[1]->parm[1]->nxt_token_t = NEXUS_PARM; com[1]->parm[1]->cur_token_t = NEXUS_VALUE; com[1]->parm[2] = Make_Nexus_Parm(); strcpy(com[1]->parm[2]->name,"missing"); com[1]->parm[2]->fp = Read_Nexus_Format; com[1]->parm[2]->com = com[1]; com[1]->parm[2]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[2]->cur_token_t = NEXUS_PARM; com[1]->parm[3] = Make_Nexus_Parm(); strcpy(com[1]->parm[3]->name,"gap"); com[1]->parm[3]->fp = Read_Nexus_Format; com[1]->parm[3]->com = com[1]; com[1]->parm[3]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[3]->cur_token_t = NEXUS_PARM; com[1]->parm[4] = Make_Nexus_Parm(); strcpy(com[1]->parm[4]->name,"symbols"); com[1]->parm[4]->fp = Read_Nexus_Format; com[1]->parm[4]->com = com[1]; com[1]->parm[4]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[4]->cur_token_t = NEXUS_PARM; com[1]->parm[5] = Make_Nexus_Parm(); strcpy(com[1]->parm[5]->name,"equate"); com[1]->parm[5]->fp = Read_Nexus_Format; com[1]->parm[5]->com = com[1]; com[1]->parm[5]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[5]->cur_token_t = NEXUS_PARM; com[1]->parm[6] = Make_Nexus_Parm(); strcpy(com[1]->parm[6]->name,"matchchar"); com[1]->parm[6]->fp = Read_Nexus_Format; com[1]->parm[6]->com = com[1]; com[1]->parm[6]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[6]->cur_token_t = NEXUS_PARM; com[1]->parm[7] = Make_Nexus_Parm(); strcpy(com[1]->parm[7]->name,"transpose"); com[1]->parm[7]->fp = Read_Nexus_Format; com[1]->parm[7]->com = com[1]; com[1]->parm[7]->nxt_token_t = NEXUS_PARM; com[1]->parm[7]->cur_token_t = NEXUS_VALUE; com[1]->parm[8] = Make_Nexus_Parm(); strcpy(com[1]->parm[8]->name,"interleave"); com[1]->parm[8]->fp = Read_Nexus_Format; com[1]->parm[8]->com = com[1]; com[1]->parm[8]->nxt_token_t = NEXUS_PARM; com[1]->parm[8]->cur_token_t = NEXUS_VALUE; com[1]->parm[9] = Make_Nexus_Parm(); strcpy(com[1]->parm[9]->name,"items"); com[1]->parm[9]->fp = Read_Nexus_Format; com[1]->parm[9]->com = com[1]; com[1]->parm[9]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[9]->cur_token_t = NEXUS_PARM; com[1]->parm[10] = Make_Nexus_Parm(); strcpy(com[1]->parm[10]->name,"statesformat"); com[1]->parm[10]->fp = Read_Nexus_Format; com[1]->parm[10]->com = com[1]; com[1]->parm[10]->nxt_token_t = NEXUS_EQUAL; com[1]->parm[10]->cur_token_t = NEXUS_PARM; /*****************************/ strcpy(com[2]->name,"eliminate"); com[2]->nparm = 0; com[2]->nxt_token_t = NEXUS_VALUE; com[2]->cur_token_t = NEXUS_COM; /*****************************/ strcpy(com[3]->name,"taxlabels"); com[3]->nparm = 0; com[3]->nxt_token_t = -1; com[3]->cur_token_t = -1; /*****************************/ strcpy(com[4]->name,"charstatelabels"); com[4]->nparm = 0; com[4]->nxt_token_t = -1; com[4]->cur_token_t = -1; /*****************************/ strcpy(com[5]->name,"charlabels"); com[5]->nparm = 0; com[5]->nxt_token_t = -1; com[5]->cur_token_t = -1; /*****************************/ strcpy(com[6]->name,"statelabels"); com[6]->nparm = 0; com[6]->nxt_token_t = -1; com[6]->cur_token_t = -1; /*****************************/ strcpy(com[7]->name,"matrix"); com[7]->nparm = 1; com[7]->nxt_token_t = NEXUS_COM; com[7]->cur_token_t = NEXUS_VALUE; /* This will allow us to skip directly to the matrix reading function */ com[7]->parm[0] = Make_Nexus_Parm(); strcpy(com[7]->parm[0]->name,"matrix"); com[7]->parm[0]->fp = Read_Nexus_Matrix; com[7]->parm[0]->com = com[7]; com[7]->parm[0]->nxt_token_t = NEXUS_COM; com[7]->parm[0]->cur_token_t = -1; /*****************************/ strcpy(com[8]->name,"begin"); com[8]->nparm = 3; com[8]->nxt_token_t = NEXUS_PARM; com[8]->cur_token_t = NEXUS_COM; com[8]->parm[0] = Make_Nexus_Parm(); strcpy(com[8]->parm[0]->name,"data"); com[8]->parm[0]->fp = Read_Nexus_Begin; com[8]->parm[0]->com = com[8]; com[8]->parm[0]->nxt_token_t = NEXUS_COM; com[8]->parm[0]->cur_token_t = NEXUS_PARM; com[8]->parm[1] = Make_Nexus_Parm(); strcpy(com[8]->parm[1]->name,"trees"); com[8]->parm[1]->fp = Read_Nexus_Begin; com[8]->parm[1]->com = com[8]; com[8]->parm[1]->nxt_token_t = NEXUS_COM; com[8]->parm[1]->cur_token_t = NEXUS_PARM; com[8]->parm[2] = Make_Nexus_Parm(); strcpy(com[8]->parm[2]->name,"taxa"); com[8]->parm[2]->fp = Read_Nexus_Taxa; com[8]->parm[2]->com = com[8]; com[8]->parm[2]->nxt_token_t = NEXUS_COM; com[8]->parm[2]->cur_token_t = NEXUS_VALUE; /*****************************/ strcpy(com[9]->name,"end"); com[9]->nparm = 0; com[9]->nxt_token_t = -1; com[9]->cur_token_t = -1; /*****************************/ strcpy(com[10]->name,"translate"); com[10]->nparm = 1; com[10]->nxt_token_t = NEXUS_COM; com[10]->cur_token_t = NEXUS_VALUE; com[10]->parm[0] = Make_Nexus_Parm(); strcpy(com[10]->parm[0]->name,"translate"); com[10]->parm[0]->fp = Read_Nexus_Translate; com[10]->parm[0]->com = com[10]; com[10]->parm[0]->nxt_token_t = NEXUS_COM; com[10]->parm[0]->cur_token_t = -1; /*****************************/ strcpy(com[11]->name,"tree"); com[11]->nparm = 1; com[11]->nxt_token_t = NEXUS_COM; com[11]->cur_token_t = NEXUS_VALUE; com[11]->parm[0] = Make_Nexus_Parm(); strcpy(com[11]->parm[0]->name,"tree"); com[11]->parm[0]->fp = Read_Nexus_Tree; com[11]->parm[0]->com = com[11]; com[11]->parm[0]->nxt_token_t = -1; com[11]->parm[0]->cur_token_t = -1; /*****************************/ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Mat(matrix *mat, calign *data) { int i; mat->n_otu = data->n_otu; mat->r = mat->n_otu; mat->curr_int = mat->n_otu; mat->method = 1; For(i,data->n_otu) { strcpy(mat->name[i],data->c_seq[i]->name); mat->on_off[i] = 1; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Defaults_Input(option* io) { io->fp_in_align = NULL; io->fp_in_tree = NULL; io->fp_in_constraint_tree = NULL; io->fp_out_tree = NULL; io->fp_out_trees = NULL; io->fp_out_boot_tree = NULL; io->fp_out_boot_stats = NULL; io->fp_out_stats = NULL; io->fp_out_ancestral = NULL; io->fp_in_coord = NULL; io->long_tax_names = NULL; io->short_tax_names = NULL; io->lon = NULL; io->lat = NULL; io->z_scores = NULL; io->cstr_tree = NULL; io->next = NULL; io->prev = NULL; io->tree = NULL; io->mod = NULL; strcpy(io->nt_or_cd,"nucleotides"); io->n_data_sets = 1; io->interleaved = 1; io->in_tree = 0; io->out_tree_file_open_mode = 1; io->out_stats_file_open_mode = 1; io->init_len = -1; io->n_otu = -1; io->n_data_set_asked = -1; io->print_boot_trees = 1; io->n_part = 1; io->ratio_test = ABAYES; io->multigene = 0; io->config_multigene = 0; io->curr_interface = 0; io->r_seed = -1; io->collapse_boot = 0; io->random_boot_seq_order = YES; io->print_trace = 0; io->print_site_lnl = 0; io->m4_model = NO; io->rm_ambigu = 0; io->append_run_ID = 0; io->quiet = 0; io->datatype = NT; io->colalias = YES; io->data_file_format = PHYLIP; io->tree_file_format = PHYLIP; io->boot_prog_every = 20; io->mem_question = YES; io->do_alias_subpatt = NO; io->lk_approx = EXACT; io->codpos = -1; io->mutmap = NO; io->state_len = 1; io->ancestral = NO; io->use_xml = NO; #ifdef BEAGLE io->beagle_resource = 0; #endif MCMC_Init_MCMC_Struct(NULL,io,io->mcmc); RATES_Init_Rate_Struct(io->rates,NULL,-1); io->rates->model = GUINDON; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Rmat(t_rmat *rmat) { rmat->n_diff_rr = 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Defaults_Model(t_mod *mod) { Set_Defaults_Ras(mod->ras); strcpy(mod->modelname->s,"HKY85"); strcpy(mod->custom_mod_string->s,"000000"); mod->next = NULL; mod->prev = NULL; mod->next_mixt = NULL; mod->prev_mixt = NULL; mod->r_mat = NULL; mod->e_frq = NULL; mod->whichmodel = HKY85; mod->n_mixt_classes = 0; mod->mod_num = 0; mod->update_eigen = NO; mod->is_mixt_mod = NO; mod->kappa->v = 4.0; mod->lambda->v = 1.0; mod->l_var_sigma = 1.E-2; mod->e_frq_weight->v = 1.0; mod->r_mat_weight->v = 1.0; mod->bootstrap = 0; mod->ns = 4; mod->use_m4mod = NO; mod->ras->gamma_median = NO; mod->m4mod = NULL; /* mod->r_mat->n_diff_rr = 0; */ /* mod->r_mat->rr = NULL; */ /* mod->r_mat->rr_val = NULL; */ /* mod->r_mat->n_rr_per_cat = NULL; */ mod->io = NULL; mod->log_l = NO; mod->gamma_mgf_bl = NO; mod->br_len_mult->v = 1.0; #if !(defined PHYTIME || defined INVITEE) mod->l_min = 1.E-8; mod->l_max = 10.0; /* mod->l_min = 1.E-4; */ /* mod->l_max = 2.0; */ #else mod->l_min = 1.E-8; mod->l_max = 2.0; #endif mod->l_var_min = mod->l_min; mod->l_var_max = mod->l_max; mod->br_len_mult->v = 1.0; mod->br_len_mult_unscaled->v = 1.0; mod->augmented = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Defaults_Ras(t_ras *ras) { ras->n_catg = 4; ras->normalise_rr = YES; ras->pinvar->v = 0.0; ras->alpha->v = 1.0; ras->invar = NO; ras->free_mixt_rates = NO; ras->parent_class_number = 0; ras->init_r_proba = YES; ras->init_rr = YES; ras->sort_rate_classes = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Defaults_Optimiz(t_opt *s_opt) { s_opt->print = YES; s_opt->last_opt = YES; s_opt->opt_subst_param = YES; s_opt->opt_alpha = YES; s_opt->opt_kappa = YES; s_opt->opt_bl = YES; s_opt->opt_lambda = NO; s_opt->opt_pinvar = NO; s_opt->opt_cov_delta = NO; s_opt->opt_cov_alpha = NO; s_opt->opt_cov_free_rates = NO; s_opt->opt_rr = NO; s_opt->init_lk = UNLIKELY; s_opt->n_it_max = 1000; s_opt->opt_topo = YES; s_opt->topo_search = NNI_MOVE; s_opt->random_input_tree = 0; s_opt->n_rand_starts = 5; s_opt->brent_it_max = BRENT_IT_MAX; s_opt->steph_spr = YES; s_opt->user_state_freq = NO; s_opt->opt_br_len_mult = NO; /* s_opt->min_diff_lk_local = 1.E-04; */ /* s_opt->min_diff_lk_global = 1.E-03; */ /* s_opt->min_diff_lk_move = 1.E-02; */ s_opt->min_diff_lk_local = 1.E-02; s_opt->min_diff_lk_global = 1.E-02; s_opt->min_diff_lk_move = 1.E-02; s_opt->p_moves_to_examine = 0.15; s_opt->fast_nni = NO; s_opt->greedy = NO; s_opt->general_pars = NO; s_opt->tree_size_mult = 1; s_opt->opt_five_branch = YES; s_opt->pars_thresh = 5; s_opt->hybrid_thresh = NO; s_opt->quickdirty = NO; s_opt->spr_pars = YES; s_opt->spr_lnL = NO; s_opt->min_depth_path = 0; s_opt->max_depth_path = 20; s_opt->deepest_path = 20; s_opt->max_delta_lnL_spr = 50.; s_opt->br_len_in_spr = 10; s_opt->opt_free_mixt_rates = YES; s_opt->constrained_br_len = NO; s_opt->opt_gamma_br_len = NO; s_opt->first_opt_free_mixt_rates = YES; s_opt->wim_n_rgrft = -1; s_opt->wim_n_globl = -1; s_opt->wim_max_dist = -1; s_opt->wim_n_optim = -1; s_opt->wim_n_best = -1; s_opt->wim_inside_opt = 0; s_opt->opt_rmat_weight = NO; s_opt->opt_efrq_weight = NO; s_opt->skip_tree_traversal = NO; s_opt->serial_free_rates = YES; s_opt->curr_opt_free_rates = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Init_Attribute(xml_attr *attr) { } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Init_Node(xml_node *parent, xml_node *new_node, char *name) { if(name) strcpy(new_node->name,name); new_node->parent = parent ? parent : NULL; new_node->next = NULL; new_node->prev = NULL; new_node->child = NULL; new_node->ds->obj = NULL; new_node->ds->next = NULL; if(parent) { if(!parent->child) { parent->child = new_node; } else { xml_node *node = parent->child; while(node->next) node = node->next; node->next = new_node; new_node->prev = node; } } new_node->attr = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu) { int i; if(existing_rates && (existing_rates->model != -1)) { rates->model = existing_rates->model; } else { rates->model = NONE; } if(rates->model == NONE) rates->model_log_rates = NO; else if(rates->model == THORNE) rates->model_log_rates = YES; else if(rates->model == GUINDON) rates->model_log_rates = YES; else if(rates->model == GAMMA) rates->model_log_rates = NO; else if(rates->model == STRICTCLOCK) rates->model_log_rates = NO; else { PhyML_Printf("\n== Please initialize model properly."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } rates->met_within_gibbs = NO; rates->c_lnL_rates = UNLIKELY; rates->c_lnL_jps = UNLIKELY; rates->adjust_rates = 0; rates->use_rates = 1; rates->lexp = 1.E-3; rates->norm_fact = 1.0; rates->inflate_var = 1.0; rates->nd_t_recorded = NO; rates->br_r_recorded = NO; rates->birth_rate = 1.E-2; rates->birth_rate_min = 1.E-6; rates->birth_rate_max = 1.E+1; if(rates->model_log_rates == YES) { rates->max_rate = LOG(10.); rates->min_rate = -LOG(10.); /* rates->max_rate = MDBL_MAX; */ /* rates->min_rate = -MDBL_MAX; */ } else { rates->max_rate = 10.0; rates->min_rate = 0.0; } /* rates->max_rate = 6.0; */ /* rates->min_rate = 0.0; */ rates->clock_r = 1.E-4; rates->min_clock = 1.E-8; rates->max_clock = 1.E-3; /* rates->clock_r = 3.E-4; */ /* rates->max_clock = 1.E-3; */ /* rates->min_clock = 1.E-5; */ if(rates->model != GAMMA) { rates->nu = 1.E-3; rates->min_nu = 0.0; rates->max_nu = 1.0; } else { rates->nu = 1.E-1; rates->min_nu = 1.E-2; rates->max_nu = 100.0; } /* rates->max_nu = 2.0; */ /* rates->nu = 1.E-4; */ /* rates->max_nu = 1.E-1; */ /* rates->min_nu = 1.E-5; */ rates->min_dt = 0.0; rates->step_rate = 1.E-4; rates->approx = 1; rates->bl_from_rt = NO; rates->update_mean_l = NO; rates->update_cov_l = NO; rates->p_max = 0.01; rates->true_tree_size = 0.0; if(n_otu > 0) { For(i,(2*n_otu-2)*(2*n_otu-2)) rates->cov_l[i] = 0.0; For(i,2*n_otu-2) { rates->n_jps[i] = -1; rates->t_jps[i] = -1; rates->mean_r[i] = 1.0; rates->mean_l[i] = 0.0; rates->cur_l[i] = 0.01; } For(i,2*n_otu-1) { if(rates->model_log_rates == YES) { rates->nd_r[i] = 0.0; rates->br_r[i] = 0.0; } else { rates->nd_r[i] = 1.0; rates->br_r[i] = 1.0; } rates->mean_t[i] = 0.0; rates->nd_t[i] = 0.0; rates->true_t[i] = 0.0; if(i < n_otu) { rates->t_has_prior[i] = YES; rates->t_prior_max[i] = 0.0; rates->t_prior_min[i] = 0.0; } else { rates->t_has_prior[i] = NO; rates->t_prior_max[i] = BIG; rates->t_prior_min[i] = -BIG; } rates->br_do_updt[i] = YES; rates->has_survived[i] = NO; rates->t_rank[i] = i; } } rates->calib = NULL; rates->update_time_norm_const = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_One_Spr(t_spr *a_spr) { a_spr->lnL = UNLIKELY; a_spr->pars = 1E+5; a_spr->depth_path = 0; a_spr->dist = 0; a_spr->init_target_l = -1.; a_spr->init_target_v = -1.; a_spr->l0 = -1.; a_spr->l1 = -1.; a_spr->l2 = -1.; a_spr->v0 = -1.; a_spr->v1 = -1.; a_spr->v2 = -1.; a_spr->n_link = NULL; a_spr->n_opp_to_link = NULL; a_spr->b_opp_to_link = NULL; a_spr->b_target = NULL; a_spr->b_init_target = NULL; a_spr->next = NULL; a_spr->prev = NULL; a_spr->next = NULL; a_spr->prev = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Model(calign *data, t_mod *mod, option *io) { int i,j; phydbl sum,aux; int result; phydbl *dr, *di, *space; #ifdef BEAGLE mod->b_inst = UNINITIALIZED; //prevents calling an uninitialized BEAGLE instance (for ex: prevents Update_Eigen(), Update_RAS(), from calling BEAGLE) mod->optimizing_topology = false; #endif mod->ns = io->mod->ns; if(io->datatype == GENERIC) mod->whichmodel = JC69; /* if(!mod->ras->invar) For(i,data->crunch_len) data->invar[i] = 0; */ dr = (phydbl *)mCalloc( mod->ns,sizeof(phydbl)); di = (phydbl *)mCalloc( mod->ns,sizeof(phydbl)); space = (phydbl *)mCalloc(2*mod->ns,sizeof(phydbl)); if(mod->log_l == YES) { mod->l_min = LOG(mod->l_min); mod->l_max = LOG(mod->l_max); } if(mod->ras->init_r_proba == YES) { For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i] = (phydbl)1./mod->ras->n_catg; For(i,mod->ras->n_catg) mod->ras->gamma_r_proba_unscaled->v[i] = (phydbl)(i+1); } else { mod->ras->gamma_r_proba_unscaled->v[0] = mod->ras->gamma_r_proba->v[0]; for(i=1;iras->n_catg;i++) mod->ras->gamma_r_proba_unscaled->v[i] = mod->ras->gamma_r_proba_unscaled->v[i-1] + mod->ras->gamma_r_proba->v[i]; } if(mod->ras->init_rr == YES) { if(mod->ras->n_catg > 1) { For(i,mod->ras->n_catg) mod->ras->gamma_rr->v[i] = (phydbl)i; For(i,mod->ras->n_catg) mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i; } else { mod->ras->gamma_rr->v[0] = 1.0; mod->ras->gamma_rr_unscaled->v[0] = 1.0; } } /* mod->br_len_mult->v = 1.0; */ /* mod->br_len_mult_unscaled->v = 1.0; */ For(i,mod->ns) { mod->e_frq->pi->v[i] = data->b_frq[i]; mod->e_frq->pi_unscaled->v[i] = mod->e_frq->pi->v[i] * 100.; } if(io->datatype == NT) { /* Set the substitution parameters to their default values if they are not fixed by the user */ if(mod->s_opt->opt_kappa == YES) { mod->kappa->v = 4.0; mod->lambda->v = 1.0; } if(mod->whichmodel == CUSTOM) { For(i,6) mod->r_mat->rr_val->v[i] = 1.0; /* Condition below is true for if custom model corresponds to TN93 or K80 */ if(mod->r_mat->rr_num->v[AC] == mod->r_mat->rr_num->v[AT] && mod->r_mat->rr_num->v[AT] == mod->r_mat->rr_num->v[CG] && mod->r_mat->rr_num->v[CG] == mod->r_mat->rr_num->v[GT] && mod->r_mat->rr_num->v[AG] != mod->r_mat->rr_num->v[AC] && mod->r_mat->rr_num->v[CT] != mod->r_mat->rr_num->v[AC]) { for(i=1;ir_mat->n_diff_rr;i++) mod->r_mat->rr_val->v[i] = 4.0; } else if(mod->r_mat->n_diff_rr == 6) /* Custom <-> GTR model */ { mod->r_mat->rr_val->v[AG] = 4.0; mod->r_mat->rr_val->v[CT] = 4.0; } } else if(mod->whichmodel == GTR) { For(i,6) mod->r_mat->rr_val->v[i] = 1.0; mod->r_mat->rr_val->v[AG] = 4.0; mod->r_mat->rr_val->v[CT] = 4.0; } } if(mod->s_opt->opt_alpha) mod->ras->alpha->v = 1.0; if(mod->s_opt->opt_pinvar) mod->ras->pinvar->v = 0.2; if(io->datatype == NT) /* Nucleotides */ { /* init for nucleotides */ mod->lambda->v = 1.; /* mod->update_eigen = YES; */ if(mod->whichmodel == JC69) { mod->e_frq->pi->v[0] = mod->e_frq->pi->v[1] = mod->e_frq->pi->v[2] = mod->e_frq->pi->v[3] = .25; mod->kappa->v = 1.; mod->s_opt->opt_state_freq = NO; mod->s_opt->opt_kappa = NO; mod->s_opt->opt_lambda = NO; mod->update_eigen = NO; } if(mod->whichmodel == K80) { mod->e_frq->pi->v[0] = mod->e_frq->pi->v[1] = mod->e_frq->pi->v[2] = mod->e_frq->pi->v[3] = .25; mod->s_opt->opt_state_freq = NO; mod->s_opt->opt_lambda = NO; mod->update_eigen = NO; } if(mod->whichmodel == F81) { mod->kappa->v = 1.; mod->update_eigen = NO; } if(mod->whichmodel == F84) { aux = ((mod->e_frq->pi->v[0]+mod->e_frq->pi->v[2])-(mod->e_frq->pi->v[1]+mod->e_frq->pi->v[3]))/(2.*mod->kappa->v); mod->lambda->v = ((mod->e_frq->pi->v[1]+mod->e_frq->pi->v[3]) + aux)/((mod->e_frq->pi->v[0]+mod->e_frq->pi->v[2]) - aux); mod->update_eigen = NO; } if(mod->whichmodel == TN93) { mod->update_eigen = NO; if(io->mod->s_opt->opt_kappa) io->mod->s_opt->opt_lambda = YES; } if(mod->whichmodel == GTR) { mod->kappa->v = 1.; mod->update_eigen = YES; io->mod->s_opt->opt_rr = YES; } if(mod->whichmodel == CUSTOM) { mod->kappa->v = 1.; mod->update_eigen = YES; /* io->mod->s_opt->opt_rr = YES; */ /* What if the user decided not to optimise the rates? */ } if(mod->whichmodel == GTR) { mod->custom_mod_string->s[0] = '0'; mod->custom_mod_string->s[1] = '1'; mod->custom_mod_string->s[2] = '2'; mod->custom_mod_string->s[3] = '3'; mod->custom_mod_string->s[4] = '4'; mod->custom_mod_string->s[5] = '5'; Translate_Custom_Mod_String(mod); } if(mod->s_opt->user_state_freq == YES && mod->whichmodel != JC69 && mod->whichmodel != K80) { For(i,4) { mod->e_frq->pi->v[i] = mod->user_b_freq->v[i]; } } if(((mod->whichmodel == GTR) || (mod->whichmodel == CUSTOM) || (mod->whichmodel == HKY85)) && (mod->use_m4mod == NO)) { mod->update_eigen = YES; Update_Eigen(mod); mod->update_eigen = NO; } /* if((mod->whichmodel != GTR) && */ /* (mod->whichmodel != CUSTOM) && */ /* (mod->whichmodel != HKY85)) mod->update_eigen = NO; */ } else if(mod->io->datatype == AA) { /* init for amino-acids */ /* see comments of PMat_Empirical for details */ /* read pi and Q from file */ /* These initialisations are needed when analysing multiple * data sets */ For(i,mod->ns*mod->ns) mod->r_mat->qmat->v[i] = .0; For(i,mod->ns ) mod->e_frq->pi->v[i] = .0; switch(mod->whichmodel) { case DAYHOFF : { Init_Qmat_Dayhoff(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case JTT : { Init_Qmat_JTT(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case MTREV : { Init_Qmat_MtREV(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case LG : { Init_Qmat_LG(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case WAG : { Init_Qmat_WAG(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case DCMUT : { Init_Qmat_DCMut(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case RTREV : { Init_Qmat_RtREV(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case CPREV : { Init_Qmat_CpREV(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case VT : { Init_Qmat_VT(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case BLOSUM62 : { Init_Qmat_Blosum62(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case MTMAM : { Init_Qmat_MtMam(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case MTART : { Init_Qmat_MtArt(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case HIVW : { Init_Qmat_HIVw(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case HIVB : { Init_Qmat_HIVb(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case AB : { Init_Qmat_AB(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case CUSTOMAA : { if(mod->fp_aa_rate_mat == NULL) { PhyML_Printf("\n. Cannot open custom rate matrix file '%s'.\n",mod->aa_rate_mat_file->s); Exit("\n"); } Read_Qmat(mod->r_mat->qmat->v,mod->e_frq->pi->v,mod->fp_aa_rate_mat); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } case FLU : { Init_Qmat_FLU(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } default : { Init_Qmat_LG(mod->r_mat->qmat->v,mod->e_frq->pi->v); if(mod->s_opt->opt_state_freq) For(i,mod->ns) mod->e_frq->pi->v[i] = data->b_frq[i]; break; } } For(i,mod->ns) if(mod->e_frq->pi->v[i] < 1.E-10) { PhyML_Printf("\n. WARNING: at least one amino-acid frequency is equal to 0.0!"); PhyML_Printf("\n. Numerical precision issues are likely to arise..."); break; } /* /\* multiply the nth col of Q by the nth term of pi/100 just as in PAML *\/ */ For(i,mod->ns) For(j,mod->ns) mod->r_mat->qmat->v[i*mod->ns+j] *= mod->e_frq->pi->v[j] / 100.0; /* compute diagonal terms of Q and mean rate mr = l/t */ mod->mr->v= .0; For (i,mod->ns) { sum=.0; For(j, mod->ns) sum += mod->r_mat->qmat->v[i*mod->ns+j]; mod->r_mat->qmat->v[i*mod->ns+i] = -sum; mod->mr->v += mod->e_frq->pi->v[i] * sum; } /* scale imod->nstantaneous rate matrix so that mu=1 */ For (i,mod->ns*mod->ns) mod->r_mat->qmat->v[i] /= mod->mr->v; /* compute eigenvectors/values */ result = 0; For(i,mod->ns*mod->ns) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i]; if(!Eigen(1,mod->r_mat->qmat_buff->v,mod->eigen->size,mod->eigen->e_val, mod->eigen->e_val_im,mod->eigen->r_e_vect, mod->eigen->r_e_vect_im,mod->eigen->space)) { /* compute inverse(Vr) into Vi */ For (i,mod->ns*mod->ns) mod->eigen->l_e_vect[i] = mod->eigen->r_e_vect[i]; if(!Matinv(mod->eigen->l_e_vect,mod->eigen->size,mod->eigen->size,YES)) { PhyML_Printf("\n== Err in file %s at line %d.",__FILE__,__LINE__); Exit("\n"); } /* compute the diagonal terms of EXP(D) */ For(i,mod->ns) mod->eigen->e_val[i] = (phydbl)EXP(mod->eigen->e_val[i]); } else { if (result==-1) PhyML_Printf("\n== Eigenvalues/vectors computation does not converge : computation cancelled"); else if (result==1) PhyML_Printf("\n== Complex eigenvalues/vectors : computation cancelled"); } } else if(mod->io->datatype == GENERIC) { /* Uniform state frequencies */ For(i,mod->ns) mod->e_frq->pi->v[i] = 1./(phydbl)mod->ns; mod->kappa->v = 1; mod->s_opt->opt_state_freq = NO; mod->s_opt->opt_kappa = NO; mod->s_opt->opt_lambda = NO; mod->update_eigen = NO; } else { PhyML_Printf("\n== Datatype not recognized.\n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(!mod->use_m4mod) Set_Model_Parameters(mod); Init_Eigen_Struct(mod->eigen); free(dr);free(di);free(space); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Init_Qmat_Dayhoff(phydbl *daa, phydbl *pi) { /* Dayhoff's model data * Dayhoff, M.O., Schwartz, R.M., Orcutt, B.C. (1978) * "A model of evolutionary change in proteins." * Dayhoff, M.O.(ed.) Atlas of Protein Sequence Structur., Vol5, Suppl3. * National Biomedical Research Foundation, Washington DC, pp.345-352. */ int i,j,naa; naa = 20; /* PhyML_Printf("\n\n. REMINDER : THIS IS NOT DAYHOFF !!!\n\n"); */ /* daa[1*20 + 0] = 0.538903; */ /* daa[2*20 + 0] = 0.412504; */ /* daa[2*20 + 1] = 0.736081; */ /* daa[3*20 + 0] = 0.586915; */ /* daa[3*20 + 1] = 0.108051; */ /* daa[3*20 + 2] = 5.446642; */ /* daa[4*20 + 0] = 2.189718; */ /* daa[4*20 + 1] = 0.830604; */ /* daa[4*20 + 2] = 0.573426; */ /* daa[4*20 + 3] = 0.077565; */ /* daa[5*20 + 0] = 1.08213; */ /* daa[5*20 + 1] = 2.950693; */ /* daa[5*20 + 2] = 1.739514; */ /* daa[5*20 + 3] = 0.559035; */ /* daa[5*20 + 4] = 0.111314; */ /* daa[6*20 + 0] = 1.386865; */ /* daa[6*20 + 1] = 0.358434; */ /* daa[6*20 + 2] = 0.541447; */ /* daa[6*20 + 3] = 5.406871; */ /* daa[6*20 + 4] = 0.003738; */ /* daa[6*20 + 5] = 4.124043; */ /* daa[7*20 + 0] = 2.085747; */ /* daa[7*20 + 1] = 0.453132; */ /* daa[7*20 + 2] = 1.815844; */ /* daa[7*20 + 3] = 1.08647; */ /* daa[7*20 + 4] = 0.526418; */ /* daa[7*20 + 5] = 0.347693; */ /* daa[7*20 + 6] = 0.438476; */ /* daa[8*20 + 0] = 0.407898; */ /* daa[8*20 + 1] = 2.689322; */ /* daa[8*20 + 2] = 5.386808; */ /* daa[8*20 + 3] = 0.884563; */ /* daa[8*20 + 4] = 0.658583; */ /* daa[8*20 + 5] = 4.588358; */ /* daa[8*20 + 6] = 0.386218; */ /* daa[8*20 + 7] = 0.368668; */ /* daa[9*20 + 0] = 0.10177; */ /* daa[9*20 + 1] = 0.104875; */ /* daa[9*20 + 2] = 0.16239; */ /* daa[9*20 + 3] = 0.011698; */ /* daa[9*20 + 4] = 0.253282; */ /* daa[9*20 + 5] = 0.083872; */ /* daa[9*20 + 6] = 0.041767; */ /* daa[9*20 + 7] = 0.009778; */ /* daa[9*20 + 8] = 0.1042; */ /* daa[10*20 + 0] = 0.248202; */ /* daa[10*20 + 1] = 0.375742; */ /* daa[10*20 + 2] = 0.093863; */ /* daa[10*20 + 3] = 0.019241; */ /* daa[10*20 + 4] = 0.572688; */ /* daa[10*20 + 5] = 0.703538; */ /* daa[10*20 + 6] = 0.071961; */ /* daa[10*20 + 7] = 0.03006; */ /* daa[10*20 + 8] = 0.418222; */ /* daa[10*20 + 9] = 3.702051; */ /* daa[11*20 + 0] = 0.652019; */ /* daa[11*20 + 1] = 5.940478; */ /* daa[11*20 + 2] = 2.352253; */ /* daa[11*20 + 3] = 0.231001; */ /* daa[11*20 + 4] = 0.027995; */ /* daa[11*20 + 5] = 3.646743; */ /* daa[11*20 + 6] = 1.507981; */ /* daa[11*20 + 7] = 0.331175; */ /* daa[11*20 + 8] = 0.698362; */ /* daa[11*20 + 9] = 0.140326; */ /* daa[11*20 + 10] = 0.171396; */ /* daa[12*20 + 0] = 0.694226; */ /* daa[12*20 + 1] = 0.419899; */ /* daa[12*20 + 2] = 0.326927; */ /* daa[12*20 + 3] = 0.039488; */ /* daa[12*20 + 4] = 0.844827; */ /* daa[12*20 + 5] = 1.394214; */ /* daa[12*20 + 6] = 0.133235; */ /* daa[12*20 + 7] = 0.085075; */ /* daa[12*20 + 8] = 0.347092; */ /* daa[12*20 + 9] = 4.051255; */ /* daa[12*20 + 10] = 6.650794; */ /* daa[12*20 + 11] = 0.617549; */ /* daa[13*20 + 0] = 0.155206; */ /* daa[13*20 + 1] = 0.057971; */ /* daa[13*20 + 2] = 0.09816; */ /* daa[13*20 + 3] = 0.020441; */ /* daa[13*20 + 4] = 0.904305; */ /* daa[13*20 + 5] = 0.052719; */ /* daa[13*20 + 6] = 0.0219; */ /* daa[13*20 + 7] = 0.046668; */ /* daa[13*20 + 8] = 0.890005; */ /* daa[13*20 + 9] = 0.844963; */ /* daa[13*20 + 10] = 2.348881; */ /* daa[13*20 + 11] = 0.028372; */ /* daa[13*20 + 12] = 1.671635; */ /* daa[14*20 + 0] = 1.433475; */ /* daa[14*20 + 1] = 0.328393; */ /* daa[14*20 + 2] = 0.173181; */ /* daa[14*20 + 3] = 0.431874; */ /* daa[14*20 + 4] = 0.09902; */ /* daa[14*20 + 5] = 0.592324; */ /* daa[14*20 + 6] = 0.488352; */ /* daa[14*20 + 7] = 0.23865; */ /* daa[14*20 + 8] = 0.462856; */ /* daa[14*20 + 9] = 0.057048; */ /* daa[14*20 + 10] = 0.233532; */ /* daa[14*20 + 11] = 0.387808; */ /* daa[14*20 + 12] = 0.096377; */ /* daa[14*20 + 13] = 0.079912; */ /* daa[15*20 + 0] = 4.887126; */ /* daa[15*20 + 1] = 0.883923; */ /* daa[15*20 + 2] = 4.627163; */ /* daa[15*20 + 3] = 1.122164; */ /* daa[15*20 + 4] = 3.186667; */ /* daa[15*20 + 5] = 1.085947; */ /* daa[15*20 + 6] = 0.569339; */ /* daa[15*20 + 7] = 1.993432; */ /* daa[15*20 + 8] = 0.867972; */ /* daa[15*20 + 9] = 0.070512; */ /* daa[15*20 + 10] = 0.163009; */ /* daa[15*20 + 11] = 0.718913; */ /* daa[15*20 + 12] = 0.301103; */ /* daa[15*20 + 13] = 0.32579; */ /* daa[15*20 + 14] = 1.449582; */ /* daa[16*20 + 0] = 2.030538; */ /* daa[16*20 + 1] = 0.639463; */ /* daa[16*20 + 2] = 2.076294; */ /* daa[16*20 + 3] = 0.377239; */ /* daa[16*20 + 4] = 1.42848; */ /* daa[16*20 + 5] = 0.979403; */ /* daa[16*20 + 6] = 0.647562; */ /* daa[16*20 + 7] = 0.145556; */ /* daa[16*20 + 8] = 0.493329; */ /* daa[16*20 + 9] = 0.973405; */ /* daa[16*20 + 10] = 0.271824; */ /* daa[16*20 + 11] = 1.20033; */ /* daa[16*20 + 12] = 1.659187; */ /* daa[16*20 + 13] = 0.1217; */ /* daa[16*20 + 14] = 0.571399; */ /* daa[16*20 + 15] = 6.641034; */ /* daa[17*20 + 0] = 0.131405; */ /* daa[17*20 + 1] = 0.552911; */ /* daa[17*20 + 2] = 0.079985; */ /* daa[17*20 + 3] = 0.060514; */ /* daa[17*20 + 4] = 0.633662; */ /* daa[17*20 + 5] = 0.21823; */ /* daa[17*20 + 6] = 0.074988; */ /* daa[17*20 + 7] = 0.169114; */ /* daa[17*20 + 8] = 0.847725; */ /* daa[17*20 + 9] = 0.10627; */ /* daa[17*20 + 10] = 0.622044; */ /* daa[17*20 + 11] = 0.060755; */ /* daa[17*20 + 12] = 0.719575; */ /* daa[17*20 + 13] = 3.14824; */ /* daa[17*20 + 14] = 0.077123; */ /* daa[17*20 + 15] = 0.276716; */ /* daa[17*20 + 16] = 0.148883; */ /* daa[18*20 + 0] = 0.165179; */ /* daa[18*20 + 1] = 0.224883; */ /* daa[18*20 + 2] = 0.528334; */ /* daa[18*20 + 3] = 0.121252; */ /* daa[18*20 + 4] = 1.174118; */ /* daa[18*20 + 5] = 0.177062; */ /* daa[18*20 + 6] = 0.074715; */ /* daa[18*20 + 7] = 0.042356; */ /* daa[18*20 + 8] = 5.911187; */ /* daa[18*20 + 9] = 0.192481; */ /* daa[18*20 + 10] = 0.321454; */ /* daa[18*20 + 11] = 0.090556; */ /* daa[18*20 + 12] = 0.406415; */ /* daa[18*20 + 13] = 10.908861; */ /* daa[18*20 + 14] = 0.070752; */ /* daa[18*20 + 15] = 0.328483; */ /* daa[18*20 + 16] = 0.181539; */ /* daa[18*20 + 17] = 3.823886; */ /* daa[19*20 + 0] = 1.78517; */ /* daa[19*20 + 1] = 0.166975; */ /* daa[19*20 + 2] = 0.106482; */ /* daa[19*20 + 3] = 0.041707; */ /* daa[19*20 + 4] = 1.876812; */ /* daa[19*20 + 5] = 0.22421; */ /* daa[19*20 + 6] = 0.247356; */ /* daa[19*20 + 7] = 0.06688; */ /* daa[19*20 + 8] = 0.1436; */ /* daa[19*20 + 9] = 9.60184; */ /* daa[19*20 + 10] = 1.599119; */ /* daa[19*20 + 11] = 0.17319; */ /* daa[19*20 + 12] = 1.645134; */ /* daa[19*20 + 13] = 0.438571; */ /* daa[19*20 + 14] = 0.252486; */ /* daa[19*20 + 15] = 0.105536; */ /* daa[19*20 + 16] = 1.789097; */ /* daa[19*20 + 17] = 0.147951; */ /* daa[19*20 + 18] = 0.200571; */ /* for (i=0; i 2664 (67% of the original 3933 positions) The species included in the analysis were: Harpiosquilla harpax [NCBI_TaxID 287944] Ixodes uriae [NCBI_TaxID 59655] Heptathela hangzhouensis [NCBI_TaxID 216259] Triops longicaudatus [NCBI_TaxID 58777] Gryllotalpa orientalis [NCBI_TaxID 213494] lepidopsocid RS-2001 [NCBI_TaxID 159971] Locusta migratoria [NCBI_TaxID 7004] Drosophila yakuba [NCBI_TaxID 7245] Ostrinia furnacalis [NCBI_TaxID 93504] Megabalanus volcano [NCBI_TaxID 266495] Periplaneta fuliginosa [NCBI_TaxID 36977] Thermobia domestica [NCBI_TaxID 89055] Aleurochiton aceris [NCBI_TaxID 266942] Schizaphis graminum [NCBI_TaxID 13262] Pteronarcys princeps [NCBI_TaxID 285953] Aleurodicus dugesii [NCBI_TaxID 30099] Pollicipes polymerus [NCBI_TaxID 36137] Gomphiocephalus hodgsoni [NCBI_TaxID 221270] Habronattus oregonensis [NCBI_TaxID 130930] Speleonectes tulumensis [NCBI_TaxID 84346] Hutchinsoniella macracantha [NCBI_TaxID 84335] Haemaphysalis flava [NCBI_TaxID 181088] Scutigera coleoptrata [NCBI_TaxID 29022] Vargula hilgendorfii [NCBI_TaxID 6674] Tricholepidion gertschi [NCBI_TaxID 89825] Varroa destructor [NCBI_TaxID 109461] Bombyx mandarina [NCBI_TaxID 7092] Thyropygus sp. [NCBI_TaxID 174155] Tribolium castaneum [NCBI_TaxID 7070] Pagurus longicarpus [NCBI_TaxID 111067] Limulus polyphemus [NCBI_TaxID 6850] Tetrodontophora bielanensis [NCBI_TaxID 48717] Penaeus monodon [NCBI_TaxID 6687] Daphnia pulex [NCBI_TaxID 6669] Apis mellifera [NCBI_TaxID 7469] Anopheles gambiae [NCBI_TaxID 7165] The topology used for inferring the model was: (((Daph_pulex,Trio_longi),((((((Aleu_aceri,Aleu_duges),Schi_grami),lepi_RS_20), ((((Ostr_furna,Bomb_manda),(Dros_yakub,Anop_gambi)),Apis_melli),Trib_casta)), ((Gryl_orien,Locu_migra),(Pter_princ,Peri_fulig))),(Tric_gerts,Ther_domes)), (Scut_coleo,Thyr_sp),Varg_hilge,Hutc_macra,((((Ixod_uriae,Haem_flava),Varr_destr), (Habr_orego,Hept_hangz)),Limu_polyp),(Poll_polym,Mega_volca),(Gomp_hodgs,Tetr_biela), ((Pagu_longi,Pena_monod),Harp_harpa),Spel_tulum)); Note this is not the ML topoLOGy but the consensus one (based on morphoLOGical data, phyLOGenetic reconstruction using nuclear genes, etc). Where relationships are not clear, a polytomy was introduced (it contains quite a lot of polytomies!). The model was estimated using (the great and helpful) Ziheng Yang's Paml software package. A four-categorized gamma distribution was used to account for heterogeneity (alpha was estimated to be 0.47821). Sites with ambiguity data were taken into account. If you would like the data related to this matrix, please contact fabascal@uvigo.es. Federico Abascal (c)2005. */ int i,j,naa; naa = 20; daa[1*20+ 0] = 0.2; daa[2*20+ 0] = 0.2; daa[2*20+ 1] = 0.2; daa[3*20+ 0] = 0.6; daa[3*20+ 1] = 4.3; daa[3*20+ 2] = 500.2; daa[4*20+ 0] = 253.5; daa[4*20+ 1] = 35.5; daa[4*20+ 2] = 98.2; daa[4*20+ 3] = 10.6; daa[5*20+ 0] = 0.2; daa[5*20+ 1] = 154.0; daa[5*20+ 2] = 261.8; daa[5*20+ 3] = 0.2; daa[5*20+ 4] = 0.2; daa[6*20+ 0] = 0.2; daa[6*20+ 1] = 0.2; daa[6*20+ 2] = 183.0; daa[6*20+ 3] = 861.8; daa[6*20+ 4] = 0.2; daa[6*20+ 5] = 261.6; daa[7*20+ 0] = 199.8; daa[7*20+ 1] = 0.2; daa[7*20+ 2] = 120.5; daa[7*20+ 3] = 12.5; daa[7*20+ 4] = 80.5; daa[7*20+ 5] = 2.6; daa[7*20+ 6] = 43.9; daa[8*20+ 0] = 0.2; daa[8*20+ 1] = 41.3; daa[8*20+ 2] = 179.5; daa[8*20+ 3] = 0.2; daa[8*20+ 4] = 12.4; daa[8*20+ 5] = 313.5; daa[8*20+ 6] = 15.2; daa[8*20+ 7] = 0.2; daa[9*20+ 0] = 25.7; daa[9*20+ 1] = 1.8; daa[9*20+ 2] = 21.3; daa[9*20+ 3] = 6.6; daa[9*20+ 4] = 63.0; daa[9*20+ 5] = 10.5; daa[9*20+ 6] = 6.8; daa[9*20+ 7] = 2.7; daa[9*20+ 8] = 0.2; daa[10*20+ 0] = 3.7; daa[10*20+ 1] = 1.8; daa[10*20+ 2] = 12.6; daa[10*20+ 3] = 1.2; daa[10*20+ 4] = 78.7; daa[10*20+ 5] = 16.3; daa[10*20+ 6] = 1.7; daa[10*20+ 7] = 1.4; daa[10*20+ 8] = 5.5; daa[10*20+ 9] = 514.5; daa[11*20+ 0] = 0.2; daa[11*20+ 1] = 208.6; daa[11*20+ 2] = 467.3; daa[11*20+ 3] = 1.7; daa[11*20+ 4] = 0.2; daa[11*20+ 5] = 349.3; daa[11*20+ 6] = 106.3; daa[11*20+ 7] = 0.2; daa[11*20+ 8] = 0.2; daa[11*20+ 9] = 3.5; daa[11*20+ 10] = 3.8; daa[12*20+ 0] = 120.6; daa[12*20+ 1] = 5.2; daa[12*20+ 2] = 78.8; daa[12*20+ 3] = 0.2; daa[12*20+ 4] = 312.3; daa[12*20+ 5] = 67.3; daa[12*20+ 6] = 0.2; daa[12*20+ 7] = 55.7; daa[12*20+ 8] = 0.2; daa[12*20+ 9] = 514.8; daa[12*20+ 10] = 885.5; daa[12*20+ 11] = 105.6; daa[13*20+ 0] = 13.1; daa[13*20+ 1] = 4.7; daa[13*20+ 2] = 19.7; daa[13*20+ 3] = 0.2; daa[13*20+ 4] = 184.1; daa[13*20+ 5] = 0.2; daa[13*20+ 6] = 0.2; daa[13*20+ 7] = 0.8; daa[13*20+ 8] = 13.8; daa[13*20+ 9] = 117.9; daa[13*20+ 10] = 262.6; daa[13*20+ 11] = 10.7; daa[13*20+ 12] = 321.6; daa[14*20+ 0] = 49.3; daa[14*20+ 1] = 0.2; daa[14*20+ 2] = 16.5; daa[14*20+ 3] = 0.2; daa[14*20+ 4] = 0.2; daa[14*20+ 5] = 39.3; daa[14*20+ 6] = 7.9; daa[14*20+ 7] = 0.2; daa[14*20+ 8] = 0.8; daa[14*20+ 9] = 0.2; daa[14*20+ 10] = 12.2; daa[14*20+ 11] = 16.8; daa[14*20+ 12] = 5.3; daa[14*20+ 13] = 14.6; daa[15*20+ 0] = 673.0; daa[15*20+ 1] = 2.7; daa[15*20+ 2] = 398.4; daa[15*20+ 3] = 44.4; daa[15*20+ 4] = 664.2; daa[15*20+ 5] = 52.4; daa[15*20+ 6] = 31.5; daa[15*20+ 7] = 226.0; daa[15*20+ 8] = 10.6; daa[15*20+ 9] = 7.2; daa[15*20+ 10] = 8.2; daa[15*20+ 11] = 144.2; daa[15*20+ 12] = 111.7; daa[15*20+ 13] = 36.1; daa[15*20+ 14] = 86.5; daa[16*20+ 0] = 243.9; daa[16*20+ 1] = 0.2; daa[16*20+ 2] = 165.9; daa[16*20+ 3] = 0.2; daa[16*20+ 4] = 182.8; daa[16*20+ 5] = 43.7; daa[16*20+ 6] = 43.4; daa[16*20+ 7] = 0.2; daa[16*20+ 8] = 18.6; daa[16*20+ 9] = 203.7; daa[16*20+ 10] = 47.8; daa[16*20+ 11] = 69.5; daa[16*20+ 12] = 288.6; daa[16*20+ 13] = 13.5; daa[16*20+ 14] = 46.8; daa[16*20+ 15] = 660.4; daa[17*20+ 0] = 0.2; daa[17*20+ 1] = 0.2; daa[17*20+ 2] = 7.7; daa[17*20+ 3] = 0.2; daa[17*20+ 4] = 21.6; daa[17*20+ 5] = 6.7; daa[17*20+ 6] = 11.0; daa[17*20+ 7] = 1.9; daa[17*20+ 8] = 0.2; daa[17*20+ 9] = 0.2; daa[17*20+ 10] = 21.1; daa[17*20+ 11] = 16.0; daa[17*20+ 12] = 70.7; daa[17*20+ 13] = 53.7; daa[17*20+ 14] = 0.2; daa[17*20+ 15] = 2.4; daa[17*20+ 16] = 0.2; daa[18*20+ 0] = 1.2; daa[18*20+ 1] = 3.9; daa[18*20+ 2] = 251.2; daa[18*20+ 3] = 0.2; daa[18*20+ 4] = 72.0; daa[18*20+ 5] = 86.7; daa[18*20+ 6] = 7.7; daa[18*20+ 7] = 8.6; daa[18*20+ 8] = 191.4; daa[18*20+ 9] = 12.3; daa[18*20+ 10] = 19.8; daa[18*20+ 11] = 117.1; daa[18*20+ 12] = 70.9; daa[18*20+ 13] = 791.6; daa[18*20+ 14] = 18.4; daa[18*20+ 15] = 30.5; daa[18*20+ 16] = 46.0; daa[18*20+ 17] = 37.7; daa[19*20+ 0] = 339.9; daa[19*20+ 1] = 0.2; daa[19*20+ 2] = 22.6; daa[19*20+ 3] = 0.2; daa[19*20+ 4] = 350.4; daa[19*20+ 5] = 0.2; daa[19*20+ 6] = 13.6; daa[19*20+ 7] = 2.6; daa[19*20+ 8] = 0.2; daa[19*20+ 9] = 1854.5; daa[19*20+ 10] = 84.7; daa[19*20+ 11] = 26.1; daa[19*20+ 12] = 281.3; daa[19*20+ 13] = 51.9; daa[19*20+ 14] = 31.7; daa[19*20+ 15] = 60.6; daa[19*20+ 16] = 544.1; daa[19*20+ 17] = 0.2; daa[19*20+ 18] = 1.6; /* MtArt.old: esta es la MtArt que hice con 26 secuencias (2 outgroups) con una topoLOGia incorrecta daa[1*20+ 0] = 0.2; daa[2*20+ 0] = 0.2; daa[2*20+ 1] = 8.0; daa[3*20+ 0] = 0.2; daa[3*20+ 1] = 0.2; daa[3*20+ 2] = 441.7; daa[4*20+ 0] = 287.9; daa[4*20+ 1] = 48.4; daa[4*20+ 2] = 82.4; daa[4*20+ 3] = 0.2; daa[5*20+ 0] = 0.2; daa[5*20+ 1] = 149.9; daa[5*20+ 2] = 278.6; daa[5*20+ 3] = 0.2; daa[5*20+ 4] = 21.7; daa[6*20+ 0] = 6.6; daa[6*20+ 1] = 0.2; daa[6*20+ 2] = 213.9; daa[6*20+ 3] = 760.8; daa[6*20+ 4] = 0.2; daa[6*20+ 5] = 292.9; daa[7*20+ 0] = 228.2; daa[7*20+ 1] = 0.2; daa[7*20+ 2] = 97.1; daa[7*20+ 3] = 10.4; daa[7*20+ 4] = 98.4; daa[7*20+ 5] = 4.0; daa[7*20+ 6] = 48.7; daa[8*20+ 0] = 0.2; daa[8*20+ 1] = 56.7; daa[8*20+ 2] = 156.4; daa[8*20+ 3] = 24.5; daa[8*20+ 4] = 15.5; daa[8*20+ 5] = 328.6; daa[8*20+ 6] = 7.0; daa[8*20+ 7] = 8.4; daa[9*20+ 0] = 26.4; daa[9*20+ 1] = 1.6; daa[9*20+ 2] = 40.1; daa[9*20+ 3] = 0.2; daa[9*20+ 4] = 22.1; daa[9*20+ 5] = 13.8; daa[9*20+ 6] = 0.2; daa[9*20+ 7] = 3.6; daa[9*20+ 8] = 0.2; daa[10*20+ 0] = 3.4; daa[10*20+ 1] = 0.6; daa[10*20+ 2] = 13.8; daa[10*20+ 3] = 0.7; daa[10*20+ 4] = 76.9; daa[10*20+ 5] = 12.1; daa[10*20+ 6] = 5.4; daa[10*20+ 7] = 2.5; daa[10*20+ 8] = 2.9; daa[10*20+ 9] = 542.6; daa[11*20+ 0] = 0.2; daa[11*20+ 1] = 240.2; daa[11*20+ 2] = 602.8; daa[11*20+ 3] = 35.5; daa[11*20+ 4] = 0.2; daa[11*20+ 5] = 357.6; daa[11*20+ 6] = 62.6; daa[11*20+ 7] = 0.2; daa[11*20+ 8] = 3.3; daa[11*20+ 9] = 0.2; daa[11*20+ 10] = 17.5; daa[12*20+ 0] = 119.0; daa[12*20+ 1] = 0.2; daa[12*20+ 2] = 91.4; daa[12*20+ 3] = 6.4; daa[12*20+ 4] = 332.3; daa[12*20+ 5] = 65.4; daa[12*20+ 6] = 0.2; daa[12*20+ 7] = 60.4; daa[12*20+ 8] = 2.4; daa[12*20+ 9] = 492.5; daa[12*20+ 10] = 815.8; daa[12*20+ 11] = 67.3; daa[13*20+ 0] = 8.2; daa[13*20+ 1] = 6.4; daa[13*20+ 2] = 31.5; daa[13*20+ 3] = 3.4; daa[13*20+ 4] = 174.4; daa[13*20+ 5] = 5.7; daa[13*20+ 6] = 5.7; daa[13*20+ 7] = 2.1; daa[13*20+ 8] = 11.0; daa[13*20+ 9] = 94.4; daa[13*20+ 10] = 243.3; daa[13*20+ 11] = 12.3; daa[13*20+ 12] = 357.8; daa[14*20+ 0] = 62.5; daa[14*20+ 1] = 0.4; daa[14*20+ 2] = 17.5; daa[14*20+ 3] = 0.2; daa[14*20+ 4] = 0.2; daa[14*20+ 5] = 48.6; daa[14*20+ 6] = 17.7; daa[14*20+ 7] = 2.7; daa[14*20+ 8] = 0.2; daa[14*20+ 9] = 0.2; daa[14*20+ 10] = 11.2; daa[14*20+ 11] = 21.7; daa[14*20+ 12] = 5.2; daa[14*20+ 13] = 12.6; daa[15*20+ 0] = 659.0; daa[15*20+ 1] = 5.2; daa[15*20+ 2] = 469.8; daa[15*20+ 3] = 52.3; daa[15*20+ 4] = 570.7; daa[15*20+ 5] = 47.8; daa[15*20+ 6] = 37.3; daa[15*20+ 7] = 227.8; daa[15*20+ 8] = 12.7; daa[15*20+ 9] = 12.3; daa[15*20+ 10] = 7.4; daa[15*20+ 11] = 189.0; daa[15*20+ 12] = 155.3; daa[15*20+ 13] = 43.8; daa[15*20+ 14] = 103.4; daa[16*20+ 0] = 276.4; daa[16*20+ 1] = 1.6; daa[16*20+ 2] = 175.6; daa[16*20+ 3] = 0.2; daa[16*20+ 4] = 96.2; daa[16*20+ 5] = 71.4; daa[16*20+ 6] = 37.4; daa[16*20+ 7] = 0.2; daa[16*20+ 8] = 14.2; daa[16*20+ 9] = 212.5; daa[16*20+ 10] = 38.5; daa[16*20+ 11] = 97.4; daa[16*20+ 12] = 254.7; daa[16*20+ 13] = 2.1; daa[16*20+ 14] = 41.6; daa[16*20+ 15] = 670.6; daa[17*20+ 0] = 6.2; daa[17*20+ 1] = 0.2; daa[17*20+ 2] = 0.2; daa[17*20+ 3] = 5.6; daa[17*20+ 4] = 0.2; daa[17*20+ 5] = 0.2; daa[17*20+ 6] = 3.1; daa[17*20+ 7] = 0.4; daa[17*20+ 8] = 0.2; daa[17*20+ 9] = 15.2; daa[17*20+ 10] = 11.5; daa[17*20+ 11] = 32.6; daa[17*20+ 12] = 82.4; daa[17*20+ 13] = 81.9; daa[17*20+ 14] = 0.2; daa[17*20+ 15] = 9.7; daa[17*20+ 16] = 0.2; daa[18*20+ 0] = 1.6; daa[18*20+ 1] = 7.7; daa[18*20+ 2] = 242.5; daa[18*20+ 3] = 0.2; daa[18*20+ 4] = 88.0; daa[18*20+ 5] = 93.1; daa[18*20+ 6] = 0.2; daa[18*20+ 7] = 6.0; daa[18*20+ 8] = 113.7; daa[18*20+ 9] = 22.1; daa[18*20+ 10] = 17.2; daa[18*20+ 11] = 138.5; daa[18*20+ 12] = 37.6; daa[18*20+ 13] = 770.2; daa[18*20+ 14] = 5.3; daa[18*20+ 15] = 25.0; daa[18*20+ 16] = 55.5; daa[18*20+ 17] = 69.3; daa[19*20+ 0] = 307.8; daa[19*20+ 1] = 2.2; daa[19*20+ 2] = 6.9; daa[19*20+ 3] = 0.2; daa[19*20+ 4] = 405.7; daa[19*20+ 5] = 0.8; daa[19*20+ 6] = 20.2; daa[19*20+ 7] = 5.7; daa[19*20+ 8] = 0.2; daa[19*20+ 9] = 1687.9; daa[19*20+ 10] = 49.4; daa[19*20+ 11] = 23.4; daa[19*20+ 12] = 329.9; daa[19*20+ 13] = 86.3; daa[19*20+ 14] = 27.3; daa[19*20+ 15] = 95.0; daa[19*20+ 16] = 443.0; daa[19*20+ 17] = 2.4; daa[19*20+ 18] = 0.2; 3*/ for (i=0; iio->datatype == NT) m4mod->n_o = 4; else if(mod->io->datatype == AA) m4mod->n_o = 20; else { PhyML_Printf("\n== Not implemented yet."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } mod->ns = m4mod->n_o * m4mod->n_h; For(i,m4mod->n_o) m4mod->o_fq[i] = mod->e_frq->pi->v[i]; /*! At that stage, the mod->pi vector as been initialized under a standard non covarion type of model. Use these frequencies as they have been set according to the nucleotide substitution model chosen (e.g., 1/4 for JC69). !*/ For(i,(int)(m4mod->n_h)) m4mod->multipl[i] = 1.; ct = 0; For(i,m4mod->n_o-1) { for(j=i+1;jn_o;j++) { m4mod->o_rr[ct] = MAX(mod->r_mat->qmat->v[i*m4mod->n_o+j],1.E-5); ct++; } } For(i,(int)(m4mod->n_h*(m4mod->n_h-1)/2)) m4mod->h_rr[i] = 1.; fq = (phydbl)(1./m4mod->n_h); if(mod->s_opt->opt_cov_delta) m4mod->delta = 1.0; if(mod->s_opt->opt_cov_alpha) m4mod->alpha = 1.0; For(i,m4mod->n_h) m4mod->h_fq[i] = fq; For(i,m4mod->n_h) m4mod->h_fq_unscaled[i] = 1.0; For(i,m4mod->n_h) m4mod->multipl[i] = (phydbl)i; For(i,m4mod->n_h) m4mod->multipl_unscaled[i] = (phydbl)i; Switch_Eigen(YES,mod); M4_Update_Qmat(m4mod,mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Init_Coord(t_geo_coord *t, int n_dim) { t->dim = n_dim; Random_String(t->id,3); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PHYREX_Init_Disk_Event(t_dsk *t, int n_dim, t_phyrex_mod *mmod) { t->prev = NULL; t->next = NULL; t->mmod = NULL; Random_String(t->id,3); GEO_Init_Coord(t->centr,n_dim); if(mmod != NULL) t->mmod = mmod; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PHYREX_Init_Migrep_Mod(t_phyrex_mod *t, int n_dim, phydbl max_lat, phydbl max_lon) { assert(n_dim == 2); t->name = PHYREX_NORMAL; t->n_dim = n_dim; t->safe_phyrex = NO; t->lim->lonlat[0] = max_lat; t->lim->lonlat[1] = max_lon; t->lbda = 1.E-0; t->min_lbda = 1.E-6; t->max_lbda = 1.E+2; t->prior_param_lbda = 1.0; t->mu = 0.300; t->min_mu = 0.001; t->max_mu = 1.000; t->prior_param_mu = 1.000; t->min_rad = 0.0; t->max_rad = 0.25*(max_lat+max_lon); t->rad = .10*(max_lat+max_lon); t->prior_param_rad = 0.5; t->update_rad = NO; t->min_sigsq = 0.0; t->max_sigsq = 1.E+2; t->sigsq = 1.0; t->prior_param_sigsq = 10.0; t->c_lnL = UNLIKELY; t->c_ln_prior_rad = UNLIKELY; t->c_ln_prior_lbda = UNLIKELY; t->c_ln_prior_mu = UNLIKELY; t->soft_bound_area = 0.1; t->sampl_area = 0.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PHYREX_Init_Lindisk_Node(t_ldsk *t, t_dsk *disk, int n_dim) { t->disk = disk; /* disk->ldsk = t; */ t->prev = NULL; t->next = NULL; t->nd = NULL; t->is_hit = NO; t->n_next = 0; GEO_Init_Coord(t->coord, n_dim); GEO_Init_Coord(t->cpy_coord,n_dim); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Init_MCMC_Struct(char *filename, option *io, t_mcmc *mcmc) { int pid; mcmc->io = io; mcmc->is = NO; mcmc->use_data = YES; mcmc->run = 0; mcmc->sample_interval = 1E+3; mcmc->chain_len = 1E+7; mcmc->chain_len_burnin = 1E+4; mcmc->randomize = YES; mcmc->norm_freq = 1E+3; mcmc->max_tune = 1.E+20; mcmc->min_tune = 1.E-10; mcmc->print_every = 2; mcmc->is_burnin = NO; mcmc->nd_t_digits = 4; mcmc->always_yes = NO; mcmc->max_lag = 1000; mcmc->sample_num = 0; if(filename) { char *s; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(mcmc->out_filename,filename); pid = getpid(); sprintf(mcmc->out_filename+strlen(mcmc->out_filename),".%d",pid); strcpy(s,mcmc->io->in_align_file); strcat(s,"_"); strcat(s,mcmc->out_filename); strcat(s,".stats"); mcmc->out_fp_stats = fopen(s,"w"); strcpy(s,mcmc->io->in_align_file); strcat(s,"_"); strcat(s,mcmc->out_filename); strcat(s,".trees"); mcmc->out_fp_trees = fopen(s,"w"); strcpy(s,mcmc->io->in_align_file); strcat(s,"_"); strcat(s,mcmc->out_filename); strcat(s,".constree"); mcmc->out_fp_constree = fopen(s,"w"); /* strcpy(s,tree->mcmc->out_filename); */ /* strcat(s,".means"); */ /* tree->mcmc->out_fp_means = fopen(s,"w"); */ /* strcpy(s,tree->mcmc->out_filename); */ /* strcat(s,".lasts"); */ /* tree->mcmc->out_fp_last = fopen(s,"w"); */ Free(s); } else { mcmc->out_fp_stats = stderr; mcmc->out_fp_trees = stderr; /* tree->mcmc->out_fp_means = stderr; */ /* tree->mcmc->out_fp_last = stderr; */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/init.h000066400000000000000000000047061263450375500145710ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef INIT_H #define INIT_H #include "utilities.h" void Init_Eigen_Struct(eigen *this); void Init_Scalar_Dbl(scalar_dbl *p); void Init_Scalar_Int(scalar_int *p); void Init_Vect_Dbl(int len,vect_dbl *p); void Init_Vect_Int(int len,vect_int *p); void Init_Tree(t_tree *tree,int n_otu); void Init_Edge_Light(t_edge *b,int num); void Init_Node_Light(t_node *n,int num); void Init_NNI(nni *a_nni); void Init_Nexus_Format(nexcom **com); void Init_Mat(matrix *mat,calign *data); void Set_Defaults_Input(option *io); void Set_Defaults_Model(t_mod *mod); void Set_Defaults_Optimiz(t_opt *s_opt); void XML_Init_Node(xml_node *prev,xml_node *new_node,char *name); void Init_One_Spr(t_spr *a_spr); void Init_Model(calign *data,t_mod *mod,option *io); int Init_Qmat_Dayhoff(phydbl *daa,phydbl *pi); int Init_Qmat_DCMut(phydbl *daa,phydbl *pi); int Init_Qmat_MtArt(phydbl *daa,phydbl *pi); int Init_Qmat_HIVb(phydbl *daa,phydbl *pi); int Init_Qmat_HIVw(phydbl *daa,phydbl *pi); int Init_Qmat_JTT(phydbl *daa,phydbl *pi); int Init_Qmat_MtREV(phydbl *daa,phydbl *pi); int Init_Qmat_LG(phydbl *daa,phydbl *pi); int Init_Qmat_WAG(phydbl *daa,phydbl *pi); int Init_Qmat_RtREV(phydbl *daa,phydbl *pi); int Init_Qmat_CpREV(phydbl *daa,phydbl *pi); int Init_Qmat_VT(phydbl *daa,phydbl *pi); int Init_Qmat_Blosum62(phydbl *daa,phydbl *pi); int Init_Qmat_MtMam(phydbl *daa,phydbl *pi); int Init_Qmat_AB(phydbl *daa, phydbl *pi); void XML_Init_Attribute(xml_attr *attr); void Init_String(t_string *ts); void Init_Triplet_Struct(triplet *triplet); void Init_Efrq(t_efrq *f); void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod); void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu); void Init_Rmat(t_rmat *rmat); void Init_MGF_Bl(t_tree *tree); int Init_Qmat_FLU(phydbl *daa, phydbl *pi); void Set_Defaults_Ras(t_ras *ras); void GEO_Init_Coord(t_geo_coord *t, int n_dim); void PHYREX_Init_Disk_Event(t_dsk *t, int n_dim, t_phyrex_mod *mod); void PHYREX_Init_Lindisk_Node(t_ldsk *t, t_dsk *devt, int n_dim); void PHYREX_Init_Migrep_Mod(t_phyrex_mod *t, int n_dim, phydbl max_lat, phydbl max_lon); void MCMC_Init_MCMC_Struct(char *filename, option *io, t_mcmc *mcmc); #endif phyml-3.2.0/src/interface.c000066400000000000000000001402541263450375500155600ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "interface.h" #include "mg.h" void Launch_Interface(option *io) { Launch_Interface_Input(io); io->ready_to_go = 0; do { switch(io->curr_interface) { case INTERFACE_DATA_TYPE : { Launch_Interface_Data_Type(io); break; } case INTERFACE_MULTIGENE : { Launch_Interface_Multigene(io); break; } case INTERFACE_MODEL : { Launch_Interface_Model(io); break; } case INTERFACE_TOPO_SEARCH : { Launch_Interface_Topo_Search(io); break; } case INTERFACE_BRANCH_SUPPORT : { Launch_Interface_Branch_Support(io); break; } default : { PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Exit(""); break; } } }while(!io->ready_to_go); if(io->in_tree == 2) { PhyML_Printf("\n. Enter the name of the input tree file > "); Getstring_Stdin(io->in_tree_file); io->fp_in_tree = Openfile(io->in_tree_file,0); } if((io->mod->whichmodel == CUSTOMAA) && (io->datatype == AA)) { char *filename; filename = (char *)mCalloc(T_MAX_NAME,sizeof(char)); fflush(NULL); PhyML_Printf("\n"); PhyML_Printf("\n. Enter the rate matrix file name > "); fflush(NULL); Getstring_Stdin(filename); io->mod->fp_aa_rate_mat = Openfile(filename,0); strcpy(io->mod->aa_rate_mat_file->s,filename); PhyML_Printf("\n"); Free(filename); fflush(NULL); } if((io->mod->s_opt->n_rand_starts) && (io->mod->s_opt->topo_search == NNI_MOVE) && (io->mod->s_opt->random_input_tree)) { Warn_And_Exit("\n. The random starting tree option is only compatible with SPR based search options.\n"); } if ((io->datatype == NT) && (io->mod->whichmodel > 10)) { char choix; PhyML_Printf("\n== Err: model incompatible with the data type. Please use JC69, K80, F81, HKY, F84, TN93 or GTR\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Warn_And_Exit("\n"); } else if ((io->datatype == AA) && (io->mod->whichmodel < 11)) { char choix; PhyML_Printf("\n== Err: model incompatible with the data type. Please use LG, Dayhoff, JTT, MtREV, WAG, DCMut, RtREV, CpREV, VT, Blosum62, MtMam, MtArt, HIVw, HIVb or AB.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } if(io->m4_model == YES) { #ifdef M4 io->mod->ns *= io->mod->m4mod->n_h; io->mod->use_m4mod = 1; M4_Make_Complete(io->mod->m4mod->n_h, io->mod->m4mod->n_o, io->mod->m4mod); #endif } else { io->mod->s_opt->opt_cov_delta = 0; io->mod->s_opt->opt_cov_alpha = 0; io->mod->s_opt->opt_cov_free_rates = 0; } if((io->mod->s_opt->opt_cov_free_rates) && (io->mod->s_opt->opt_cov_alpha)) { io->mod->s_opt->opt_cov_free_rates = 0; io->mod->m4mod->use_cov_alpha = 0; io->mod->m4mod->use_cov_free = 1; } if(io->print_site_lnl) { strcpy(io->out_lk_file,io->in_align_file); strcat(io->out_lk_file, "_phyml_lk"); if(io->append_run_ID) { strcat(io->out_lk_file,"_"); strcat(io->out_lk_file,io->run_id_string); } strcat(io->out_lk_file, ".txt"); io->fp_out_lk = Openfile(io->out_lk_file,1); } if(io->print_trace) { strcpy(io->out_trace_file,io->in_align_file); strcat(io->out_trace_file,"_phyml_trace"); if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); } strcat(io->out_trace_file,".txt"); io->fp_out_trace = Openfile(io->out_trace_file,1); } if(io->mod->s_opt->random_input_tree) { strcpy(io->out_trees_file,io->in_align_file); strcat(io->out_trees_file,"_phyml_trees"); if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); } strcat(io->out_trees_file,".txt"); io->fp_out_trees = Openfile(io->out_trees_file,1); } if((io->print_boot_trees) && (io->mod->bootstrap > 0)) { strcpy(io->out_boot_tree_file,io->in_align_file); strcat(io->out_boot_tree_file,"_phyml_boot_trees"); if(io->append_run_ID) { strcat(io->out_boot_tree_file,"_"); strcat(io->out_boot_tree_file,io->run_id_string); } strcat(io->out_boot_tree_file,".txt"); io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1); strcpy(io->out_boot_stats_file,io->in_align_file); strcat(io->out_boot_stats_file,"_phyml_boot_stats"); if(io->append_run_ID) { strcat(io->out_boot_stats_file,"_"); strcat(io->out_boot_stats_file,io->run_id_string); } strcat(io->out_boot_stats_file,".txt"); io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1); } if(io->append_run_ID) { strcat(io->out_tree_file,"_"); strcat(io->out_stats_file,"_"); strcat(io->out_tree_file,io->run_id_string); strcat(io->out_stats_file,io->run_id_string); strcat(io->out_tree_file,".txt"); strcat(io->out_stats_file,".txt"); } if(io->mod->ras->n_catg == 1) io->mod->s_opt->opt_alpha = 0; if(io->mod->whichmodel != K80 && io->mod->whichmodel != HKY85 && io->mod->whichmodel != F84 && io->mod->whichmodel != TN93) { io->mod->s_opt->opt_kappa = 0; } io->fp_out_tree = Openfile(io->out_tree_file,1); io->fp_out_stats = Openfile(io->out_stats_file,1); if(io->mod->whichmodel == GTR) { /* Make_Custom_Model(io->mod); */ io->mod->s_opt->opt_rr = 1; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Clear() { #ifdef WIN32 system("cls"); #elif UNIX PhyML_Printf("\033[2J\033[H"); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Input(option *io) { char choix; int n_trial; Clear(); Print_Banner(stdout); #ifdef EVOLVE char *n_data_sets; PhyML_Printf("\n\n"); PhyML_Printf("\n. Enter the tree file name > "); fflush(NULL); Getstring_Stdin(io->in_tree_file); io->fp_in_tree = Openfile(io->in_tree_file,0); PhyML_Printf("\n"); PhyML_Printf("\n. Enter the reference sequence file name > "); fflush(NULL); Getstring_Stdin(io->in_align_file); io->fp_in_align = Openfile(io->in_align_file,0); PhyML_Printf("\n"); PhyML_Printf("\n. Number of data sets > "); n_data_sets = (char *)mCalloc(10000,sizeof(char)); Getstring_Stdin(n_data_sets); n_trial = 0; while((!atoi(n_data_sets)) || (atoi(n_data_sets) < 0)) { if(++n_trial > 10) Exit("\n== Err : the number of sets must be a positive integer"); PhyML_Printf("\n. The number of sets must be a positive integer"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(n_data_sets); } io->n_data_set_asked = atoi(n_data_sets); Free(n_data_sets); #elif OPTIMIZ PhyML_Printf("\n. Enter the tree file name > "); fflush(NULL); Getstring_Stdin(io->in_tree_file); io->fp_in_tree = Openfile(io->in_tree_file,0); PhyML_Printf("\n"); PhyML_Printf("\n. Enter the reference sequence file name > "); fflush(NULL); Getstring_Stdin(io->in_align_file); io->fp_in_align = Openfile(io->in_align_file,0); PhyML_Printf("\n"); #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) PhyML_Printf("\n. Enter the sequence file name > "); fflush(NULL); Getstring_Stdin(io->in_align_file); io->fp_in_align = Openfile(io->in_align_file,0); #endif #if defined(PHYML) || defined(PART) || defined(PHYML_INSERT) strcpy(io->out_stats_file,io->in_align_file); strcat(io->out_stats_file,"_phyml_stats.txt"); strcpy(io->out_tree_file,io->in_align_file); strcat(io->out_tree_file,"_phyml_tree.txt"); strcpy(io->out_lk_file,io->in_align_file); strcat(io->out_lk_file,"_phyml_lk.txt"); #endif #ifdef WIN32 #ifdef EVOLVE if(Filexists("evolve_out.txt")); #elif OPTIMIZ if(Filexists("optimiz_out.txt")) #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) if(Filexists(io->out_stats_file)) #endif #elif UNIX #ifdef EVOLVE if(Filexists("evolve_out")); #elif OPTIMIZ if(Filexists("optimiz_out")) #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) if(Filexists(io->out_stats_file)) #endif #endif { PhyML_Printf("\n"); #ifdef EVOLVE PhyML_Printf("\n. A file 'evolve_out' already exists"); #elif OPTIMIZ PhyML_Printf("\n. A file 'optimiz_out' already exists"); #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) PhyML_Printf("\n. A file '%s' already exists",io->out_stats_file); #endif PhyML_Printf("\n. Do you want to Replace it or Append to it ? "); n_trial = 0; do { PhyML_Printf("\n. Please type R or A > "); if(!scanf("%c",&choix)) Exit("\n"); if(choix == '\n') choix = 'r'; else getchar(); if(++n_trial>10) Exit("\n"); Uppercase(&choix); } while((choix != 'R') && (choix != 'A')); if(choix == 'R') io->out_stats_file_open_mode = 1; else io->out_stats_file_open_mode = 2; } /* io->fp_out_stats = Openfile(io->out_stats_file,io->out_stats_file_open_mode); */ #ifdef WIN32 #ifdef EVOLVE if(Filexists("evolve_seq.txt")) #elif OPTIMIZ if(Filexists("optimiz_tree.txt")) #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) if(Filexists(io->out_tree_file)) #endif #elif UNIX #ifdef EVOLVE if(Filexists("evolve_seq")) #elif OPTIMIZ if(Filexists("optimiz_tree")) #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) if(Filexists(io->out_tree_file)) #endif #endif { PhyML_Printf("\n"); #ifdef EVOLVE PhyML_Printf("\n. A file 'evolve_seq' already exists"); #elif OPTIMIZ PhyML_Printf("\n. A file 'optimiz_tree' already exists"); #elif defined(PHYML) || defined(PART) || defined(PHYML_INSERT) PhyML_Printf("\n. A file '%s' already exists",io->out_tree_file); #endif PhyML_Printf("\n. Do you want to Replace it or Append to it ? "); n_trial = 0; do { PhyML_Printf("\n. Please type R or A > "); if(!scanf("%c",&choix)) Exit("\n"); if(choix == '\n') choix = 'r'; else getchar(); Uppercase(&choix); if(++n_trial>10) Exit("\n"); } while((choix != 'R') && (choix != 'A')); if(choix == 'R') io->out_tree_file_open_mode = 1; else io->out_tree_file_open_mode = 2; } /* io->fp_out_tree = Openfile(io->out_tree_file,io->out_tree_file_open_mode); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Data_Type(option *io) { char choix; char *s; char *buff; Clear(); Print_Banner(stdout); if(io->config_multigene) Print_Data_Set_Number(io,stdout); s = (char *)mCalloc(100,sizeof(char)); buff = (char *)mCalloc(100,sizeof(char)); PhyML_Printf("\n\n"); PhyML_Printf(" ................... \n"); PhyML_Printf(" Menu : Input Data \n"); PhyML_Printf(" ......................... \n"); PhyML_Printf("\n\n"); PhyML_Printf(" [+] " ".................................... Next sub-menu\n"); PhyML_Printf(" [-] " "................................ Previous sub-menu\n"); PhyML_Printf(" [Y] " ".............................. Launch the analysis\n"); PhyML_Printf("\n"); if(io->datatype == NT) strcpy(s,"DNA"); else if(io->datatype == AA) strcpy(s,"AA"); else strcpy(s,"Generic"); PhyML_Printf(" [D] " "....................... Data type (DNA/AA/Generic) " " %-15s \n",s); PhyML_Printf(" [I] " "...... Input sequences interleaved (or sequential) " " %-15s \n", (io->interleaved)?("interleaved"):("sequential")); strcpy(s,""); sprintf(s," (%d sets)",io->n_data_sets); strcpy(buff,(io->n_data_sets > 1)?("yes"):("no")); buff=strcat(buff,(io->n_data_sets > 1)?(s):("\0")); PhyML_Printf(" [M] " "....................... Analyze multiple data sets " " %-15s \n",buff); if(!io->append_run_ID) strcpy(s,"none"); else strcpy(s,io->run_id_string); PhyML_Printf(" [R] " "........................................... Run ID " " %-15s \n",s); PhyML_Printf("\n\n. Are these settings correct ? " "(type '+', '-', 'Y' or other letter for one to change) "); if(!scanf("%c",&choix)) Exit("\n"); if(choix != '\n') getchar(); /* \n */ fflush(NULL); Uppercase(&choix); switch(choix) { /* case '\n': */ /* { */ /* io->curr_interface++; */ /* break; */ /* } */ case 'R' : { io->append_run_ID = (io->append_run_ID)?(0):(1); PhyML_Printf("\n. Enter a run ID (any string of characters) > "); Getstring_Stdin(io->run_id_string); break; } case 'M' : { char *c; int n_trial; PhyML_Printf("\n. How many data sets > "); c = (char *)mCalloc(100,sizeof(char)); Getstring_Stdin(c); n_trial = 0; while((!atoi(c)) || (atoi(c) < 0)) { if(++n_trial > 10) Exit("\n== Err : The number of data sets must be a positive integer"); PhyML_Printf("\n. The number of data sets must be a positive integer"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(c); } io->n_data_sets = atoi(c); #ifdef PART if(io->n_data_sets > 1) { io->multigene = 1; } #endif if((io->mod->bootstrap > 1) && (io->n_data_sets > 1)) { PhyML_Printf("\n. Bootstrap option is not allowed with multiple data sets !\n"); PhyML_Printf("\n. Type any key to exit."); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } Free(c); break; } case 'I' : { if(io->interleaved) io->interleaved = 0; else io->interleaved = 1; break; } case 'D' : { if(io->datatype == NT) { io->datatype = AA; io->mod->ns = 20; io->mod->s_opt->opt_kappa = 0; io->mod->whichmodel = LG; strcpy(io->mod->modelname->s,"LG"); } else if(io->datatype == AA) { io->datatype = GENERIC; io->mod->whichmodel = JC69; strcpy(io->mod->modelname->s,"JC69"); strcpy(io->nt_or_cd,"natural numbers"); } else if(io->datatype == GENERIC) { io->datatype = NT; io->mod->ns = 4; io->mod->whichmodel = HKY85; strcpy(io->mod->modelname->s,"HKY85"); strcpy(io->nt_or_cd,"nucleotides"); } break; } case '-' : { io->curr_interface = (io->config_multigene)?(INTERFACE_MODEL):(INTERFACE_BRANCH_SUPPORT); break; } case '+' : { io->curr_interface = (io->multigene)?(INTERFACE_MULTIGENE):(INTERFACE_MODEL); break; } case 'Y' : { io->ready_to_go = 1; break; } default : { break; } } Free(s); Free(buff); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Model(option *io) { char choix; char *s; s = (char *)mCalloc(100,sizeof(char)); Clear(); Print_Banner(stdout); if(io->config_multigene) Print_Data_Set_Number(io,stdout); PhyML_Printf("\n\n"); PhyML_Printf(" ........................... \n"); PhyML_Printf(" Menu : Substitution Model \n"); PhyML_Printf(" ................................. \n"); PhyML_Printf("\n\n"); PhyML_Printf(" [+] " ".................................... Next sub-menu\n"); PhyML_Printf(" [-] " "................................ Previous sub-menu\n"); PhyML_Printf(" [Y] " ".............................. Launch the analysis\n"); PhyML_Printf("\n"); if (io->datatype == NT) { if(!strcmp(io->nt_or_cd,"nucleotides")) { PhyML_Printf(" [M] " "................. Model of nucleotide substitution " " %-15s \n", io->mod->modelname->s); if((io->mod->whichmodel == F81) || (io->mod->whichmodel == HKY85) || (io->mod->whichmodel == F84) || (io->mod->whichmodel == TN93) || (io->mod->whichmodel == GTR) || (io->mod->whichmodel == CUSTOM)) { /* PhyML_Printf(" [F] " */ /* ".......... Base frequency estimates (empirical/ML) " */ /* " %-15s \n", */ /* (io->mod->s_opt->opt_state_freq)?("ML"):("empirical")); */ /* } */ /* else if(io->mod->whichmodel == CUSTOM) */ /* { */ PhyML_Printf(" [F] " "................. Optimise equilibrium frequencies " " %-15s \n", (io->mod->s_opt->opt_state_freq)?("yes"):("no")); } if(io->mod->whichmodel == CUSTOM) { if(!io->mod->s_opt->opt_state_freq) { PhyML_Printf(" [E] " "......... Equilibrium frequencies (empirical/user) " " %-15s \n", (io->mod->s_opt->user_state_freq)?("user defined"):("empirical")); } PhyML_Printf(" [K] " "............................. Current custom model " " %-15s \n", io->mod->custom_mod_string->s); PhyML_Printf(" [O] " "................ Optimise relative rate parameters " " %-15s \n",(io->mod->s_opt->opt_rr)?("yes"):("no")); } } } else if(io->datatype == AA) { PhyML_Printf(" [M] " "................ Model of amino-acids substitution " " %-15s \n", io->mod->modelname->s); PhyML_Printf(" [F] " ". Amino acid frequencies (empirical/model defined) " " %-15s \n", (io->mod->s_opt->opt_state_freq)?("empirical"):("model")); } else if(io->datatype == GENERIC) { PhyML_Printf(" [M] " "................. Model of nucleotide substitution " " %-15s \n", io->mod->modelname->s); } if ((io->datatype == NT) && ((io->mod->whichmodel == K80) || (io->mod->whichmodel == HKY85)|| (io->mod->whichmodel == F84) || (io->mod->whichmodel == TN93))) { strcpy(s,(io->mod->s_opt->opt_kappa)?("estimated"):("fixed")); if(io->mod->s_opt->opt_kappa) strcat(s,""); else strcat(s," (ts/tv = "); /* (io->mod->s_opt->opt_kappa)?((char *)strcat(s,"")):((char *)sprintf(s+(int)strlen((char *)s),"%3.2f)",io->mod->kappa->v)); */ if(io->mod->s_opt->opt_kappa) { strcat((char *)s,""); } else { sprintf((char *)(s+(int)strlen(s)),"%3.2f)",io->mod->kappa->v); } PhyML_Printf(" [T] " ".................... Ts/tv ratio (fixed/estimated) " " %-15s \n",s); } strcpy(s,io->mod->s_opt->opt_pinvar?"estimated":"fixed"); strcat(s,io->mod->s_opt->opt_pinvar?"":" (p-invar = "); if(io->mod->s_opt->opt_pinvar) { strcat(s,""); } else { sprintf((char *)(s+strlen((char *)s)),"%3.2f)",io->mod->ras->pinvar->v); } PhyML_Printf(" [V] " ". Proportion of invariable sites (fixed/estimated)" " %-15s \n",s); PhyML_Printf(" [R] " "....... One category of substitution rate (yes/no) " " %-15s \n", (io->mod->ras->n_catg > 1)?("no"):("yes")); if(io->mod->ras->n_catg > 1) { PhyML_Printf(" [C] " "........... Number of substitution rate categories " " %-15d \n", io->mod->ras->n_catg); } if(io->mod->ras->n_catg > 1) { PhyML_Printf(" [G] " "............. Gamma distributed rates across sites " " %-15s \n",(io->mod->ras->free_mixt_rates)?("no"):("yes")); } if((io->mod->ras->n_catg > 1) && (io->mod->ras->free_mixt_rates == NO)) { strcpy(s,(io->mod->s_opt->opt_alpha)?("estimated"):("fixed")); strcat(s,io->mod->s_opt->opt_alpha?"":" (alpha = "); if(io->mod->s_opt->opt_alpha) { strcat(s, ""); } else { sprintf(s+strlen(s),"%3.2f)",io->mod->ras->alpha->v); } PhyML_Printf(" [A] " "... Gamma distribution parameter (fixed/estimated) " " %-15s \n",s); /* strcpy(s,(io->mod->ras->gamma_median)?("median"):("mean")); */ /* PhyML_Printf(" [G] " */ /* ".........'Middle' of each rate class (mean/median) " */ /* " %-15s \n",s); */ } PhyML_Printf("\n\n. Are these settings correct ? " "(type '+', '-', 'Y' or other letter for one to change) "); if(!scanf("%c",&choix)) Exit("\n"); if(choix != '\n') getchar(); /* \n */ Uppercase(&choix); switch(choix) { /* case '\n': */ /* { */ /* io->curr_interface++; */ /* break; */ /* } */ case 'G' : { io->mod->ras->free_mixt_rates = (io->mod->ras->free_mixt_rates)?(NO):(YES); break; } case 'O' : { io->mod->s_opt->opt_rr = (io->mod->s_opt->opt_rr)?(0):(1); break; } case 'K' : { int i,j; char **rr_param,*rr; t_mod *mod; int n_trial; if(io->mod->whichmodel == CUSTOM) { rr_param = (char **)mCalloc(6,sizeof(char *)); For(i,6) rr_param[i] = (char *)mCalloc(10,sizeof(char)); rr = (char *)mCalloc(50,sizeof(char)); mod = io->mod; mod->s_opt->opt_rr = 1; n_trial = 0; do { PhyML_Printf("\n. Enter a new custom model > "); Getstring_Stdin(io->mod->custom_mod_string->s); if(strlen(io->mod->custom_mod_string->s) == 6) { For(i,6) { while(!isdigit((int)io->mod->custom_mod_string->s[i])) { if(++n_trial > 10) Exit("\n== Err : this string is not valid !\n"); PhyML_Printf("\n. This string is not valid\n"); PhyML_Printf("\n. Enter a new model > "); Getstring_Stdin(io->mod->custom_mod_string->s); } } if(i == 6) break; } else { PhyML_Printf("\n. The string should be of length 6\n"); n_trial++; } }while(n_trial < 10); if(n_trial == 10) Exit(""); if(!mod->r_mat) { mod->r_mat = (t_rmat *)Make_Rmat(mod->ns); Init_Rmat(mod->r_mat); Make_Custom_Model(mod); Translate_Custom_Mod_String(io->mod); } strcpy(rr_param[0],"A<->C"); strcpy(rr_param[1],"A<->G"); strcpy(rr_param[2],"A<->T"); strcpy(rr_param[3],"C<->G"); strcpy(rr_param[4],"C<->T"); strcpy(rr_param[5],"G<->T"); PhyML_Printf("\n. Set the relative rate values\n"); For(i,mod->r_mat->n_diff_rr) { sprintf(rr,"\n. ["); For(j,6) { if(mod->r_mat->rr_num->v[j] == i) { sprintf(rr+strlen(rr),"%s = ",rr_param[j]); } } sprintf(rr+strlen(rr)-3,"]"); PhyML_Printf("%s",rr); PhyML_Printf(" (current=%.2f) > ",mod->r_mat->rr_val->v[i]); Getstring_Stdin(rr); if(rr[0] != '\0') { n_trial = 0; while((atof(rr) < .0)) { if(++n_trial > 10) Exit("\n== Err : the value of this parameter must be a positive number\n"); PhyML_Printf("\n. The value of this parameter must be a positive number\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(rr); } io->mod->r_mat->rr_val->v[i] = (phydbl)atof(rr); } } For(i,6) Free(rr_param[i]); Free(rr_param); Free(rr); } break; } case 'E' : { int i; if(io->mod->whichmodel == CUSTOM) { io->mod->s_opt->user_state_freq = (io->mod->s_opt->user_state_freq)?(0):(1); if(io->mod->s_opt->user_state_freq) { if(!io->mod->s_opt->opt_state_freq) { char **bases; char *bs; phydbl sum; int n_trial; bases = (char **)mCalloc(4,sizeof(char *)); For(i,4) bases[i] = (char *)mCalloc(50,sizeof(char)); bs = (char *)mCalloc(100,sizeof(char)); strcpy(bases[0],". f(A)> "); strcpy(bases[1],". f(C)> "); strcpy(bases[2],". f(G)> "); strcpy(bases[3],". f(T)> "); PhyML_Printf("\n. Set nucleotide frequencies \n"); sum = .0; For(i,4) { PhyML_Printf("%s",bases[i]); Getstring_Stdin(bs); n_trial = 0; while((atof(bs) < .0001) || (bs[0] == '\0')) { if(++n_trial > 10) Exit("\n== Err : the value of this parameter must be a positive number\n"); PhyML_Printf("\n. The value of this parameter must be a positive number\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(bs); } io->mod->user_b_freq->v[i] = (phydbl)atof(bs); sum += io->mod->user_b_freq->v[i]; } For(i,4) io->mod->user_b_freq->v[i] /= sum; if(sum > 1.0 || sum < 1.0) { PhyML_Printf("\n. The nucleotide frequencies have to be normalised in order to sum to 1.0.\n"); PhyML_Printf("\n. The frequencies are now : f(A)=%f, f(C)=%f, f(G)=%f, f(T)=%f.\n", io->mod->user_b_freq->v[0], io->mod->user_b_freq->v[1], io->mod->user_b_freq->v[2], io->mod->user_b_freq->v[3]); PhyML_Printf("\n. Enter any key to continue.\n"); if(!scanf("%c",bs)) Exit("\n"); } For(i,4) Free(bases[i]); Free(bases); Free(bs); } else { Warn_And_Exit("\n. 'E' is not a valid option with these model settings.\n"); } } } break; } case 'A' : { char answer; int n_trial; answer = 0; switch(io->mod->s_opt->opt_alpha) { case 0 : { PhyML_Printf("\n. Optimise alpha ? [Y/n] "); if(!scanf("%c",&answer)) Exit("\n"); if(answer == '\n') answer = 'Y'; else getchar(); break; } case 1 : { PhyML_Printf("\n. Optimise alpha ? [N/y] "); if(!scanf("%c",&answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); break; } default : Exit("\n"); } n_trial = 0; while((answer != 'Y') && (answer != 'y') && (answer != 'N') && (answer != 'n')) { if(++n_trial > 10) Exit("\n== Err : wrong answers !"); PhyML_Printf("\n. Optimise alpha ? [N/y] "); if(!scanf("%c",&answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); } switch(answer) { case 'Y' : case 'y' : { io->mod->s_opt->opt_alpha = 1; io->mod->s_opt->opt_subst_param = 1; break; } case 'N' : case 'n' : { char *a; a = (char *)mCalloc(100,sizeof(char)); io->mod->ras->alpha->v = 10.0; io->mod->s_opt->opt_alpha = 0; PhyML_Printf("\n. Enter your value of alpha > "); Getstring_Stdin(a); n_trial = 0; while(atof(a) < 1.E-10) { if(++n_trial > 10) Exit("\n== Err : alpha must be > 1.E-10\n"); PhyML_Printf("\n. Alpha must be 1.E-10\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(a); } io->mod->ras->alpha->v = (phydbl)atof(a); Free(a); io->mod->s_opt->opt_alpha = 0; break; } } break; } case 'C' : { char *c; int n_trial; PhyML_Printf("\n. Enter your number of categories > "); c = (char *)mCalloc(100,sizeof(char)); Getstring_Stdin(c); n_trial = 0; while((!atoi(c)) || (atoi(c) < 0)) { if(++n_trial > 10) Exit("\n== Err : the number of categories must be a positive integer\n"); PhyML_Printf("\n. The number of categories must be a positive integer\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(c); } io->mod->ras->n_catg = atoi(c); Free(c); break; } case 'R' : { io->mod->ras->n_catg = (io->mod->ras->n_catg == 1)?(4):(1); break; } case 'V' : { char answer; int n_trial; answer = 0; switch(io->mod->s_opt->opt_pinvar) { case 0 : { PhyML_Printf("\n. Optimise p-invar ? [Y/n] "); answer = 0; if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'Y'; else getchar(); break; } case 1 : { PhyML_Printf("\n. Optimise p-invar ? [N/y] "); if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); break; } default : Exit("\n"); } n_trial = 0; while((answer != 'Y') && (answer != 'y') && (answer != 'N') && (answer != 'n')) { if(++n_trial > 10) Exit("\n== Err : wrong answers !"); PhyML_Printf("\n. Optimise p-invar ? [N/y] "); if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); } switch(answer) { case 'Y' : case 'y' : { io->mod->s_opt->opt_subst_param = 1; io->mod->s_opt->opt_pinvar = 1; io->mod->ras->pinvar->v = 0.2; io->mod->ras->invar = 1; break; } case 'N' : case 'n' : { char *p; p = (char *)mCalloc(100,sizeof(char)); PhyML_Printf("\n. Enter your value of p-invar > "); Getstring_Stdin(p); n_trial = 0; while((atof(p) < 0.0) || (atof(p) > 1.0)) { if(++n_trial > 10) Exit("\n== Err : the proportion of invariable sites must be a positive number between 0.0 and 1.0"); PhyML_Printf("\n. The proportion must be a positive number between 0.0 and 1.0\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(p); } io->mod->ras->pinvar->v = (phydbl)atof(p); if(io->mod->ras->pinvar->v > 0.0+SMALL) io->mod->ras->invar = 1; else io->mod->ras->invar = 0; Free(p); io->mod->s_opt->opt_pinvar = 0; break; } } break; } case 'T' : { char answer; int n_trial; answer = 0; if((io->datatype == AA) || (io->mod->whichmodel == JC69)|| (io->mod->whichmodel == F81) || (io->mod->whichmodel == GTR) || (io->mod->whichmodel == CUSTOM)) { PhyML_Printf("\n. 'K' is not a valid choice for this model\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } switch(io->mod->s_opt->opt_kappa) { case 0 : { PhyML_Printf("\n. Optimise ts/tv ratio ? [Y/n] "); if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'Y'; else getchar(); break; } case 1 : { PhyML_Printf("\n. Optimise ts/tv ratio ? [N/y] "); if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); break; } default : Exit("\n"); } n_trial = 0; while((answer != 'Y') && (answer != 'y') && (answer != 'N') && (answer != 'n')) { if(++n_trial > 10) Exit("\n== Err : wrong answers !"); PhyML_Printf("\n. Optimise ts/tv ratio ? [N/y] "); if(!scanf("%c", &answer)) Exit("\n"); if(answer == '\n') answer = 'N'; else getchar(); } switch(answer) { case 'Y' : case 'y' : { io->mod->kappa->v = 4.0; io->mod->s_opt->opt_subst_param = 1; io->mod->s_opt->opt_kappa = 1; if(io->mod->whichmodel == TN93) io->mod->s_opt->opt_lambda = 1; break; } case 'N' : case 'n' : { char *t; t = (char *)mCalloc(100,sizeof(char)); io->mod->s_opt->opt_kappa = 0; PhyML_Printf("\n. Enter your value of the ts/tv ratio > "); Getstring_Stdin(t); n_trial = 0; while(atof(t) < .0) { if(++n_trial > 10) Exit("\n== Err : the ts/tv ratio must be a positive number\n"); PhyML_Printf("\n. The ratio must be a positive number"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(t); } io->mod->kappa->v = (phydbl)atof(t); io->mod->s_opt->opt_kappa = 0; io->mod->s_opt->opt_lambda = 0; Free(t); break; } } break; } case 'F' : { if((io->mod->whichmodel == JC69) || (io->mod->whichmodel == K80)) { Warn_And_Exit("\n. 'F' is not a valid choice with these model settings.\n"); } io->mod->s_opt->opt_state_freq = (io->mod->s_opt->opt_state_freq)?(0):(1); break; } case 'M' : { if(io->datatype == NT) { if(!strcmp(io->nt_or_cd,"nucleotides")) { if(io->mod->whichmodel == JC69) { io->mod->whichmodel = K80; } else if(io->mod->whichmodel == K80) { io->mod->whichmodel = F81; } else if(io->mod->whichmodel == F81) { io->mod->whichmodel = HKY85; } else if(io->mod->whichmodel == HKY85) { io->mod->whichmodel = F84; } else if(io->mod->whichmodel == F84) { io->mod->whichmodel = TN93; } else if(io->mod->whichmodel == TN93) { io->mod->whichmodel = GTR; } else if(io->mod->whichmodel == GTR) { io->mod->whichmodel = CUSTOM; } else if(io->mod->whichmodel == CUSTOM) { io->mod->whichmodel = JC69; } } } else if(io->datatype == AA) { if(io->mod->whichmodel == LG) { io->mod->whichmodel = WAG; } else if(io->mod->whichmodel == WAG) { io->mod->whichmodel = DAYHOFF; } else if(io->mod->whichmodel == DAYHOFF) { io->mod->whichmodel = JTT; } else if(io->mod->whichmodel == JTT) { io->mod->whichmodel = BLOSUM62; } else if(io->mod->whichmodel == BLOSUM62) { io->mod->whichmodel = MTREV; } else if(io->mod->whichmodel == MTREV) { io->mod->whichmodel = RTREV; } else if(io->mod->whichmodel == RTREV) { io->mod->whichmodel = CPREV; } else if(io->mod->whichmodel == CPREV) { io->mod->whichmodel = DCMUT; } else if(io->mod->whichmodel == DCMUT) { io->mod->whichmodel = VT; } else if(io->mod->whichmodel == VT) { io->mod->whichmodel = MTMAM; } else if(io->mod->whichmodel == MTMAM) { io->mod->whichmodel = MTART; } else if(io->mod->whichmodel == MTART) { io->mod->whichmodel = HIVW; } else if(io->mod->whichmodel == HIVW) { io->mod->whichmodel = HIVB; } else if(io->mod->whichmodel == HIVB) { io->mod->whichmodel = AB; } else if(io->mod->whichmodel == AB) { io->mod->whichmodel = CUSTOMAA; } else if(io->mod->whichmodel == CUSTOMAA) { io->mod->whichmodel = LG; } } else if(io->datatype == GENERIC) { io->mod->whichmodel = JC69; } Set_Model_Name(io->mod); break; } case '-' : { io->curr_interface = INTERFACE_DATA_TYPE; break; } case '+' : { io->curr_interface = (io->config_multigene)?(INTERFACE_DATA_TYPE):(INTERFACE_TOPO_SEARCH); break; } case 'Y' : { io->ready_to_go = 1; break; } default : { break; } } if(io->mod->s_opt->opt_alpha || io->mod->s_opt->opt_kappa || io->mod->s_opt->opt_lambda || io->mod->s_opt->opt_pinvar || io->mod->s_opt->opt_rr) io->mod->s_opt->opt_subst_param = 1; else io->mod->s_opt->opt_subst_param = 0; Free(s); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Topo_Search(option *io) { char choix; char *s; s = (char *)mCalloc(100,sizeof(char)); Clear(); Print_Banner(stdout); PhyML_Printf("\n\n"); PhyML_Printf(" ....................... \n"); PhyML_Printf(" Menu : Tree Searching \n"); PhyML_Printf(" ............................. \n"); PhyML_Printf("\n\n"); PhyML_Printf(" [+] " ".................................... Next sub-menu\n"); PhyML_Printf(" [-] " "................................ Previous sub-menu\n"); PhyML_Printf(" [Y] " ".............................. Launch the analysis\n"); PhyML_Printf("\n"); PhyML_Printf(" [O] " "........................... Optimise tree topology " " %-15s \n", (io->mod->s_opt->opt_topo)?("yes"):("no")); if(io->mod->s_opt->opt_topo) { switch(io->in_tree) { case 0: { strcpy(s,"BioNJ"); break; } case 1: { strcpy(s,"parsimony"); break; } case 2: { strcpy(s,"user tree"); break; } } PhyML_Printf(" [U] " "........ Starting tree (BioNJ/parsimony/user tree) " " %-15s \n",s); } else { switch(io->in_tree) { case 0: { strcpy(s,"BioNJ"); break; } case 2: { strcpy(s,"user tree"); break; } } PhyML_Printf(" [U] " "..................... Input tree (BioNJ/user tree) " " %-15s \n",s); } if(io->mod->s_opt->opt_topo) { char *s; s = (char *)mCalloc(T_MAX_OPTION,sizeof(char)); if(io->mod->s_opt->topo_search == NNI_MOVE) { strcpy(s,"NNI moves (fast, approximate)\0"); } else if(io->mod->s_opt->topo_search == SPR_MOVE) { strcpy(s,"SPR moves (slow, accurate)\0"); } else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) { strcpy(s,"Best of NNI and SPR \0"); } PhyML_Printf(" [S] " ".................. Tree topology search operations " " %-15s \n",s); Free(s); if(io->mod->s_opt->topo_search != NNI_MOVE) { PhyML_Printf(" [R] " "........................ Add random starting trees " " %-15s \n", (io->mod->s_opt->random_input_tree)?("yes"):("no")); if(io->mod->s_opt->random_input_tree) { PhyML_Printf(" [N] " ".................. Number of random starting trees " " %-15d \n",io->mod->s_opt->n_rand_starts); } } } else { PhyML_Printf(" [L] " ".......................... Optimise branch lengths " " %-15s \n", (io->mod->s_opt->opt_bl)?("yes"):("no")); } PhyML_Printf("\n\n. Are these settings correct ? " "(type '+', '-', 'Y' or other letter for one to change) "); if(!scanf("%c",&choix)) Exit("\n"); if(choix != '\n') getchar(); /* \n */ Free(s); Uppercase(&choix); switch(choix) { case '-' : { io->curr_interface = INTERFACE_MODEL; break; } case '+' : { io->curr_interface = INTERFACE_BRANCH_SUPPORT; break; } case 'Y' : { io->ready_to_go = 1; break; } case 'U' : { io->in_tree++; if(!io->mod->s_opt->opt_topo) { if(io->in_tree == 1) io->in_tree = 2; } if(io->in_tree == 3) io->in_tree = 0; break; } case 'N' : { char *n; int n_trial; PhyML_Printf("\n. Enter your number of starting trees > "); n = (char *)mCalloc(100,sizeof(char)); Getstring_Stdin(n); n_trial = 0; while(atoi(n) < 1) { if(++n_trial > 10) Exit("\n== Err : the number of starting trees must be a positive integer\n"); PhyML_Printf("\n. The number of starting trees must be a positive integer\n"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(n); } io->mod->s_opt->n_rand_starts = atoi(n); io->n_trees = 1; Free(n); break; } case 'O' : { io->mod->s_opt->opt_topo = (io->mod->s_opt->opt_topo)?(0):(1); break; } case 'L' : { if(!io->mod->s_opt->opt_topo) { io->mod->s_opt->opt_bl = (io->mod->s_opt->opt_bl)?(0):(1); } break; } case 'S' : { if(io->mod->s_opt->topo_search == NNI_MOVE) { io->mod->s_opt->topo_search = SPR_MOVE; io->mod->s_opt->n_rand_starts = 1; io->mod->s_opt->random_input_tree = 0; io->mod->s_opt->greedy = 0; } else if(io->mod->s_opt->topo_search == SPR_MOVE) { io->mod->s_opt->topo_search = BEST_OF_NNI_AND_SPR; io->mod->s_opt->n_rand_starts = 1; io->mod->s_opt->random_input_tree = 0; io->mod->s_opt->greedy = 0; } else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) { io->mod->s_opt->topo_search = NNI_MOVE; io->mod->s_opt->n_rand_starts = 1; io->mod->s_opt->random_input_tree = 0; io->mod->s_opt->greedy = 0; } break; } case 'R' : { io->mod->s_opt->random_input_tree = (io->mod->s_opt->random_input_tree)?(0):(1); if(io->mod->s_opt->random_input_tree) { if(io->fp_in_tree) fclose(io->fp_in_tree); /* io->in_tree = 0; */ io->n_trees = 1; io->mod->s_opt->n_rand_starts = 5; strcpy(io->out_trees_file,io->in_align_file); strcat(io->out_trees_file,"_phyml_trees.txt"); } break; } default : { break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Branch_Support(option *io) { char choix; char *s; s = (char *)mCalloc(100,sizeof(char)); Clear(); Print_Banner(stdout); PhyML_Printf("\n\n"); PhyML_Printf(" ....................... \n"); PhyML_Printf(" Menu : Branch Support \n"); PhyML_Printf(" ............................. \n"); PhyML_Printf("\n\n"); PhyML_Printf(" [+] " ".................................... Next sub-menu\n"); PhyML_Printf(" [-] " "................................ Previous sub-menu\n"); PhyML_Printf(" [Y] " ".............................. Launch the analysis\n"); PhyML_Printf("\n"); strcpy(s,(io->mod->bootstrap > 0)?("yes"):("no")); if(io->mod->bootstrap > 0) sprintf(s+strlen(s)," (%d replicate%s)", io->mod->bootstrap, (io->mod->bootstrap>1)?("s"):("")); /* PhyML_Printf(" [+] " */ PhyML_Printf(" [B] " "................ Non parametric bootstrap analysis " " %-15s \n",s); if(io->ratio_test == 0) { strcpy(s,"no"); } else if(io->ratio_test == 1) { strcpy(s,"yes / aLRT statistics"); } else if(io->ratio_test == 2) { strcpy(s,"yes / Chi2-based supports"); } else if(io->ratio_test == 3) { strcpy(s,"yes / min of SH-like & Chi2-based supports"); } else if(io->ratio_test == 4) { strcpy(s,"yes / SH-like supports"); } else if(io->ratio_test == 5) { strcpy(s,"yes / aBayes supports"); } /* PhyML_Printf(" [+] " */ PhyML_Printf(" [A] " "................ Approximate likelihood ratio test " " %-15s \n",s); PhyML_Printf("\n. Are these settings correct ? " "(type '+', '-', 'Y' or other letter for one to change) "); if(!scanf("%c",&choix)) Exit("\n"); if(choix != '\n') getchar(); /* \n */ Uppercase(&choix); Free(s); switch(choix) { /* case '\n': */ /* { */ /* io->curr_interface++; */ /* break; */ /* } */ case 'B' : { if(io->mod->bootstrap > 0) io->mod->bootstrap = 0; else { char *r; char answer; int n_trial; answer = 0; io->ratio_test = 0; if(io->n_data_sets > 1) { PhyML_Printf("\n. Bootstrap option is not allowed with multiple data sets.\n"); PhyML_Printf("\n. Type any key to exit.\n"); if(!scanf("%c",&choix)) Exit("\n"); Exit("\n"); } PhyML_Printf("\n. Number of replicates > "); r = (char *)mCalloc(T_MAX_OPTION,sizeof(char)); Getstring_Stdin(r); n_trial = 0; while((!atoi(r)) || (atoi(r) < 0)) { if(++n_trial > 10) Exit("\n== Err : the number of replicates must be a positive integer\n"); PhyML_Printf("\n. The number of replicates must be a positive integer"); PhyML_Printf("\n. Enter a new value > "); Getstring_Stdin(r); } io->mod->bootstrap = atoi(r); PhyML_Printf("\n. Print bootstrap trees (and statistics) ? (%s) > ", (io->print_boot_trees)?("Y/n"):("y/N")); if(!scanf("%c",&answer)) Exit("\n"); if(answer == '\n') answer = (io->print_boot_trees)?('Y'):('N'); else getchar(); switch(answer) { case 'Y' : case 'y' : { io->print_boot_trees = 1; strcpy(io->out_boot_tree_file,io->in_align_file); strcat(io->out_boot_tree_file,"_phyml_boot_trees.txt"); io->fp_out_boot_tree = Openfile(io->out_boot_tree_file,1); strcpy(io->out_boot_stats_file,io->in_align_file); strcat(io->out_boot_stats_file,"_phyml_boot_stats.txt"); io->fp_out_boot_stats = Openfile(io->out_boot_stats_file,1); break; } case 'N' : case 'n' : { io->print_boot_trees = 0; io->fp_out_boot_tree = NULL; io->fp_out_boot_stats = NULL; break; } } Free(r); } break; } case 'A' : { io->mod->bootstrap = 0; switch(io->ratio_test) { case 0 : { io->ratio_test = 1; break; } case 1 : { io->ratio_test = 2; break; } case 2 : { /* io->ratio_test = 3; */ io->ratio_test = 4; break; } case 3 : { io->ratio_test = 4; break; } case 4 : { io->ratio_test = 5; break; } case 5 : { io->ratio_test = 0; break; } } break; } case '-' : { io->curr_interface = INTERFACE_TOPO_SEARCH; break; } case '+' : { io->curr_interface = INTERFACE_DATA_TYPE; break; } case 'Y' : { io->ready_to_go = 1; break; } default : break; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Launch_Interface_Multigene(option *io) { #ifdef PART if((io->n_data_sets > 1) && (io->multigene)) { int set, n_trial; char choix; io->n_part = io->n_data_sets; io->st = (supert_tree *)PART_Make_Supert_tree_Light(io); io->st->n_part = io->n_data_sets; For(set,io->n_part) { io->st->optionlist[set] = Make_Input(); Set_Defaults_Input(io->st->optionlist[set]); Set_Defaults_Model(io->st->optionlist[set]->mod); Set_Defaults_Optimiz(io->st->optionlist[set]->mod->s_opt); io->st->optionlist[set]->curr_gt = set; PhyML_Printf("\n. Enter the sequence file name [data set %2d] > ",set+1); fflush(NULL); Getstring_Stdin(io->st->optionlist[set]->in_align_file); io->st->optionlist[set]->fp_in_align = Openfile(io->st->optionlist[set]->in_align_file,0); } PhyML_Printf("\n. Do you want to use your own initial tree ? [N/y] "); if(!scanf("%c", &choix)) Exit("\n"); if(choix != '\n') getchar(); n_trial = 0; while((choix != 'Y') && (choix != 'y') && (choix != 'N') && (choix != 'n')) { if(++n_trial > 10) Exit("\n== Err : wrong answers !"); PhyML_Printf("\n. Do you want to use your own initial tree ? [N/y] ? "); if(!scanf("%c", &choix)) Exit("\n"); if(choix == '\n') choix = 'N'; else getchar(); } switch(choix) { case '\n' : break; case 'Y' : case 'y' : { io->in_tree = 2; PhyML_Printf("\n. Enter the name of the tree file > "); Getstring_Stdin(io->in_tree_file); io->fp_in_tree = Openfile(io->in_tree_file,0); break; } case 'N' : case 'n' : { io->in_tree = 0; break; } default : break; } io->curr_gt = 0; do { io->st->optionlist[io->curr_gt]->config_multigene = 1; do { switch(io->st->optionlist[io->curr_gt]->curr_interface) { case INTERFACE_DATA_TYPE : { Launch_Interface_Data_Type(io->st->optionlist[io->curr_gt]); break; } case INTERFACE_MODEL : { Launch_Interface_Model(io->st->optionlist[io->curr_gt]); break; } default : { PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Exit(""); break; } } }while(!io->st->optionlist[io->curr_gt]->ready_to_go); io->curr_gt++; }while(io->curr_gt < io->n_part); } io->ready_to_go = 1; PART_Fill_Model_Partitions_Table(io->st); #endif } phyml-3.2.0/src/interface.h000066400000000000000000000014451263450375500155630ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef INTERFACE_H #define INTERFACE_H #include "utilities.h" #include "help.h" #include "models.h" #include "free.h" #include "help.h" void Launch_Interface(option *input); void Clear(); void Launch_Interface_Input(option *input); void Launch_Interface_Data_Type(option *input); void Launch_Interface_Model(option *input); void Launch_Interface_Topo_Search(option *input); void Launch_Interface_Branch_Support(option *input); void Launch_Interface_Multigene(option *input); #endif phyml-3.2.0/src/invitee.c000066400000000000000000003015641263450375500152660ustar00rootroot00000000000000#include "spr.h" #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "mixt.h" #include "invitee.h" #ifdef MPI #include "mpi_boot.h" #endif #include ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PhyTime_XML(char *xml_file) { FILE *f; char **clade, *clade_name, **mon_list; phydbl low, up; int i, j, n_taxa, clade_size, node_num, n_mon; //rnd_num xml_node *n_r, *n_t, *n_m, *n_cur; t_cal *last_calib; align **data, **c_seq; option *io; calign *cdata; t_opt *s_opt; t_mod *mod; time_t t_beg,t_end; int r_seed; char *most_likely_tree; int user_lk_approx; t_tree *tree; t_node **a_nodes; //*node; m4 *m4mod; srand(time(NULL)); i = 0; j = 0; last_calib = NULL; mod = NULL; most_likely_tree = NULL; n_taxa = 0; node_num = -1; //file can/cannot be open: if ((f =(FILE *)fopen(xml_file, "r")) == NULL) { PhyML_Printf("\n== File '%s' can not be opened...\n",xml_file); Exit("\n"); } n_r = XML_Load_File(f); //memory allocation for model parameters: io = (option *)Make_Input(); mod = (t_mod *)Make_Model_Basic(); s_opt = (t_opt *)Make_Optimiz(); m4mod = (m4 *)M4_Make_Light(); Set_Defaults_Input(io); Set_Defaults_Model(mod); Set_Defaults_Optimiz(s_opt); io -> mod = mod; mod = io -> mod; mod -> s_opt = s_opt; clade_size = -1; //////////////////////////////////////////////////////////////////////////// //////////////////////reading tree topology://////////////////////////////// //looking for a node n_t = XML_Search_Node_Name("topology", YES, n_r); //setting tree: /* tree = (t_tree *)mCalloc(1,sizeof(t_tree)); */ n_cur = XML_Search_Node_Name("instance", YES, n_t); if(n_cur != NULL) { if(XML_Search_Attribute(n_cur, "user.tree") != NULL) { strcpy(io -> out_tree_file, XML_Search_Attribute(n_cur, "user.tree") -> value); io -> fp_out_tree = Openfile(io -> out_tree_file, 1); io -> tree = Read_Tree_File_Phylip(io -> fp_in_tree); } else { PhyML_Printf("\n== No input tree was not found. \n"); PhyML_Printf("\n== Please specify either a tree file name or enter the whole tree directly in the XML file (in Newick format). \n"); Exit("\n"); } } else io -> tree = Read_Tree(&n_t -> value); io -> n_otu = io -> tree -> n_otu; tree = io -> tree; //setting initial values to n_calib: For(i, 2 * tree -> n_otu - 2) { tree -> a_nodes[i] -> n_calib = 0; //PhyML_Printf("\n. '%d' \n", tree -> a_nodes[i] -> n_calib); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //memory for nodes: a_nodes = (t_node **)mCalloc(2 * io -> n_otu - 1,sizeof(t_node *)); For(i, 2 * io -> n_otu - 2) a_nodes[i] = (t_node *)mCalloc(1,sizeof(t_node)); //setting a model: tree -> rates = RATES_Make_Rate_Struct(io -> n_otu); RATES_Init_Rate_Struct(tree -> rates, io -> rates, tree -> n_otu); //reading seed: if(XML_Search_Attribute(n_r, "seed")) io -> r_seed = String_To_Dbl(XML_Search_Attribute(n_r, "seed") -> value); //TO DO: check that the tree has a root Update_Ancestors(io -> tree -> n_root, io -> tree -> n_root -> v[2], io -> tree); Update_Ancestors(io -> tree -> n_root, io -> tree -> n_root -> v[1], io -> tree); //////////////////////////////////////////////////////////////////////////// //////////////////////memory allocation for temp parameters///////////////// //memory for monitor flag: io -> mcmc -> monitor = (int *)mCalloc(2 * io -> n_otu - 1,sizeof(int)); //memory for sequences: n_cur = XML_Search_Node_Name("alignment", YES, n_r); data = (align **)mCalloc(io -> n_otu,sizeof(align *)); For(i, io -> n_otu) { data[i] = (align *)mCalloc(1,sizeof(align)); data[i] -> name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); if(n_cur -> child -> value != NULL) data[i] -> state = (char *)mCalloc(strlen(n_cur -> child -> value) + 1,sizeof(char)); else data[i] -> state = (char *)mCalloc(T_MAX_SEQ,sizeof(char)); } io -> data = data; //tree -> data = data; //memory for clade: clade_name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); //memory for list of clades to be monitored mon_list = (char **)mCalloc(T_MAX_FILE,sizeof(char *)); For(i, T_MAX_FILE) { mon_list[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //reading monitor node: i = 0; n_m = XML_Search_Node_Name("monitor", YES, n_r); if(n_m != NULL) { do { strcpy(mon_list[i], n_m -> child -> attr -> value); i++; if(n_m -> child) n_m -> child = n_m -> child -> next; else break; } while(n_m -> child); n_mon = i; } else { n_mon = 0; PhyML_Printf("\n. There is no clade to be monitored. \n"); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //chekcing for calibration node (upper or lower bound) to exist: n_cur = XML_Search_Node_Name("calibration", YES, n_r); if(n_cur == NULL) { PhyML_Printf("\n== There is no calibration information provided. \n"); PhyML_Printf("\n== Please check your data. \n"); Exit("\n"); } else { if(XML_Search_Node_Name("upper", NO, n_cur -> child) == NULL && XML_Search_Node_Name("lower", NO, n_cur -> child) == NULL) { PhyML_Printf("\n== There is no calibration information provided. \n"); PhyML_Printf("\n== Please check your data. \n"); Exit("\n"); } } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// if(XML_Search_Attribute(n_r, "use_data") != NULL) { if(XML_Search_Attribute(n_r, "use_data") -> value != NULL && (!strcmp(XML_Search_Attribute(n_r, "use_data") -> value, "YES"))) io -> mcmc -> use_data = YES; if(XML_Search_Attribute(n_r, "use_data") -> value != NULL && (!strcmp(XML_Search_Attribute(n_r, "use_data") -> value, "NO"))) io -> mcmc -> use_data = NO; } n_r = n_r -> child; tree -> rates -> tot_num_cal = 0; do { if(!strcmp(n_r -> name, "alignment"))//looking for a node . { if(!n_r -> attr -> value) { PhyML_Printf("\n== Sequence type (nt / aa) must be provided. \n"); PhyML_Printf("\n== Please, include this information as an attribute of component <%s>. \n", n_r -> name); Exit("\n"); } char *s; s = To_Upper_String(n_r -> attr -> value); /* if(!strcmp(To_Upper_String(n_r -> attr -> value), "NT")) */ if(!strcmp(s, "NT")) { io -> datatype = 0; io -> mod -> ns = 4; } /* if(!strcmp(To_Upper_String(n_r -> attr -> value), "AA")) */ if(!strcmp(s, "AA")) { io -> datatype = 1; io -> mod -> ns = 20; } free(s); n_cur = XML_Search_Node_Name("instance", YES, n_r); if(n_cur != NULL) { if(XML_Search_Attribute(n_cur, "user.alignment") != NULL) { strcpy(io -> in_align_file, XML_Search_Attribute(n_cur, "user.alignment") -> value); io -> fp_in_align = Openfile(io -> in_align_file, 1); Detect_Align_File_Format(io); io -> data = Get_Seq(io); } } else { char *s; i = 0; s = To_Upper_String(n_r -> child -> value); do { strcpy(io -> in_align_file, "invitee"); strcpy(io -> data[i] -> name, n_r -> child -> attr -> value); /* strcpy(io -> data[i] -> state, To_Upper_String(n_r -> child -> value)); */ strcpy(io -> data[i] -> state, s); i++; if(n_r -> child -> next) n_r -> child = n_r -> child -> next; else break; } while(n_r -> child); n_taxa = i; free(s); } //checking if a sequences of the same lengths: i = 1; For(i, n_taxa) if(strlen(io -> data[0] -> state) != strlen(io -> data[i] -> state)) { PhyML_Printf("\n== All the sequences should be of the same length. Please check your data...\n"); Exit("\n"); break; } //checking sequence names: i = 0; For(i, n_taxa) Check_Sequence_Name(io -> data[i] -> name); //check if a number of tips is equal to a number of taxa: if(n_taxa != io -> n_otu) { PhyML_Printf("\n== The number of taxa is not the same as a number of tips. Check your data...\n"); Exit("\n"); } //deleting '-', etc. from sequences: io -> data[0] -> len = strlen(io -> data[0] -> state); Post_Process_Data(io); n_r = n_r -> next; } else if(!strcmp(n_r -> name, "calibration"))//looking for a node . { tree -> rates -> tot_num_cal++; if (tree -> rates -> calib == NULL) tree -> rates -> calib = Make_Calib(tree -> n_otu); if(last_calib) { last_calib -> next = tree -> rates -> calib; tree -> rates -> calib -> prev = last_calib; } last_calib = tree -> rates -> calib; low = -BIG; up = BIG; n_cur = XML_Search_Node_Name("lower", YES, n_r); if(n_cur != NULL) low = String_To_Dbl(n_cur -> value); n_cur = XML_Search_Node_Name("upper", YES, n_r); if(n_cur != NULL) up = String_To_Dbl(n_cur -> value); do { if(!strcmp("appliesto", n_r -> child -> name)) { //case of internal node: strcpy(clade_name, n_r -> child -> attr -> value);//reached clade names n_r -> child -> attr -> value if(!strcmp("root", clade_name)) { node_num = io -> tree -> n_root -> num; } else if(strcmp("NO_CLADE", clade_name) && strcmp("root", clade_name)) { xml_node *n_clade, *nd2; nd2 = n_r -> parent; n_clade = XML_Search_Node_Generic("clade", "id", clade_name, YES, nd2); if(n_clade) //found clade with a given name { i = 0; xml_node *nd; nd = n_clade -> child; clade = XML_Reading_Clade(nd, tree); clade_size = XML_Number_Of_Taxa_In_Clade(nd); node_num = Find_Clade(clade, clade_size, io -> tree); } else { PhyML_Printf("\n== The calibration information for clade [%s] was not found.", clade_name); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } if(strcmp("NO_CLADE", clade_name)) { For(j, n_mon) { if(!strcmp(clade_name, mon_list[j])) io -> mcmc -> monitor[node_num] = YES; } } if(strcmp("NO_CLADE", clade_name)) { tree -> rates -> calib -> proba[node_num] = String_To_Dbl(n_r -> child -> attr -> next -> value); if(!n_r -> child -> attr -> next && n_r -> child -> next == NULL) tree -> rates -> calib -> proba[node_num] = 1.; if(!n_r -> child -> attr -> next && n_r -> child -> next) { PhyML_Printf("\n== You either need to provide information about the probability with which calibration "); PhyML_Printf("\n== applies to a node or you need to apply calibration only to one node."); PhyML_Printf("\n. Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } tree -> rates -> calib -> all_applies_to[tree -> rates -> calib -> n_all_applies_to] -> num = node_num; } else tree -> rates -> calib -> proba[2 * tree -> n_otu - 1] = String_To_Dbl(n_r -> child -> attr -> next -> value); tree -> rates -> calib -> n_all_applies_to++; tree -> rates -> calib -> lower = low; tree -> rates -> calib -> upper = up; PhyML_Printf("\n. Lower bound: %f.", low); PhyML_Printf("\n. Upper bound: %f.", up); ///////////////////////////////////////////////////////////////////////////////////////////////////// PhyML_Printf("\n. ......................................................................."); PhyML_Printf("\n"); if(strcmp(clade_name, "NO_CLADE")) PhyML_Printf("\n. Clade name: [%s]", clade_name); else { PhyML_Printf("\n. Calibration with:"); PhyML_Printf("\n. Lower bound set to: %15f time units.", low); PhyML_Printf("\n. Upper bound set to: %15f time units.", up); PhyML_Printf("\n. does not apply to any node with probability [%f]", String_To_Dbl(n_r -> child -> attr -> next -> value)); PhyML_Printf("\n. ......................................................................."); } if(strcmp(clade_name, "root") && strcmp(clade_name, "NO_CLADE")) { For(i, clade_size) PhyML_Printf("\n. Taxon name: [%s]", clade[i]); } if(strcmp(clade_name, "NO_CLADE")) { PhyML_Printf("\n. Node number to which calibration applies to is [%d] with probability [%f]", node_num, String_To_Dbl(n_r -> child -> attr -> next -> value)); PhyML_Printf("\n. Lower bound set to: %15f time units.", low); PhyML_Printf("\n. Upper bound set to: %15f time units.", up); PhyML_Printf("\n. ......................................................................."); } ///////////////////////////////////////////////////////////////////////////////////////////////////// if(n_r -> child -> next) n_r -> child = n_r -> child -> next; else break; } else if(n_r -> child -> next) n_r -> child = n_r -> child -> next; else break; } while(n_r -> child); tree -> rates -> calib = tree -> rates -> calib -> next; n_r = n_r -> next; } else if(!strcmp(n_r -> name, "ratematrices"))//initializing rate matrix: { if(n_r -> child) { Make_Ratematrice_From_XML_Node(n_r -> child, io, mod); n_r = n_r -> next; } else n_r = n_r -> next; } else if(!strcmp(n_r -> name, "equfreqs"))//initializing frequencies: { if(n_r -> child) { Make_Efrq_From_XML_Node(n_r -> child , io, mod); n_r = n_r -> next; } else n_r = n_r -> next; } else if(!strcmp(n_r -> name, "siterates"))//initializing site rates: { if(n_r -> child) { Make_RAS_From_XML_Node(n_r, io -> mod); n_r = n_r -> next; } else n_r = n_r -> next; } else if (n_r -> next) n_r = n_r -> next; else break; } while(1); tree -> rates -> calib = last_calib; while(tree -> rates -> calib -> prev) tree -> rates -> calib = tree -> rates -> calib -> prev; //////////////////////////////////////////////////////////////////////////////////////////////// //Check for the sum of probabilities for one calibration add up to one do { phydbl p = 0.0; for(i = tree -> n_otu; i < 2 * tree -> n_otu; i++) { p = p + tree -> rates -> calib -> proba[i]; /* PhyML_Printf("\n. # applies to %d \n", tree -> rates -> calib -> n_all_applies_to); */ /* PhyML_Printf("\n. %f \n", tree -> rates -> calib -> proba[i]); */ } if(!Are_Equal(p, 1.0, 1.E-10)) { PhyML_Printf("\n. ......................................................................."); PhyML_Printf("\n. WARNING! The sum of the probabilities for the calibration with:"); PhyML_Printf("\n. Lower bound set to: %15f time units.", tree -> rates -> calib -> lower); PhyML_Printf("\n. Upper bound set to: %15f time units.", tree -> rates -> calib -> upper); PhyML_Printf("\n. is not equal to 1."); PhyML_Printf("\n. The probability that this calibration does not apply to any node is set to [%f].", 1.0 - p); PhyML_Printf("\n. ......................................................................."); tree -> rates -> calib -> proba[2 * tree -> n_otu - 1] = 1.0 - p; tree -> rates -> calib -> n_all_applies_to++; /* PhyML_Printf("\n==You need to provide proper probabilities for the calibration. \n"); */ /* PhyML_Printf("\n. Err. in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ } if(tree -> rates -> calib -> next) tree -> rates -> calib = tree -> rates -> calib -> next; else break; } while(tree -> rates -> calib); while(tree -> rates -> calib -> prev) tree -> rates -> calib = tree -> rates -> calib -> prev; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //clear memory: free(clade_name); For(i, tree -> n_otu) { free(clade[i]); } free(clade); For(i, T_MAX_FILE) { free(mon_list[i]); } free(mon_list); /* do */ /* { */ /* printf("\n %f %f \n", tree -> rates -> calib -> lower, tree -> rates -> calib -> upper); */ /* printf("\n numb applies to: %d \n", tree -> rates -> calib -> n_all_applies_to); */ /* For(i, tree -> rates -> calib -> n_all_applies_to) printf("\n Node number %d \n", tree -> rates -> calib -> all_applies_to[i] -> num); */ /* if(tree -> rates -> calib -> next) tree -> rates -> calib = tree -> rates -> calib -> next; */ /* else break; */ /* } */ /* while(tree -> rates -> calib); */ /* while(tree -> rates -> calib -> prev) tree -> rates -> calib = tree -> rates -> calib -> prev; */ /* Exit("\n"); */ //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //START analysis: r_seed = (io -> r_seed < 0)?(time(NULL)):(io -> r_seed); srand(r_seed); rand(); PhyML_Printf("\n. Seed: %d\n", r_seed); PhyML_Printf("\n. Pid: %d\n",getpid()); PhyML_Printf("\n. Compressing sequences...\n"); data = io -> data; data[0] -> len = strlen(data[0] -> state); //////////////////////////////////////////////////////////////////////////// //memory for compressed sequences: cdata = (calign *)mCalloc(1,sizeof(calign)); c_seq = (align **)mCalloc(io -> n_otu,sizeof(align *)); For(i, io -> n_otu) { c_seq[i] = (align *)mCalloc(1,sizeof(align)); c_seq[i] -> name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); c_seq[i] -> state = (char *)mCalloc(data[0] -> len + 1,sizeof(char)); } cdata -> c_seq = c_seq; //////////////////////////////////////////////////////////////////////////// cdata = Compact_Data(data, io); Free_Seq(io -> data, cdata -> n_otu); io -> mod -> io = io; Check_Ambiguities(cdata, io -> mod -> io -> datatype, io -> state_len); Make_Model_Complete(mod); Init_Model(cdata, mod, io); if(io -> mod -> use_m4mod) M4_Init_Model(mod -> m4mod, cdata, mod); time(&(t_beg)); RATES_Fill_Lca_Table(tree); tree -> mod = mod; tree -> io = io; tree -> data = cdata; tree -> n_pattern = tree -> data -> crunch_len / tree -> io -> state_len; Set_Both_Sides(YES, tree); Prepare_Tree_For_Lk(tree); //calculate the probabilities of each combination of calibrations: TIMES_Calib_Partial_Proba(tree); int cal_numb = 0; do { if(!Are_Equal(tree -> rates -> times_partial_proba[cal_numb], 0.0, 1.E-10)) break; else cal_numb += 1; } while(1); PhyML_Printf("\n. Calibration number chosen %d.\n", cal_numb); Set_Current_Calibration(cal_numb, tree); tree -> rates -> numb_calib_chosen[cal_numb]++; int tot_num_comb; tot_num_comb = Number_Of_Comb(tree -> rates -> calib); PhyML_Printf("\n. The number of calibration combinations that is going to be considered is %d.\n", tot_num_comb); /* For(i, tot_num_comb) Set_Current_Calibration(i, tree); */ /* Exit("\n"); */ //set initial value for Hastings ratio for conditional jump: /* tree -> rates -> c_lnL_Hastings_ratio = 0.0; */ TIMES_Set_All_Node_Priors(tree); tree -> rates -> cur_comb_numb = cal_numb; tree -> rates -> log_K_cur = K_Constant_Prior_Times_Log(tree); TIMES_Get_Number_Of_Time_Slices(tree); TIMES_Label_Edges_With_Calibration_Intervals(tree); tree -> write_br_lens = NO; PhyML_Printf("\n. Input tree with calibration information ('almost' compatible with MCMCtree).\n"); char *t; t = Write_Tree(tree, YES); PhyML_Printf("\n. %s \n", t); free(t); tree -> write_br_lens = YES; // Work with log of branch lengths? if(tree -> mod -> log_l == YES) Log_Br_Len(tree); if(io -> mcmc -> use_data == YES) { // Force the exact likelihood score user_lk_approx = tree -> io -> lk_approx; tree -> io -> lk_approx = EXACT; /* MLE for branch lengths */ /* printf("\n. %s",Write_Tree(tree,NO)); */ /* printf("\n. alpha %f",tree->mod->ras->alpha->v); */ /* printf("\n. %f %f %f %f",tree->mod->e_frq->pi->v[0],tree->mod->e_frq->pi->v[1],tree->mod->e_frq->pi->v[2],tree->mod->e_frq->pi->v[3]); */ /* Lk(NULL,tree); */ /* printf("\n. %f",tree->c_lnL); */ /* Exit("\n"); */ Round_Optimize(tree, tree -> data, ROUND_MAX); // Set vector of mean branch lengths for the Normal approximation of the likelihood RATES_Set_Mean_L(tree); // Estimate the matrix of covariance for the Normal approximation of the likelihood PhyML_Printf("\n"); PhyML_Printf("\n. Computing Hessian..."); tree -> rates -> bl_from_rt = 0; Free(tree -> rates -> cov_l); tree -> rates -> cov_l = Hessian_Seo(tree); // tree->rates->cov_l = Hessian_Log(tree); For(i, (2 * tree -> n_otu - 3) * (2 * tree -> n_otu - 3)) tree -> rates -> cov_l[i] *= -1.0; if(!Iter_Matinv(tree -> rates -> cov_l, 2 * tree -> n_otu - 3, 2 * tree -> n_otu - 3, YES)) Exit("\n"); tree -> rates -> covdet = Matrix_Det(tree -> rates -> cov_l, 2 * tree -> n_otu - 3, YES); For(i,(2 * tree -> n_otu - 3) * (2 * tree -> n_otu - 3)) tree -> rates -> invcov[i] = tree -> rates -> cov_l[i]; if(!Iter_Matinv(tree -> rates -> invcov, 2 * tree -> n_otu - 3, 2 * tree -> n_otu - 3, YES)) Exit("\n"); tree -> rates -> grad_l = Gradient(tree); // Pre-calculation of conditional variances to speed up calculations RATES_Bl_To_Ml(tree); RATES_Get_Conditional_Variances(tree); RATES_Get_All_Reg_Coeff(tree); RATES_Get_Trip_Conditional_Variances(tree); RATES_Get_All_Trip_Reg_Coeff(tree); Lk(NULL, tree); PhyML_Printf("\n"); PhyML_Printf("\n. p(data|model) [exact ] ~ %.2f",tree -> c_lnL); tree -> io -> lk_approx = NORMAL; For(i,2 * tree -> n_otu - 3) tree -> rates -> u_cur_l[i] = tree -> rates -> mean_l[i] ; tree -> c_lnL = Lk(NULL,tree); PhyML_Printf("\n. p(data|model) [approx] ~ %.2f",tree -> c_lnL); tree -> io -> lk_approx = user_lk_approx; } tree -> rates -> model = io -> rates -> model; PhyML_Printf("\n. Selected model '%s' \n", RATES_Get_Model_Name(io -> rates -> model)); if(tree -> rates -> model == GUINDON) tree -> mod -> gamma_mgf_bl = YES; tree -> rates -> bl_from_rt = YES; if(tree -> io -> cstr_tree) Find_Surviving_Edges_In_Small_Tree(tree, tree -> io -> cstr_tree); time(&t_beg); tree -> mcmc = MCMC_Make_MCMC_Struct(); MCMC_Copy_MCMC_Struct(tree -> io -> mcmc, tree -> mcmc, "phytime"); tree -> mod -> m4mod = m4mod; MCMC_Complete_MCMC(tree -> mcmc, tree); tree -> mcmc -> is_burnin = NO; MCMC(tree); PhyML_Printf("\n"); For(i,6) printf(" %d ", tree -> rates -> numb_calib_chosen[i]); PhyML_Printf("\n"); MCMC_Close_MCMC(tree -> mcmc); MCMC_Free_MCMC(tree -> mcmc); PhyML_Printf("\n"); Free_Calib(tree -> rates -> calib); Add_Root(tree->a_edges[0],tree); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); Free_Cseq(cdata); Free_Model(mod); if(io -> fp_in_align) fclose(io -> fp_in_align); if(io -> fp_in_tree) fclose(io -> fp_in_tree); if(io -> fp_out_lk) fclose(io -> fp_out_lk); if(io -> fp_out_tree) fclose(io -> fp_out_tree); if(io -> fp_out_trees) fclose(io -> fp_out_trees); if(io -> fp_out_stats) fclose(io -> fp_out_stats); fclose(f); Free(most_likely_tree); Free_Input(io); time(&t_end); Print_Time_Info(t_beg,t_end); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Calculate the prior probability for node times taking into account the //probailitis with which each calibration applies to the particular node. phydbl TIMES_Calib_Cond_Prob(t_tree *tree) { phydbl times_lk, *Yule_val, *times_partial_proba, times_tot_proba, c, constant, ln_t; int i, tot_num_comb; t_cal *calib; times_tot_proba = 0.0; calib = tree -> rates -> calib; times_partial_proba = tree -> rates -> times_partial_proba; tot_num_comb = Number_Of_Comb(calib); Yule_val = (phydbl *)mCalloc(tot_num_comb, sizeof(phydbl)); For(i, tot_num_comb) { Set_Current_Calibration(i, tree); int result; result = TRUE; TIMES_Set_All_Node_Priors_S(&result, tree); times_lk = TIMES_Lk_Yule_Order_Root_Cond(tree); constant = 0.0; if(tot_num_comb > 1 && times_lk > -INFINITY && result != FALSE && tree->rates->update_time_norm_const == YES) { tree -> rates -> node_height_dens_log_norm_const_update[i] = K_Constant_Prior_Times_Log(tree); constant = tree -> rates -> node_height_dens_log_norm_const_update[i]; } else constant = tree -> rates -> node_height_dens_log_norm_const_update[i]; Yule_val[i] = constant + times_lk; while(calib -> prev) calib = calib -> prev; } /* Exit("\n"); */ c = .0; times_tot_proba = 0.0; For(i, tot_num_comb) { times_tot_proba += times_partial_proba[i] * EXP(Yule_val[i] + c); } ln_t = -c + LOG(times_tot_proba); free(Yule_val); return(ln_t); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //Function calculates the normalizing constant K of the joint distribution Yule_Order. //Use the fact that density Yule_Order can be used streight forward only in case of the complete //overlap of the calibration intervals for all of the nodes or in case of no overlap. phydbl K_Constant_Prior_Times_Log(t_tree *tree) { int i, j, k, f, n_otu, *indic, *n_slice, *slice_numbers; phydbl buf, chop_bound, *t_prior_min, *t_prior_max, *t_slice, *t_slice_min, *t_slice_max, *g_i_node; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; n_otu = tree -> n_otu; t_slice = (phydbl *)mCalloc(2 * (n_otu - 1), sizeof(phydbl)); //the vector of the union of lower and upper bounds, lined up in incresing order. t_slice_min = (phydbl *)mCalloc(2 * n_otu - 3, sizeof(phydbl)); //vector of the lower bounds of the sliced intervals. t_slice_max = (phydbl *)mCalloc(2 * n_otu - 3, sizeof(phydbl)); //vector of the upper bounds of the sliced intervals. indic = (int *)mCalloc((n_otu - 1) * (2 * n_otu - 3), sizeof(int)); //vector of the indicators, columns - node numbers (i + n_otu), rows - the number of the sliced interval. slice_numbers = (int *)mCalloc((n_otu - 1) * (2 * n_otu - 3), sizeof(int )); //vecor of the slice intervals numbers, columns node numbers (i + n_otu), rows - the number of the sliced interval. n_slice = (int *)mCalloc(n_otu - 1, sizeof(int)); //vector of the numbers of sliced intervals that apply to one node with number (i + n_otu). g_i_node = (phydbl *)mCalloc((n_otu - 1) * (2 * n_otu - 3), sizeof(phydbl)); //vector of the values of the function g evaluated for each node. i = 0; /* K = 0; */ j = n_otu; //////////////////////////////////////////////////////////////////////////// //Put prior bounds in one vector t_slice. Excluding tips. For(i, n_otu - 1) { t_slice[i] = t_prior_min[j]; j++; } j = n_otu; for(i = n_otu - 1; i < 2 * n_otu - 3; i++) { t_slice[i] = t_prior_max[j]; j++; } if(tree -> rates -> nd_t[tree -> n_root -> num] > t_prior_min[tree -> n_root -> num]) chop_bound = MIN(tree -> rates -> nd_t[tree -> n_root -> num], t_prior_max[tree -> n_root -> num]); else chop_bound = t_prior_min[tree -> n_root -> num]; t_slice[2 * n_otu - 3] = chop_bound; //////////////////////////////////////////////////////////////////////////// //Get slices in increasing order. Excluding tips. do { f = NO; For(j, 2 * n_otu - 3) { if(t_slice[j] > t_slice[j + 1]) { buf = t_slice[j]; t_slice[j] = t_slice[j + 1]; t_slice[j + 1] = buf; f = YES; } } } while(f); for(j = 1; j < 2 * n_otu - 2; j++) t_slice[j] = MAX(chop_bound, t_slice[j]); //////////////////////////////////////////////////////////////////////////// //Get the intervals with respect to slices. Total number of t_slice_min(max) - 2 * n_otu - 3. Excluding tips. i = 0; For(j, 2 * n_otu - 3) { t_slice_min[j] = t_slice[i]; t_slice_max[j] = t_slice[i + 1]; i++; } //////////////////////////////////////////////////////////////////////////// //Getting indicators for the node number [i + n_otu] to have slice. i = i + n_otu is the node number on the tree and j is the slice number, total //number of intervals is 2 * n_otu - 3. Excluding tips. For(i, n_otu - 1) { For(j, 2 * n_otu - 3) { if(Are_Equal(t_prior_min[i + n_otu], t_slice_min[j], 1.E-10) && t_prior_max[i + n_otu] > t_slice_max[j] && t_prior_min[i + n_otu] < t_slice_max[j] && !Are_Equal(t_slice_max[j], t_slice_min[j], 1.E-10)) indic[i * (2 * n_otu - 3) + j] = 1; else if(Are_Equal(t_prior_max[i + n_otu], t_slice_max[j], 1.E-10) && t_prior_min[i + n_otu] < t_slice_min[j] && t_prior_max[i + n_otu] > t_slice_min[j] && !Are_Equal(t_slice_max[j], t_slice_min[j], 1.E-10)) indic[i * (2 * n_otu - 3) + j] = 1; else if(t_prior_min[i + n_otu] < t_slice_min[j] && t_prior_max[i + n_otu] > t_slice_max[j] && !Are_Equal(t_slice_max[j], t_slice_min[j], 1.E-10)) indic[i * (2 * n_otu - 3) + j] = 1; else if(Are_Equal(t_prior_min[i + n_otu], t_slice_min[j], 1.E-10) && Are_Equal(t_prior_max[i + n_otu], t_slice_max[j], 1.E-10)) indic[i * (2 * n_otu - 3) + j] = 1; } } For(i, n_otu - 2) { indic[i * (2 * n_otu - 3)] = 0; } for(j = 1; j < 2 * n_otu - 3; j++) { indic[(n_otu - 2) * (2 * n_otu - 3) + j] = 0; } /* printf("\n"); */ /* printf(" ", j); */ /* For(j, 2 * n_otu - 3) printf(". '%d' ", j); */ /* printf("\n"); */ /* For(i, n_otu - 1) */ /* { */ /* printf(" ['%d'] ", i + n_otu); */ /* For(j, 2 * n_otu - 3) */ /* { */ /* printf(". '%d' ", indic[i * (2 * n_otu - 3) + j]); */ /* } */ /* printf("\n"); */ /* } */ //////////////////////////////////////////////////////////////////////////// //Running through all of the combinations of slices int *cur_slices, *cur_slices_shr, *cur_slices_cpy, *slices_start_node, shr_num_slices; phydbl *t_cur_slice_min, *t_cur_slice_max; phydbl tot_num_comb; phydbl log_g_i, lmbd; lmbd = tree -> rates -> birth_rate; tot_num_comb = 1; t_cur_slice_min = (phydbl *)mCalloc(n_otu - 1, sizeof(phydbl)); t_cur_slice_max = (phydbl *)mCalloc(n_otu - 1, sizeof(phydbl)); cur_slices = (int *)mCalloc(n_otu - 1, sizeof(int)); //the vector of the current slices with repetition. cur_slices_cpy = (int *)mCalloc(n_otu - 1, sizeof(int)); slices_start_node = (int *)mCalloc(n_otu - 1, sizeof(int)); cur_slices_shr = (int *)mCalloc(n_otu - 1, sizeof(int)); //the vector of the current slices without repetition. //////////////////////////////////////////////////////////////////////////// //Get the number of slices that can be applied for each node and the vectors of slice numbers for each node. For(i, n_otu - 1) { k = 0; For(j, 2 * n_otu - 3) { if(indic[i * (2 * n_otu - 3) + j] == 1) { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// g_i_node[i * (2 * n_otu - 3) + j] = (EXP(lmbd * t_slice_max[j]) - EXP(lmbd * t_slice_min[j])) / (EXP(lmbd * t_prior_max[i + n_otu]) - EXP(lmbd * t_prior_min[i + n_otu])); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// slice_numbers[i * (2 * n_otu - 3) + k] = j; n_slice[i]++; k++; } } } /* printf("\n"); */ /* For(i, n_otu - 1) */ /* { */ /* printf(" ['%d'] ", i + n_otu); */ /* For(j, 2 * n_otu - 3) */ /* { */ /* printf(". '%f' ", g_i_node[i * (2 * n_otu - 3) + j]); */ /* } */ /* printf("\n"); */ /* } */ /* printf("\n"); */ /* For(i, n_otu - 1) */ /* { */ /* printf(" ['%d'] ", i + n_otu); */ /* For(j, n_slice[i]) */ /* { */ /* printf(". '%d' ", slice_numbers[i * (2 * n_otu - 3) + j]); */ /* } */ /* printf("\n"); */ /* } */ For(i, n_otu - 1) { tot_num_comb = tot_num_comb * n_slice[i]; } int r, numb_unsuc, max_size, comb_numb, *combinations, *max_combination, numb_approx; /* **combinations; */ phydbl K_total; phydbl *t_slice_min_f, *t_slice_max_f, *K_val_approx; int *root_nodes, *dif; phydbl K_total_cur, max_K_val, scl_const; max_size = 1000000; combinations = (int *)mCalloc(max_size*(n_otu-1), sizeof(int)); max_combination = (int *)mCalloc((n_otu-1), sizeof(int)); t_slice_min_f = (phydbl *)mCalloc(n_otu - 1, sizeof(phydbl)); t_slice_max_f = (phydbl *)mCalloc(n_otu - 1, sizeof(phydbl)); K_val_approx = (phydbl *)mCalloc(max_size, sizeof(phydbl)); root_nodes = (int *)mCalloc(n_otu - 1, sizeof(int)); dif = (int *)mCalloc(n_otu - 1, sizeof(int)); numb_approx = 0; max_K_val = 0; scl_const = 0.0; /* lmbd = 4.0; */ numb_unsuc = 0; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////CALCULATING THE MAXIMUM VALUE OF m_i * g_i FOR ONE COMBINATION OF SLICES://////////////////////////////////////////////////////////////// comb_numb = 0; K_total = 0.0; do { /* printf("\n ____________________________________________________________________________________________________ \n"); */ int x = 0, f = FALSE; For(i, n_otu - 1) { r = rand()%(n_slice[i]); t_slice_min_f[i] = t_slice_min[slice_numbers[i * (2 * n_otu - 3) + r]]; t_slice_max_f[i] = t_slice_max[slice_numbers[i * (2 * n_otu - 3) + r]]; cur_slices[i] = slice_numbers[i * (2 * n_otu - 3) + r]; } For(i, n_otu - 1) { cur_slices_cpy[i] = cur_slices[i]; slices_start_node[i] = cur_slices[i]; } For(i, n_otu - 1) { for(j = i + 1; j < n_otu - 1; j++) { if(cur_slices[i] == cur_slices[j]) cur_slices[j] = -1; } } //For(i, n_otu - 1) printf(" Slice number'%d' \n", cur_slices[i]); shr_num_slices = 0; For(i, n_otu -1) { if(cur_slices[i] >= 0) { cur_slices_shr[shr_num_slices] = cur_slices[i]; shr_num_slices++; } } int result_1; int c = 0; int num_elem; result_1 = TRUE; Check_Time_Slices(tree -> n_root, tree -> n_root -> v[1], &result_1, t_slice_min_f, t_slice_max_f, tree); Check_Time_Slices(tree -> n_root, tree -> n_root -> v[2], &result_1, t_slice_min_f, t_slice_max_f, tree); /* printf("\n. [START] Result '%d' \n", result_1); */ K_total_cur = 0.0; if(result_1 != TRUE) K_total_cur = 0.0; else { int n_1, n_2; num_elem = 0; x = 0; f = FALSE; if(comb_numb > 0) { For(i, comb_numb) { x = 0; For(j, n_otu - 1) { dif[j] = combinations[i*(n_otu-1) + j] - cur_slices_cpy[j]; if(dif[j] == 0) x++; } if(x == n_otu - 1) f = TRUE; } } if(!f) { For(i, n_otu - 1) combinations[comb_numb*(n_otu - 1) + i] = cur_slices_cpy[i]; /* printf("\n"); */ /* printf(" [1][CUR SLICES PROPOSED] "); */ /* printf(" [COMB NUMBER] = [%d] --- ", comb_numb); */ /* For(i, n_otu - 1) printf(". [%d] .", combinations[comb_numb*(n_otu - 1) + i]); */ /* printf("\n"); */ For(i, shr_num_slices) { Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[1], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[2], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); } /* for(i = 0; i < n_otu - 2; i++) printf("\n. [START] Node [%d] Slice_min [%f] Slice_max [%f] \n", i + n_otu, t_slice_min_f[i], t_slice_max_f[i]); */ For(j, num_elem) { n_1 = 0; n_2 = 0; Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[1], &n_1, t_slice_min_f, t_slice_max_f, tree); Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree); /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */ K_total_cur = K_total_cur + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1); /* printf("\n. K_total_cur [%f] \n", K_total_cur); */ /* printf("\n. [START] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */ } /* printf("\n. [START] LOG(m_i) [%f] \n", K_total_cur); */ /* printf("\n. K_total_cur [%f] \n", K_total_cur); */ log_g_i = 0.0; For(i, n_otu - 2) log_g_i += LOG_g_i(lmbd, t_slice_max_f[i], t_slice_min_f[i], t_prior_max[i + n_otu], MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num])); /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */ K_total_cur = EXP(K_total_cur + log_g_i + scl_const); if(K_total_cur > max_K_val) { For(i, n_otu - 1) max_combination[i] = cur_slices_cpy[i]; max_K_val = K_total_cur; } K_val_approx[numb_approx] = K_total_cur; numb_approx++; /* printf("\n. [APPROX] Approximated constant after start (K_total_cur) = [%f] \n", (K_total_cur)); */ /* printf("\n. [START] m_i * g_i [%f] \n", K_total_cur); */ /* printf("\n. [START] sum(m_i * g_i) = m_i * g_i [%f] \n", K_total_cur); */ /* printf("\n. K of the tree for starting combination of slices [%f] \n", K_total_cur); */ comb_numb++; if(comb_numb > max_size) { combinations = (int *)mRealloc(combinations, max_size*(n_otu - 1) + (n_otu - 1),sizeof(char)); max_size = max_size + 1; } c++; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /* printf("\n. ____________________________________________________________________________________________ \n"); */ phydbl K_part, K_max; int m, n, count; K_max = K_total_cur; /* printf("\n. K_total [%f] \n", K_total); */ do { r = rand()%(n_otu - 1); count = 0; For(m, r) { /* printf("\n. NODE NUMBER ['%d'] \n", m + n_otu); */ For(n, 2 * n_otu - 3) { K_part = 0.0; if(g_i_node[m * (2 * n_otu - 3) + n] > 0) { t_slice_min_f[m] = t_slice_min[n]; t_slice_max_f[m] = t_slice_max[n]; cur_slices_cpy[m] = n; For(i, n_otu - 1) cur_slices[i] = cur_slices_cpy[i]; For(i, n_otu - 1) { for(j = i + 1; j < n_otu - 1; j++) { if(cur_slices[i] == cur_slices[j]) cur_slices[j] = -1; } } shr_num_slices = 0; For(i, n_otu -1) { if(cur_slices[i] >= 0) { cur_slices_shr[shr_num_slices] = cur_slices[i]; shr_num_slices++; } } result_1 = TRUE; Check_Time_Slices(tree -> n_root, tree -> n_root -> v[1], &result_1, t_slice_min_f, t_slice_max_f, tree); Check_Time_Slices(tree -> n_root, tree -> n_root -> v[2], &result_1, t_slice_min_f, t_slice_max_f, tree); if(result_1 != TRUE) K_part = 0.0; else { int n_1, n_2; x = 0; f = FALSE; num_elem = 0; if(comb_numb > 0) { For(i, comb_numb) { x = 0; For(j, n_otu - 1) { dif[j] = combinations[i*(n_otu-1) + j] - cur_slices_cpy[j]; if(dif[j] == 0) x++; } if(x == n_otu - 1) f = TRUE; } } if(!f) { For(i, n_otu - 1) combinations[comb_numb*(n_otu-1) + i] = cur_slices_cpy[i]; /* printf("\n"); */ /* printf(" [2][CUR SLICES PROPOSED] "); */ /* printf(" [COMB NUMBER] = [%d] --- ", comb_numb); */ /* For(i, n_otu - 1) printf(". [%d] .", combinations[comb_numb*(n_otu-1) + i]); */ /* printf("\n"); */ For(i, shr_num_slices) { Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[1], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[2], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); } For(j, num_elem) { n_1 = 0; n_2 = 0; Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[1], &n_1, t_slice_min_f, t_slice_max_f, tree); Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree); /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */ K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1); /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */ } /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */ /* printf("\n. K_part [%f] \n", K_part); */ if(K_part > max_K_val) { For(i, n_otu - 1) max_combination[i] = cur_slices_cpy[i]; max_K_val = K_part; } log_g_i = 0.0; For(i, n_otu - 2) log_g_i += LOG_g_i(lmbd, t_slice_max_f[i], t_slice_min_f[i], t_prior_max[i + n_otu], MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num])); /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */ K_part = EXP(K_part + log_g_i + scl_const); if(K_part > max_K_val) { For(i, n_otu - 1) max_combination[i] = cur_slices_cpy[i]; max_K_val = K_part; } /* printf("\n. [START] m_i * g_i [%f] \n", K_part); */ K_val_approx[numb_approx] = K_part; numb_approx++; K_total_cur = K_total_cur + K_part; /* printf("\n. [APPROX] Approximated constant after one run (K_part) = [%f] \n", (K_part)); */ /* printf("\n. K_max [%f] K_part [%f] \n", K_max, K_part); */ /* printf("\n. [CONT] sum(m_i * g_i) [%f] \n", K_total_cur); */ if(K_max < K_part) { K_max = K_part; /* For(i, n_otu - 1) slices_start_node[i] = cur_slices_cpy[i]; */ count++; } comb_numb++; if(comb_numb > max_size) { combinations = (int *)mRealloc(combinations, max_size*(n_otu - 1) + (n_otu - 1),sizeof(char)); max_size = max_size + 1; } c++; } } } } } for(m = r; m < n_otu - 1; m++) { For(n, 2 * n_otu - 3) { K_part = 0.0; if(g_i_node[m * (2 * n_otu - 3) + n] > 0) { t_slice_min_f[m] = t_slice_min[n]; t_slice_max_f[m] = t_slice_max[n]; cur_slices_cpy[m] = n; For(i, n_otu - 1) cur_slices[i] = cur_slices_cpy[i]; For(i, n_otu - 1) { for(j = i + 1; j < n_otu - 1; j++) { if(cur_slices[i] == cur_slices[j]) cur_slices[j] = -1; } } shr_num_slices = 0; For(i, n_otu -1) { if(cur_slices[i] >= 0) { cur_slices_shr[shr_num_slices] = cur_slices[i]; shr_num_slices++; } } result_1 = TRUE; Check_Time_Slices(tree -> n_root, tree -> n_root -> v[1], &result_1, t_slice_min_f, t_slice_max_f, tree); Check_Time_Slices(tree -> n_root, tree -> n_root -> v[2], &result_1, t_slice_min_f, t_slice_max_f, tree); if(result_1 != TRUE) K_part = 0.0; else { int n_1, n_2; x = 0; f = FALSE; num_elem = 0; if(comb_numb > 0) { For(i, comb_numb) { x = 0; For(j, n_otu - 1) { dif[j] = combinations[i*(n_otu-1) + j] - cur_slices_cpy[j]; /* dif[j] = combinations[i][j] - cur_slices_cpy[j]; */ if(dif[j] == 0) x++; /* printf(". [%d] ", dif[j]); */ } if(x == n_otu - 1) f = TRUE; } } if(!f) { For(i, n_otu - 1) combinations[comb_numb*(n_otu-1) + i] = cur_slices_cpy[i]; /* printf("\n"); */ /* printf(" [2][CUR SLICES PROPOSED] "); */ /* printf(" [COMB NUMBER] = [%d] --- ", comb_numb); */ /* For(i, n_otu - 1) printf(". [%d] .", combinations[comb_numb*(n_otu-1) + i]); */ /* printf("\n"); */ For(i, shr_num_slices) { Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[1], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[2], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); } For(j, num_elem) { n_1 = 0; n_2 = 0; Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[1], &n_1, t_slice_min_f, t_slice_max_f, tree); Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree); /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */ K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1); /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */ } /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */ /* printf("\n. K_part [%f] \n", K_part); */ log_g_i = 0.0; For(i, n_otu - 2) log_g_i += LOG_g_i(lmbd, t_slice_max_f[i], t_slice_min_f[i], t_prior_max[i + n_otu], MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num])); /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */ K_part = EXP(K_part + log_g_i + scl_const); if(K_part > max_K_val) { For(i, n_otu - 1) max_combination[i] = cur_slices_cpy[i]; max_K_val = K_part; } /* printf("\n. [START] m_i * g_i [%f] \n", K_part); */ K_val_approx[numb_approx] = K_part; numb_approx++; K_total_cur = K_total_cur + K_part; /* printf("\n. [APPROX] Approximated constant after one run (K_part) = [%f] \n", (K_part)); */ /* printf("\n. K_max [%f] K_part [%f] \n", K_max, K_part); */ /* printf("\n. [CONT] sum(m_i * g_i) [%f] \n", K_total_cur); */ if(K_max < K_part) { K_max = K_part; /* For(i, n_otu - 1) slices_start_node[i] = cur_slices_cpy[i]; */ count++; } comb_numb++; if(comb_numb > max_size) { combinations = (int *)mRealloc(combinations, max_size*(n_otu - 1) + (n_otu - 1),sizeof(char)); max_size = max_size + 1; } c++; } } } } } if(Are_Equal(count, 0, 1.E-10)) break; } while(1); ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// For(m, n_otu - 1) { For(i, n_otu - 1) cur_slices_cpy[i] = max_combination[i]; For(i, n_otu - 1) { t_slice_min_f[i] = t_slice_min[cur_slices_cpy[i]]; t_slice_max_f[i] = t_slice_max[cur_slices_cpy[i]]; } For(n, 2 * n_otu - 3) { K_part = 0.0; if(g_i_node[m * (2 * n_otu - 3) + n] > 0) { t_slice_min_f[m] = t_slice_min[n]; t_slice_max_f[m] = t_slice_max[n]; cur_slices_cpy[m] = n; For(i, n_otu - 1) cur_slices[i] = cur_slices_cpy[i]; For(i, n_otu - 1) { for(j = i + 1; j < n_otu - 1; j++) { if(cur_slices[i] == cur_slices[j]) cur_slices[j] = -1; } } shr_num_slices = 0; For(i, n_otu -1) { if(cur_slices[i] >= 0) { cur_slices_shr[shr_num_slices] = cur_slices[i]; shr_num_slices++; } } result_1 = TRUE; Check_Time_Slices(tree -> n_root, tree -> n_root -> v[1], &result_1, t_slice_min_f, t_slice_max_f, tree); Check_Time_Slices(tree -> n_root, tree -> n_root -> v[2], &result_1, t_slice_min_f, t_slice_max_f, tree); if(result_1 != TRUE) K_part = 0.0; else { int n_1, n_2; x = 0; f = FALSE; num_elem = 0; if(comb_numb > 0) { For(i, comb_numb) { x = 0; For(j, n_otu - 1) { dif[j] = combinations[i*(n_otu-1) + j] - cur_slices_cpy[j]; /* dif[j] = combinations[i][j] - cur_slices_cpy[j]; */ if(dif[j] == 0) x++; /* printf(". [%d] ", dif[j]); */ } if(x == n_otu - 1) f = TRUE; } } if(!f) { For(i, n_otu - 1) combinations[comb_numb*(n_otu-1) + i] = cur_slices_cpy[i]; /* printf("\n"); */ /* printf(" [2][CUR SLICES PROPOSED] "); */ /* printf(" [COMB NUMBER] = [%d] --- ", comb_numb); */ /* For(i, n_otu - 1) printf(". [%d] .", combinations[comb_numb*(n_otu-1) + i]); */ /* printf("\n"); */ For(i, shr_num_slices) { Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[1], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); Search_Root_Node_In_Slice(tree -> n_root, tree -> n_root -> v[2], root_nodes, &num_elem, t_slice_min[cur_slices_shr[i]], t_slice_max[cur_slices_shr[i]], t_slice_min_f, t_slice_max_f, tree); } For(j, num_elem) { n_1 = 0; n_2 = 0; Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[1], &n_1, t_slice_min_f, t_slice_max_f, tree); Number_Of_Nodes_In_Slice(tree -> a_nodes[root_nodes[j] + n_otu], tree -> a_nodes[root_nodes[j] + n_otu] -> v[2], &n_2, t_slice_min_f, t_slice_max_f, tree); /* printf("\n. n_1 [%d] n_2 [%d]\n", n_1, n_2); */ K_part = K_part + LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1); /* printf("\n. [CONT] LOG(m_i) [%f] \n", LOG(1) - LOG(n_1 + n_2 + 1) - LnGamma(n_1 + 1) - LnGamma(n_2 + 1)); */ } /* printf("\n. [CONT] LOG(m_i) [%f] \n", K_part); */ /* printf("\n. K_part [%f] \n", K_part); */ log_g_i = 0.0; For(i, n_otu - 2) log_g_i += LOG_g_i(lmbd, t_slice_max_f[i], t_slice_min_f[i], t_prior_max[i + n_otu], MAX(t_prior_min[i + n_otu],tree->rates->nd_t[tree->n_root->num])); /* printf("\n. [START] LOG(g_i) [%f] \n", log_g_i); */ K_part = EXP(K_part + log_g_i + scl_const); if(K_part > max_K_val) { For(i, n_otu - 1) max_combination[i] = cur_slices_cpy[i]; max_K_val = K_part; } /* printf("\n. [START] m_i * g_i [%f] \n", K_part); */ K_val_approx[numb_approx] = K_part; numb_approx++; K_total_cur = K_total_cur + K_part; comb_numb++; if(comb_numb > max_size) { combinations = (int *)mRealloc(combinations, max_size*(n_otu - 1) + (n_otu - 1),sizeof(char)); max_size = max_size + 1; } c++; } } } } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// K_total = K_total + K_total_cur; /* printf("\n. [APPROX TOTAL] Approximated constant (K_total) = [%f] \n", (K_total)); */ /* printf("\n%G %d", K_total, c); */ if(Are_Equal(c, 0, 1.E-10)) numb_unsuc++; else numb_unsuc = 0; } while(numb_unsuc < 100); /* printf("\n"); */ /* printf("\n. [APPROX TOTAL] LOG(K_total) = [%f] \n", LOG(K_total)); */ /* printf("\n. [APPROX TOTAL] LOG(Constant) = scl_const - LOG(K_total) = [%f] \n", scl_const - LOG(K_total)); */ /* printf("\n. [APPROX TOTAL] Approximated constant 1 / (K_total) = [%f] \n", 1 / (K_total)); */ /* printf("\n ____________________________________________________________________________________________________ \n"); */ /* printf("\n. [APPROX TOTAL] Numb_approx = [%d] \n", numb_approx); */ /* printf("\n"); */ /* } */ ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// free(combinations); free(max_combination); free(dif); free(t_cur_slice_min); free(t_cur_slice_max); free(cur_slices); free(cur_slices_cpy); free(slices_start_node); free(cur_slices_shr); free(t_slice); free(t_slice_min); free(t_slice_max); free(t_slice_min_f); free(t_slice_max_f); free(indic); free(slice_numbers); free(root_nodes); free(n_slice); free(g_i_node); free(K_val_approx); return(-LOG(K_total)); } //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// int Number_Of_Comb_Slices(int m, int num_elem, int *n_slice) { int i, num_comb; i = 0; num_comb = 1; for(i = m; i < num_elem; i++) num_comb = num_comb * n_slice[i]; return(num_comb); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Check the combination of the time slices to be set correctly. void Check_Time_Slices(t_node *a, t_node *d, int *result, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree) { int n_otu; n_otu = tree -> n_otu; d -> anc = a; if(d -> tax) return; else { if(t_cur_slice_max[d -> num - n_otu] < t_cur_slice_max[a -> num - n_otu]) { *result = FALSE; } int i; For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Check_Time_Slices(d, d -> v[i], result, t_cur_slice_min, t_cur_slice_max, tree); } } ////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// //Getting the number of nodes on both sides from the node d_start, that are in the slice of that node. void Number_Of_Nodes_In_Slice(t_node *d_start, t_node *d, int *n, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree) { int n_otu; n_otu = tree -> n_otu; if(d -> tax) return; else { if(Are_Equal(t_cur_slice_max[d_start -> num - n_otu], t_cur_slice_max[d -> num - n_otu], 1.E-10) && Are_Equal(t_cur_slice_min[d_start -> num - n_otu], t_cur_slice_min[d -> num - n_otu], 1.E-10)) { (*n)++; int i; For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Number_Of_Nodes_In_Slice(d_start, d -> v[i], n, t_cur_slice_min, t_cur_slice_max, tree); } } } ////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// //Returnig the root node in the given slice. void Search_Root_Node_In_Slice(t_node *d_start, t_node *d, int *root_nodes, int *num_elem, phydbl t_slice_min, phydbl t_slice_max, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree) { int j, n_otu, f; j = 0; f = FALSE; n_otu = tree -> n_otu; if(Are_Equal(t_cur_slice_max[d_start -> num - n_otu], t_slice_max, 1.E-10) && Are_Equal(t_cur_slice_min[d_start -> num - n_otu], t_slice_min, 1.E-10)) { For(j, *num_elem) if(d_start -> num - n_otu == (root_nodes[j])) f = TRUE; if(f != TRUE) { (root_nodes[(*num_elem)]) = d_start -> num - n_otu; (*num_elem)++; return; } } else { d -> anc = d_start; if(d -> tax) return; else { if(Are_Equal(t_cur_slice_max[d -> num - n_otu], t_slice_max, 1.E-10) && Are_Equal(t_cur_slice_min[d -> num - n_otu], t_slice_min, 1.E-10)) { (root_nodes[*num_elem]) = d -> num - n_otu; (*num_elem)++; return; } int i; For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Search_Root_Node_In_Slice(d, d -> v[i], root_nodes, num_elem, t_slice_min, t_slice_max, t_cur_slice_min, t_cur_slice_max, tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Factorial(int base) { if(base == 0) return(1); if(base == 1) return(1); return(base * Factorial(base-1)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Calculate the vector of the norm.constants for prior on node times. //The length of the vector is the total number of combinations of calibrations. phydbl *Norm_Constant_Prior_Times(t_tree *tree) { phydbl *log_K_val; int i, tot_num_comb; t_cal *calib; calib = tree -> rates -> calib; tot_num_comb = Number_Of_Comb(calib); log_K_val = (phydbl *)mCalloc(tot_num_comb, sizeof(phydbl)); For(i, tot_num_comb) { Set_Current_Calibration(i, tree); int result = TRUE; TIMES_Set_All_Node_Priors_S(&result, tree); if(result == TRUE) log_K_val[i] = K_Constant_Prior_Times_Log(tree); while(calib -> prev) calib = calib -> prev; } return(log_K_val); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Sets a vector of the partial probabilities for each combination of calibrations void TIMES_Calib_Partial_Proba(t_tree *tree) { phydbl *times_partial_proba, proba, *t_prior_min, *t_prior_max; int i, j, k, tot_num_comb; t_cal *calib; short int *t_has_prior; proba = 0.0; times_partial_proba = tree -> rates -> times_partial_proba; calib = tree -> rates -> calib; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; t_has_prior = tree -> rates -> t_has_prior; tot_num_comb = Number_Of_Comb(calib); For(i, tot_num_comb) { times_partial_proba[i] = 1.0; for(j = tree -> n_otu; j < 2 * tree -> n_otu - 1; j++) { t_prior_min[j] = -BIG; t_prior_max[j] = BIG; t_has_prior[j] = NO; } do { k = (i % Number_Of_Comb(calib)) / Number_Of_Comb(calib -> next); if(calib -> all_applies_to[k] -> num) { t_prior_min[calib -> all_applies_to[k] -> num] = MAX(t_prior_min[calib -> all_applies_to[k] -> num], calib -> lower); t_prior_max[calib -> all_applies_to[k] -> num] = MIN(t_prior_max[calib -> all_applies_to[k] -> num], calib -> upper); t_has_prior[calib -> all_applies_to[k] -> num] = YES; proba = calib -> proba[calib -> all_applies_to[k] -> num]; times_partial_proba[i] *= proba; } else { proba = calib -> proba[2 * tree -> n_otu - 1]; times_partial_proba[i] *= proba; } if(calib -> next) calib = calib -> next; else break; } while(calib); int result; result = TRUE; TIMES_Set_All_Node_Priors_S(&result, tree); if(result != TRUE) times_partial_proba[i] = 0; /* printf("\n. [4] Partial Proba [%f] \n", times_partial_proba[i]); */ while(calib -> prev) calib = calib -> prev; } phydbl sum_proba; sum_proba = 0.0; For(i, tot_num_comb) sum_proba += times_partial_proba[i]; if(!Are_Equal(sum_proba, 1.0, 1.E-10)) { For(i, tot_num_comb) times_partial_proba[i] = times_partial_proba[i] / sum_proba; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Function checks if the randomized node times are within the //upper and lower time limits, taken into account the times of //the ancestor and descendent. void Check_Node_Time(t_node *a, t_node *d, int *result, t_tree *tree) { phydbl t_low, t_up; phydbl *t_prior_min, *t_prior_max, *nd_t; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; if((a == tree -> n_root) && ((nd_t[a -> num] > MIN(t_prior_max[a -> num], MIN(nd_t[a -> v[1] -> num], nd_t[a -> v[2] -> num]))) || (nd_t[a -> num] < t_prior_min[a -> num]))) { *result = FALSE; return; } if(d -> tax) return; else { t_low = MAX(t_prior_min[d -> num], nd_t[d -> anc -> num]); t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); /* printf("\n. CHECK: %d t:%f u:%f d:%f",d->num,nd_t[d->num],t_up,t_low); */ if(nd_t[d -> num] < t_low || nd_t[d -> num] > t_up) { *result = FALSE; return; } int i; For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Check_Node_Time(d, d -> v[i], result, tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Function calculates the TOTAL number of calibration combinations, //given the number of nodes to which each calibartion applies to. int Number_Of_Comb(t_cal *calib) { int num_comb; if(!calib) return(1); num_comb = 1; do { num_comb *= calib -> n_all_applies_to; if(calib -> next) calib = calib -> next; else break; } while(calib); return(num_comb); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Function calculates the TOTAL number of calibration combinations, //given the number of nodes to which each calibartion applies to. int Number_Of_Calib(t_cal *calib) { int num_calib; num_calib = 0; do { num_calib++; if(calib -> next) calib = calib -> next; else break; } while(calib); return(num_calib); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Function sets current calibration in the following way: // Suppose we have a vector of calibrations C=(C1, C2, C3), each calibration // applies to a set of nodes. We can reach each node number through the indexes (corresponds // to the number the information was read). C1={0,1,2}, C2={0,1}, C3={0}; // The total number of combinations is 3*2*1=6. The first combination with row number 0 // will be {0,0,0}, the second row will be {0,1,0} and so on. Calling the node numbers with // the above indexes will return current calibration. Also sets the vector of probabilities // for current calibration combination. void Set_Current_Calibration(int row, t_tree *tree) { t_cal *calib; phydbl *t_prior_min, *t_prior_max; short int *t_has_prior; int k, i, j, *curr_nd_for_cal; calib = tree -> rates -> calib; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; t_has_prior = tree -> rates -> t_has_prior; curr_nd_for_cal = tree -> rates -> curr_nd_for_cal; /* printf("\n COMBINATION NUMBER [%d] \n", row); */ for(j = tree -> n_otu; j < 2 * tree -> n_otu - 1; j++) { t_prior_min[j] = -BIG; t_prior_max[j] = BIG; t_has_prior[j] = NO; } k = -1; i = 0; do { k = (row % Number_Of_Comb(calib)) / Number_Of_Comb(calib -> next); if(calib -> all_applies_to[k] -> num) { /* printf("\n"); */ /* printf(" %f %f %f %f ", calib -> lower, calib -> upper, t_prior_min[calib -> all_applies_to[k] -> num], t_prior_max[calib -> all_applies_to[k] -> num]); */ /* printf("\n"); */ /* printf("\n"); */ /* printf(" Node number [%d] ", calib -> all_applies_to[k] -> num); */ /* printf("\n"); */ t_prior_min[calib -> all_applies_to[k] -> num] = MAX(t_prior_min[calib -> all_applies_to[k] -> num], calib -> lower); /* printf("\n Prior min [%f] \n", t_prior_min[calib -> all_applies_to[k] -> num]); */ t_prior_max[calib -> all_applies_to[k] -> num] = MIN(t_prior_max[calib -> all_applies_to[k] -> num], calib -> upper); /* printf("\n Prior max [%f] \n", t_prior_max[calib -> all_applies_to[k] -> num]); */ t_has_prior[calib -> all_applies_to[k] -> num] = YES; curr_nd_for_cal[i] = calib -> all_applies_to[k] -> num; i++; } if(calib->next) calib = calib->next; else break; } while(calib); while(calib -> prev) calib = calib -> prev; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Randomly choose a combination of calibrations drawing an index of calibration combination, //used function Set_Cur_Calibration. void Random_Calibration(t_tree *tree) { int rnd, num_comb; t_cal *calib; calib = tree -> rates -> calib; num_comb = Number_Of_Comb(calib); srand(time(NULL)); rnd = rand()%(num_comb); Set_Current_Calibration(rnd, tree); TIMES_Set_All_Node_Priors(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Variable curr_nd_for_cal is a vector of node numbers, the length of that vector is a number of calibrations. //Function randomly updates that vector by randomly changing one node and setting times limits with respect //to a new vector. int RND_Calibration_And_Node_Number(t_tree *tree) { int i, j, tot_num_cal, cal_num, node_ind, node_num, *curr_nd_for_cal; phydbl *t_prior_min, *t_prior_max; //*times_partial_proba; short int *t_has_prior; t_cal *cal; tot_num_cal = tree -> rates -> tot_num_cal; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; t_has_prior = tree -> rates -> t_has_prior; curr_nd_for_cal = tree -> rates -> curr_nd_for_cal; cal = tree -> rates -> calib; cal_num = rand()%(tot_num_cal - 1); i = 0; while (i != cal_num) { cal = cal -> next; i++; } node_ind = rand()%(cal -> n_all_applies_to); node_num = cal -> all_applies_to[node_ind] -> num; curr_nd_for_cal[cal_num] = node_num; for(j = tree -> n_otu; j < 2 * tree -> n_otu - 1; j++) { t_prior_min[j] = -BIG; t_prior_max[j] = BIG; t_has_prior[j] = NO; } while(cal -> prev) cal = cal -> prev; i = 0; do { t_prior_min[curr_nd_for_cal[i]] = cal -> lower; t_prior_max[curr_nd_for_cal[i]] = cal -> upper; t_has_prior[curr_nd_for_cal[i]] = YES; i++; if(cal->next) cal = cal -> next; else break; } while(cal); while(cal -> prev) cal = cal -> prev; TIMES_Set_All_Node_Priors(tree); return(node_num); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Return the value uniformly distributed between two values. phydbl Randomize_One_Node_Time(phydbl min, phydbl max) { phydbl u; u = Uni(); u *= (max - min); u += min; return(u); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Calculates the Hastings ratio for the analysis. Used in case of //calibration conditional jump. NOT THE RIGHT ONE TO USE! void Lk_Hastings_Ratio_Times(t_node *a, t_node *d, phydbl *tot_prob, t_tree *tree) { phydbl t_low, t_up; phydbl *t_prior_min, *t_prior_max, *nd_t; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; if(d -> tax) return; else { t_low = MAX(t_prior_min[d -> num], nd_t[d -> anc -> num]); t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); (*tot_prob) += LOG(1) - LOG(t_up - t_low); int i; For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) { Lk_Hastings_Ratio_Times(d, d -> v[i], tot_prob, tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Updates nodes which are below a randomized node in case if new proposed time //for that node is below the current value. void Update_Descendent_Cond_Jump(t_node *a, t_node *d, phydbl *L_Hast_ratio, t_tree *tree) { int result = TRUE; phydbl t_low, t_up; phydbl *t_prior_min, *t_prior_max, *nd_t; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; Check_Node_Time(tree -> n_root, tree -> n_root -> v[1], &result, tree); Check_Node_Time(tree -> n_root, tree -> n_root -> v[2], &result, tree); if(d -> tax) return; else { if(result != TRUE) { int i; t_low = MAX(nd_t[a -> num], t_prior_min[d -> num]); if(t_low < MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])) t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); else t_up = t_prior_max[d -> num]; nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up); (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low); For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Update_Descendent_Cond_Jump(d, d -> v[i], L_Hast_ratio, tree); } else return; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //Updates nodes which are above a randomized node in case if new proposed time //for that node is above the current value. void Update_Ancestor_Cond_Jump(t_node *d, phydbl *L_Hast_ratio, t_tree *tree) { int result = TRUE; phydbl t_low, t_up; phydbl *t_prior_min, *t_prior_max, *nd_t; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; Check_Node_Time(tree -> n_root, tree -> n_root -> v[1], &result, tree); Check_Node_Time(tree -> n_root, tree -> n_root -> v[2], &result, tree); if(result != TRUE) { if(d == tree -> n_root) { t_low = t_prior_min[d -> num]; t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up); (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low); return; } else { t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); if(nd_t[d -> anc -> num] > t_up) t_low = t_prior_min[d -> num]; else t_low = MAX(t_prior_min[d -> num], nd_t[d -> anc -> num]); nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up); (*L_Hast_ratio) += LOG(1) - LOG(t_up - t_low); Update_Ancestor_Cond_Jump(d -> anc, L_Hast_ratio, tree); } } else return; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //when made a calibration conditional jump, updates node times //with respect to the new calibration which was made with respect //to the randomly chosen node, the root is fixed. Updates only those nodes //that are not within new intervals. Traverse up and down. void Update_Times_RND_Node_Ancestor_Descendant(int rnd_node, phydbl *L_Hast_ratio, t_tree *tree) { int i; phydbl *t_prior_min, *t_prior_max, *nd_t; phydbl new_time_rnd_node = 0.0; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; new_time_rnd_node = Randomize_One_Node_Time(t_prior_min[rnd_node], t_prior_max[rnd_node]); nd_t[rnd_node] = new_time_rnd_node; Update_Ancestor_Cond_Jump(tree -> a_nodes[rnd_node] -> anc, L_Hast_ratio, tree); For(i,3) if((tree -> a_nodes[rnd_node] -> v[i] != tree -> a_nodes[rnd_node] -> anc) && (tree -> a_nodes[rnd_node] -> b[i] != tree -> e_root)) Update_Descendent_Cond_Jump(tree -> a_nodes[rnd_node], tree -> a_nodes[rnd_node] -> v[i], L_Hast_ratio, tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// //when made a calibration conditional jump, updates node times //with respect to the new calibration which was made with respect //to the randomly chosen node, starting from the root down to the tips. //Updates only those nodes that are not within new intervals. void Update_Times_Down_Tree(t_node *a, t_node *d, phydbl *L_Hastings_ratio, t_tree *tree) { int i; phydbl *t_prior_min, *t_prior_max, *nd_t, t_low, t_up; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; t_low = MAX(t_prior_min[d -> num], nd_t[a -> num]); t_up = t_prior_max[d -> num]; //printf("\n. [1] Node number: [%d] \n", d -> num); if(d -> tax) return; else { if(nd_t[d -> num] > t_up || nd_t[d -> num] < t_low) { //printf("\n. [2] Node number: [%d] \n", d -> num); //(*L_Hastings_ratio) += (LOG(1) - LOG(t_up - t_low)); (*L_Hastings_ratio) += (- LOG(t_up - t_low)); nd_t[d -> num] = Randomize_One_Node_Time(t_low, t_up); /* t_prior_min[d -> num] = t_low; */ /* t_prior_max[d -> num] = t_up; */ } For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Update_Times_Down_Tree(d, d -> v[i], L_Hastings_ratio, tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Search_Node_Attribute_Value_Clade(char *attr_name, char *value, int skip, xml_node *node) { xml_node *match; //printf("\n. Node name [%s] Attr name [%s] Attr value [%s] \n", node -> name, attr_name, value); if(!node) { PhyML_Printf("\n== node: %p attr: %p",node,node?node->attr:NULL); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } match = NULL; if(skip == NO && node -> attr) { xml_attr *attr; attr = node -> attr; do { if(!strcmp(attr -> name, attr_name) && !strcmp(attr -> value, value)) { match = node; break; } attr = attr->next; if(!attr) break; } while(1); } if(match) return(match); if(node -> next && !match) { match = XML_Search_Node_Attribute_Value_Clade(attr_name, value, NO, node -> next); return match; } return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char **XML_Reading_Clade(xml_node *n_clade, t_tree *tree) { int i, /* j, */ n_otu; char **clade; i = 0; n_otu = tree -> n_otu; clade = (char **)mCalloc(n_otu, sizeof(char *)); /* For(j, n_otu) */ /* { */ /* clade[j] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */ /* } */ if(n_clade) { do { clade[i] = n_clade -> attr -> value; i++; if(n_clade -> next) n_clade = n_clade -> next; else break; } while(n_clade); } else { PhyML_Printf("== Clade is empty. \n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return(clade); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade) { int clade_size = 0; if(n_clade) { do { clade_size++; if(n_clade -> next) n_clade = n_clade -> next; else break; } while(n_clade); } else { PhyML_Printf("==Clade is empty. \n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return(clade_size); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors_S(int *result, t_tree *tree) { int i; phydbl min_prior; /* Set all t_prior_max values */ TIMES_Set_All_Node_Priors_Bottom_Up_S(tree->n_root,tree->n_root->v[2], result, tree); TIMES_Set_All_Node_Priors_Bottom_Up_S(tree->n_root,tree->n_root->v[1], result, tree); tree->rates->t_prior_max[tree->n_root->num] = MIN(tree->rates->t_prior_max[tree->n_root->num], MIN(tree->rates->t_prior_max[tree->n_root->v[2]->num], tree->rates->t_prior_max[tree->n_root->v[1]->num])); /* Set all t_prior_min values */ if(!tree->rates->t_has_prior[tree->n_root->num]) { min_prior = 1.E+10; For(i,2*tree->n_otu-2) { if(tree->rates->t_has_prior[i]) { if(tree->rates->t_prior_min[i] < min_prior) min_prior = tree->rates->t_prior_min[i]; } } tree->rates->t_prior_min[tree->n_root->num] = 2.0 * min_prior; } if(tree->rates->t_prior_min[tree->n_root->num] > 0.0) { *result = FALSE; } TIMES_Set_All_Node_Priors_Top_Down_S(tree->n_root,tree->n_root->v[2], result, tree); TIMES_Set_All_Node_Priors_Top_Down_S(tree->n_root,tree->n_root->v[1], result, tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors_Bottom_Up_S(t_node *a, t_node *d, int *result, t_tree *tree) { int i; phydbl t_sup; if(d->tax) return; else { t_node *v1, *v2; /* the two sons of d */ For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { TIMES_Set_All_Node_Priors_Bottom_Up_S(d,d->v[i], result, tree); } } v1 = v2 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } if(tree->rates->t_has_prior[d->num] == YES) { t_sup = MIN(tree->rates->t_prior_max[d->num], MIN(tree->rates->t_prior_max[v1->num], tree->rates->t_prior_max[v2->num])); tree->rates->t_prior_max[d->num] = t_sup; if(tree->rates->t_prior_max[d->num] < tree->rates->t_prior_min[d->num]) { *result = FALSE; } } else { tree->rates->t_prior_max[d->num] = MIN(tree->rates->t_prior_max[v1->num], tree->rates->t_prior_max[v2->num]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors_Top_Down_S(t_node *a, t_node *d, int *result, t_tree *tree) { if(d->tax) return; else { int i; if(tree->rates->t_has_prior[d->num] == YES) { tree->rates->t_prior_min[d->num] = MAX(tree->rates->t_prior_min[d->num],tree->rates->t_prior_min[a->num]); if(tree->rates->t_prior_max[d->num] < tree->rates->t_prior_min[d->num]) { *result = FALSE; } } else { tree->rates->t_prior_min[d->num] = tree->rates->t_prior_min[a->num]; } For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { TIMES_Set_All_Node_Priors_Top_Down_S(d,d->v[i], result, tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl LOG_g_i(phydbl lmbd, phydbl t_slice_max, phydbl t_slice_min, phydbl t_prior_max, phydbl t_prior_min) { phydbl result = 0.0; if(lmbd * t_prior_min < -10.0) { phydbl K; K = -10.0 - lmbd * t_prior_min; /* printf("\n. K = [%f] \n", K); */ if(lmbd * t_prior_max + K > 700.0) { PhyML_Printf("\n. Please scale your calibration intervals. \n"); PhyML_Printf("\n. Cannot calculate EXP(-lmbd * t_prior_max). \n"); PhyML_Printf("\n. Err. in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } else { result = LOG(EXP(lmbd * t_slice_max + K) - EXP(lmbd * t_slice_min + K)) - LOG(EXP(lmbd * t_prior_max + K) - EXP(lmbd * t_prior_min + K)); } } else { result = LOG(EXP(lmbd * t_slice_max) - EXP(lmbd * t_slice_min)) - LOG(EXP(lmbd * t_prior_max) - EXP(lmbd * t_prior_min)); } return(result); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int CombineInt(int int1, int int2) { int mem; mem = 500 * 2; char cResult[mem]; sprintf(cResult, "%d%d", int1, int2); return atoi(cResult); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Jump_Calibration_Move_Pre(t_node *a, t_node *d, phydbl old_ta, phydbl *log_hastings_ratio, t_tree *tree) { int i; phydbl *t_prior_min_new, *t_prior_max_new, t_low_new, t_up_new; phydbl *t_prior_min_old, *t_prior_max_old, t_low_old, t_up_old; phydbl *nd_t, old_t; phydbl eps = DBL_MIN; int move_anyway; t_prior_min_new = tree -> rates -> t_prior_min; t_prior_max_new = tree -> rates -> t_prior_max; t_prior_min_old = tree -> rates -> t_prior_min_ori; t_prior_max_old = tree -> rates -> t_prior_max_ori; nd_t = tree -> rates -> nd_t; t_low_new = MAX(t_prior_min_new[d -> num], nd_t[a -> num]); t_up_new = t_prior_max_new[d -> num]; t_low_old = MAX(t_prior_min_old[d -> num], old_ta); t_up_old = t_prior_max_old[d -> num]; old_t = nd_t[d -> num]; /* move_anyway = NO; */ /* if(Uni() < .5) move_anyway = YES; */ move_anyway = YES; if(d -> tax) return; else { if((nd_t[d -> num] > t_up_new || nd_t[d -> num] < t_low_new) || (move_anyway == YES)) /* Hastings ratio */ { (*log_hastings_ratio) += LOG(t_up_new - t_low_new + eps); } if((nd_t[d -> num] > t_up_new || nd_t[d -> num] < t_low_new) || (move_anyway == YES)) /* Do the jump */ { nd_t[d -> num] = Uni()*(t_up_new - t_low_new) + t_low_new; } if((nd_t[d -> num] > t_up_old || nd_t[d -> num] < t_low_old) || (move_anyway == YES)) /* Hastings ratio */ { (*log_hastings_ratio) -= LOG(t_up_old - t_low_old + eps); } For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Jump_Calibration_Move_Pre(d, d -> v[i], old_t, log_hastings_ratio, tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Multiple_Time_Proposal_Density(t_node *a, t_node *d, phydbl *time_proposal_density, t_tree *tree) { int i; phydbl *t_prior_min, *t_prior_max, *nd_t, t_low, t_up; t_prior_min = tree -> rates -> t_prior_min; t_prior_max = tree -> rates -> t_prior_max; nd_t = tree -> rates -> nd_t; //printf("\n. [1] Node number: [%d] \n", d -> num); if(d -> tax) return; else { t_low = MAX(t_prior_min[d -> num], nd_t[a -> num]); t_up = t_prior_max[d -> num]; /* t_up = MIN(t_prior_max[d -> num], MIN(nd_t[d -> v[1] -> num], nd_t[d -> v[2] -> num])); */ /* printf("\n. Low [%f] Up [%f] \n", t_low, t_up); */ (*time_proposal_density) += (- LOG(t_up - t_low)); For(i,3) if((d -> v[i] != d -> anc) && (d -> b[i] != tree -> e_root)) Multiple_Time_Proposal_Density(d, d -> v[i], time_proposal_density, tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/invitee.h000066400000000000000000000050271263450375500152660ustar00rootroot00000000000000#ifndef INVITEE_H #define INVITEE_H #include "utilities.h" int My_Function(int argc, char **argv); int My_main(int argc, char **argv); void PhyTime_XML(char *xml_file); phydbl TIMES_Calib_Cond_Prob(t_tree *tree); int Number_Of_Comb(t_cal *calib); int Number_Of_Calib(t_cal *calib); void Check_Node_Time(t_node *a, t_node *d, int *result, t_tree *tree); void Set_Current_Calibration(int row, t_tree *tree); void Random_Calibration(t_tree *tree); int RND_Calibration_And_Node_Number(t_tree *tree); phydbl Randomize_One_Node_Time(phydbl min, phydbl max); void Lk_Hastings_Ratio_Times(t_node *a, t_node *d, phydbl *tot_prob, t_tree *tree); void Update_Descendent_Cond_Jump(t_node *a, t_node *d, phydbl *L_Hast_ratio, t_tree *tree); void Update_Ancestor_Cond_Jump(t_node *d, phydbl *L_Hast_ratio, t_tree *tree); void Update_Times_RND_Node_Ancestor_Descendant(int rnd_node, phydbl *L_Hast_ratio, t_tree *tree); void Update_Times_Down_Tree(t_node *a, t_node *d, phydbl *L_Hastings_ratio, t_tree *tree); phydbl K_Constant_Prior_Times_Log(t_tree *tree); int Number_Of_Comb_Slices(int m, int num_elem, int *n_slice); void Check_Time_Slices(t_node *a, t_node *d, int *result, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree); void Number_Of_Nodes_In_Slice(t_node *d_start, t_node *d, int *n, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree); void Search_Root_Node_In_Slice(t_node *d_start, t_node *d, int *root_nodes, int *num_elem, phydbl t_slice_min, phydbl t_slice_max, phydbl *t_cur_slice_min, phydbl *t_cur_slice_max, t_tree *tree); int Factorial(int base); phydbl *Norm_Constant_Prior_Times(t_tree *tree); void TIMES_Calib_Partial_Proba(t_tree *tree); xml_node *XML_Search_Node_Attribute_Value_Clade(char *attr_name, char *value, int skip, xml_node *node); char **XML_Reading_Clade(xml_node *n_clade, t_tree *tree); int XML_Number_Of_Taxa_In_Clade(xml_node *n_clade); void TIMES_Set_All_Node_Priors_S(int *result, t_tree *tree); void TIMES_Set_All_Node_Priors_Bottom_Up_S(t_node *a, t_node *d, int *result, t_tree *tree); void TIMES_Set_All_Node_Priors_Top_Down_S(t_node *a, t_node *d, int *result, t_tree *tree); phydbl LOG_g_i(phydbl lmbd, phydbl t_slice_max, phydbl t_slice_min, phydbl t_prior_max, phydbl t_prior_min); int CombineInt(int int1, int int2); void Update_Current_Times_Down_Tree(t_node *a, t_node *d, t_tree *tree); void Multiple_Time_Proposal_Density(t_node *a, t_node *d, phydbl *time_proposal_density, t_tree *tree); void Jump_Calibration_Move_Pre(t_node *a, t_node *d, phydbl old_ta, phydbl *log_hastings_ratio, t_tree *tree); #endif phyml-3.2.0/src/io.c000066400000000000000000006131661263450375500142360ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "io.h" #include "assert.h" #ifdef BEAGLE #include "libhmsbeagle/beagle.h" #endif /* Tree parser function. We need to pass a pointer to the string of characters since this string might be freed and then re-allocated by that function (i.e., its address in memory might change) */ t_tree *Read_Tree(char **s_tree) { char **subs; int i,n_ext,n_int,n_otu; t_tree *tree; int degree,len; t_node *root_node; n_int = n_ext = 0; n_otu=0; For(i,(int)strlen((*s_tree))) if((*s_tree)[i] == ',') n_otu++; n_otu+=1; tree = Make_Tree_From_Scratch(n_otu,NULL); subs = Sub_Trees((*s_tree),°ree); Clean_Multifurcation(subs,degree,3); if(degree == 2) { /* Unroot_Tree(subs); */ /* degree = 3; */ /* root_node = tree->a_nodes[n_otu]; */ root_node = tree->a_nodes[2*n_otu-2]; root_node->num = 2*n_otu-2; tree->n_root = root_node; n_int -= 1; } else { root_node = tree->a_nodes[n_otu]; root_node->num = n_otu; tree->n_root = NULL; } if(degree > 3) /* Multifurcation at the root. Need to re-assemble the subtrees since Clean_Multifurcation added sets of parenthesis and the corresponding NULL edges */ { degree = 3; Free((*s_tree)); len = 0; For(i,degree) len += (strlen(subs[i])+1); len += 5; (*s_tree) = (char *)mCalloc(len,sizeof(char)); (*s_tree)[0] = '('; (*s_tree)[1] = '\0'; For(i,degree) { strcat((*s_tree),subs[i]); strcat((*s_tree),",\0"); } sprintf((*s_tree)+strlen((*s_tree))-1,"%s",");\0"); For(i,NODE_DEG_MAX) Free(subs[i]); Free(subs); subs = Sub_Trees((*s_tree),°ree); } root_node->tax = 0; tree->has_branch_lengths = 0; tree->num_curr_branch_available = 0; For(i,degree) R_rtree((*s_tree),subs[i],root_node,tree,&n_int,&n_ext); for(i=degree;in_root) { tree->e_root = tree->a_edges[tree->num_curr_branch_available]; tree->n_root->v[2] = tree->n_root->v[0]; tree->n_root->v[0] = NULL; tree->n_root->l[2] = tree->n_root->l[0]; For(i,3) if(tree->n_root->v[2]->v[i] == tree->n_root) { tree->n_root->v[2]->v[i] = tree->n_root->v[1]; break; } For(i,3) if(tree->n_root->v[1]->v[i] == tree->n_root) { tree->n_root->v[1]->v[i] = tree->n_root->v[2]; break; } Connect_One_Edge_To_Two_Nodes(tree->n_root->v[2], tree->n_root->v[1], tree->e_root, tree); tree->e_root->l->v = tree->n_root->l[2] + tree->n_root->l[1]; if(tree->e_root->l->v > 0.0) tree->n_root_pos = tree->n_root->l[2] / tree->e_root->l->v; else tree->n_root_pos = .5; } return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* 'a' in t_node a stands for ancestor. 'd' stands for descendant */ void R_rtree(char *s_tree_a, char *s_tree_d, t_node *a, t_tree *tree, int *n_int, int *n_ext) { int i; t_node *d; int n_otu = tree->n_otu; if(strstr(s_tree_a," ")) { PhyML_Printf("\n== [%s]",s_tree_a); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } if(s_tree_d[0] == '(') { char **subs; int degree; t_edge *b; (*n_int)+=1; if((*n_int + n_otu) == (2*n_otu-1)) { PhyML_Printf("\n== The number of internal nodes in the tree exceeds the number of taxa minus one."); PhyML_Printf("\n== There probably is a formating problem in the input tree."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } d = tree->a_nodes[n_otu+*n_int]; d->num = n_otu + *n_int; d->tax = 0; b = tree->a_edges[tree->num_curr_branch_available]; Read_Branch_Label(s_tree_d,s_tree_a,tree->a_edges[tree->num_curr_branch_available]); Read_Branch_Length(s_tree_d,s_tree_a,tree); For(i,3) { if(!a->v[i]) { a->v[i]=d; d->l[0]=tree->a_edges[tree->num_curr_branch_available]->l->v; a->l[i]=tree->a_edges[tree->num_curr_branch_available]->l->v; break; } } d->v[0]=a; if(a != tree->n_root) { Connect_One_Edge_To_Two_Nodes(a,d,tree->a_edges[tree->num_curr_branch_available],tree); } subs=Sub_Trees(s_tree_d,°ree); if(degree > 2) { Clean_Multifurcation(subs,degree,2); Free(s_tree_d); s_tree_d = (char *)mCalloc(strlen(subs[0])+strlen(subs[1])+5,sizeof(char)); strcat(s_tree_d,"("); strcat(s_tree_d,subs[0]); strcat(s_tree_d,","); strcat(s_tree_d,subs[1]); strcat(s_tree_d,")"); For(i,b->n_labels) { strcat(s_tree_d,"#"); strcat(s_tree_d,b->labels[i]); } For(i,NODE_DEG_MAX) Free(subs[i]); Free(subs); subs=Sub_Trees(s_tree_d,°ree); } R_rtree(s_tree_d,subs[0],d,tree,n_int,n_ext); R_rtree(s_tree_d,subs[1],d,tree,n_int,n_ext); for(i=2;ia_nodes[*n_ext]; d->tax = 1; Read_Node_Name(d,s_tree_d,tree); Read_Branch_Label(s_tree_d,s_tree_a,tree->a_edges[tree->num_curr_branch_available]); Read_Branch_Length(s_tree_d,s_tree_a,tree); For(i,3) { if(!a->v[i]) { a->v[i]=d; d->l[0]=tree->a_edges[tree->num_curr_branch_available]->l->v; a->l[i]=tree->a_edges[tree->num_curr_branch_available]->l->v; break; } } d->v[0]=a; if(a != tree->n_root) { Connect_One_Edge_To_Two_Nodes(a,d,tree->a_edges[tree->num_curr_branch_available],tree); } d->num=*n_ext; (*n_ext)+=1; } Free(s_tree_d); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Branch_Label(char *s_d, char *s_a, t_edge *b) { char *sub_tp; char *p; int posp,posl; sub_tp = (char *)mCalloc(3+(int)strlen(s_d)+1,sizeof(char)); /* sub_tp = (char *)mCalloc(T_MAX_LINE,sizeof(char)); */ sub_tp[0] = '('; sub_tp[1] = '\0'; strcat(sub_tp,s_d); strcat(sub_tp,"#"); p = strstr(s_a,sub_tp); if(!p) { sub_tp[0] = ','; sub_tp[1] = '\0'; strcat(sub_tp,s_d); strcat(sub_tp,"#"); p = strstr(s_a,sub_tp); } b->n_labels = 0; if(p) { if(!(b->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(b); b->n_labels++; posp = strlen(s_d); while(p[posp] != '#') posp++; posp++; posl = 0; do { b->labels[b->n_labels-1][posl] = p[posp]; posl++; posp++; if(p[posp] == '#') { b->labels[b->n_labels-1][posl] = '\0'; b->n_labels++; if(!(b->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(b); posp++; posl=0; } } while((p[posp] != ':') && (p[posp] != ',') && (p[posp] != '(')); b->labels[b->n_labels-1][posl] = '\0'; } if(p) { /* if(b->n_labels == 1) */ /* PhyML_Printf("\n. Read label '%s' on t_edge %3d.",b->labels[0],b->num); */ /* else */ /* { */ /* PhyML_Printf("\n. Read labels "); */ /* For(i,b->n_labels) PhyML_Printf("'%s' ",b->labels[i]); */ /* PhyML_Printf("on t_edge %3d.",b->num); */ /* } */ if(!strcmp(b->labels[0],"NULL")) { b->does_exist = NO; } } /* else */ /* { */ /* PhyML_Printf("\n. No label found on %s",s_d); */ /* } */ Free(sub_tp); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Branch_Length(char *s_d, char *s_a, t_tree *tree) { char *sub_tp; char *p; t_edge *b; int i; b = tree->a_edges[tree->num_curr_branch_available]; /* sub_tp = (char *)mCalloc(T_MAX_LINE,sizeof(char)); */ sub_tp = (char *)mCalloc(10+strlen(s_d)+1,sizeof(char)); For(i,b->n_labels) { strcat(s_d,"#"); strcat(s_d,b->labels[i]); } sub_tp[0] = '('; sub_tp[1] = '\0'; strcat(sub_tp,s_d); strcat(sub_tp,":"); p = strstr(s_a,sub_tp); if(!p) { sub_tp[0] = ','; sub_tp[1] = '\0'; strcat(sub_tp,s_d); strcat(sub_tp,":"); p = strstr(s_a,sub_tp); } if(p) { b->l->v = atof((char *)p+(int)strlen(sub_tp)); tree->has_branch_lengths = YES; b->does_exist = YES; } else { b->l->v = -1.; } Free(sub_tp); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Node_Name(t_node *d, char *s_tree_d, t_tree *tree) { int i; if(!tree->a_edges[tree->num_curr_branch_available]->n_labels) { d->name = (char *)mCalloc(strlen(s_tree_d)+1,sizeof(char )); strcpy(d->name,s_tree_d); } else { i = 0; do { d->name = (char *)realloc(d->name,(i+1)*sizeof(char )); d->name[i] = s_tree_d[i]; i++; } while(s_tree_d[i] != '#'); d->name[i] = '\0'; } d->ori_name = d->name; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Clean_Multifurcation(char **subtrees, int current_deg, int end_deg) { if(current_deg <= end_deg) return; else { char *s_tmp; int i; /* s_tmp = (char *)mCalloc(T_MAX_LINE,sizeof(char)); */ s_tmp = (char *)mCalloc(10+ (int)strlen(subtrees[0])+1+ (int)strlen(subtrees[1])+1, sizeof(char)); strcat(s_tmp,"(\0"); strcat(s_tmp,subtrees[0]); strcat(s_tmp,",\0"); strcat(s_tmp,subtrees[1]); strcat(s_tmp,")#NULL\0"); /* Add the label 'NULL' to identify a non-existing edge */ Free(subtrees[0]); subtrees[0] = s_tmp; for(i=1;in_otu) PhyML_Fprintf(fp,"\t%3d\t%s,\n",i+1,tree->a_nodes[i]->name); PhyML_Fprintf(fp,"\tUTREE PAUP_1=\n"); PhyML_Fprintf(fp,"%s\n",s_tree); PhyML_Fprintf(fp,"ENDBLOCK;"); } Free(s_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *Write_Tree(t_tree *tree, int custom) { char *s; int i,available; #ifndef MPI int init_len; init_len = 3*(int)T_MAX_NAME; s=(char *)mCalloc(init_len,sizeof(char)); available = init_len; #elif defined MPI s=(char *)mCalloc(T_MAX_LINE,sizeof(char)); #endif s[0]='('; if(custom == NO) { if(!tree->n_root) { i = 0; while((!tree->a_nodes[tree->n_otu+i]->v[0]) || (!tree->a_nodes[tree->n_otu+i]->v[1]) || (!tree->a_nodes[tree->n_otu+i]->v[2])) i++; R_wtree(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[0],&available,&s,tree); R_wtree(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[1],&available,&s,tree); R_wtree(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[2],&available,&s,tree); } else { R_wtree(tree->n_root,tree->n_root->v[2],&available,&s,tree); R_wtree(tree->n_root,tree->n_root->v[1],&available,&s,tree); } } else { int pos; pos = 1; if(!tree->n_root) { i = 0; while((!tree->a_nodes[tree->n_otu+i]->v[0]) || (!tree->a_nodes[tree->n_otu+i]->v[1]) || (!tree->a_nodes[tree->n_otu+i]->v[2])) i++; R_wtree_Custom(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[0],&available,&s,&pos,tree); R_wtree_Custom(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[1],&available,&s,&pos,tree); R_wtree_Custom(tree->a_nodes[tree->n_otu+i],tree->a_nodes[tree->n_otu+i]->v[2],&available,&s,&pos,tree); } else { R_wtree_Custom(tree->n_root,tree->n_root->v[2],&available,&s,&pos,tree); R_wtree_Custom(tree->n_root,tree->n_root->v[1],&available,&s,&pos,tree); } } s[(int)strlen(s)-1]=')'; s[(int)strlen(s)]=';'; return s; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void R_wtree(t_node *pere, t_node *fils, int *available, char **s_tree, t_tree *tree) { int i,p; char *format; int last_len; #if !(defined PHYTIME || defined INVITEE) phydbl mean_len; #endif format = (char *)mCalloc(100,sizeof(char)); sprintf(format,"%%.%df",tree->bl_ndigits); p = -1; if(fils->tax) { /* printf("\n- Writing on %p",*s_tree); */ /* ori_len = *pos; */ last_len = (int)strlen(*s_tree); if(OUTPUT_TREE_FORMAT == NEWICK) { if(tree->write_tax_names == YES) { if(tree->io && tree->io->long_tax_names) { strcat(*s_tree,tree->io->long_tax_names[fils->num]); } else { if(fils->name && strlen(fils->name) > 0) strcat(*s_tree,fils->name); else sprintf(*s_tree+(int)strlen(*s_tree),"%d",fils->num+1); } } else if(tree->write_tax_names == NO) { sprintf(*s_tree+(int)strlen(*s_tree),"%d",fils->num+1); } } else if(OUTPUT_TREE_FORMAT == NEXUS) { sprintf(*s_tree+(int)strlen(*s_tree),"%d",fils->num+1); } else { PhyML_Printf("\n== Unknown tree format."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); PhyML_Printf("\n== s=%s\n",*s_tree); } if((fils->b) && (fils->b[0]) && (tree->write_br_lens == YES)) { (*s_tree)[(int)strlen(*s_tree)] = ':'; #if !(defined PHYTIME || defined INVITEE) if(!tree->n_root) { if(tree->is_mixt_tree == NO) { mean_len = fils->b[0]->l->v; } else mean_len = MIXT_Get_Mean_Edge_Len(fils->b[0],tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len)); } else { if(pere == tree->n_root) { phydbl root_pos = (fils == tree->n_root->v[2])?(tree->n_root_pos):(1.-tree->n_root_pos); if(tree->is_mixt_tree == NO) { mean_len = tree->e_root->l->v; } else mean_len = MIXT_Get_Mean_Edge_Len(tree->e_root,tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len) * root_pos); } else { if(tree->is_mixt_tree == NO) { mean_len = fils->b[0]->l->v; } else mean_len = MIXT_Get_Mean_Edge_Len(fils->b[0],tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len)); } } #else if(!tree->n_root) { sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[0]->l->v)); } else { if(tree->rates) sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,tree->rates->cur_l[fils->num])); } #endif } /* strcat(*s_tree,","); */ (*s_tree)[(int)strlen(*s_tree)] = ','; #ifndef MPI (*available) -= ((int)strlen(*s_tree) - last_len); /* printf("\n0 Available = %d [%d %d]",(*available),(int)strlen(*s_tree),last_len); */ /* printf("\n0 %s [%d,%d]",*s_tree,(int)(int)strlen(*s_tree),*available); */ if(*available < 0) { PhyML_Printf("\n== s=%s\n",*s_tree); PhyML_Printf("\n== len=%d\n",(int)strlen(*s_tree)); PhyML_Printf("\n== The sequence names in your input file might be too long."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(*available < (int)T_MAX_NAME) { (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char)); For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0'; (*available) = 3*(int)T_MAX_NAME; /* printf("\n. ++ 0 Available = %d",(*available)); */ } #endif } else { (*s_tree)[(int)strlen(*s_tree)]='('; #ifndef MPI (*available) -= 1; /* printf("\n1 Available = %d [%d %d]",(*available),(int)strlen(*s_tree),last_len); */ /* printf("\n1 %s [%d,%d]",*s_tree,(int)(int)strlen(*s_tree),*available); */ if(*available < (int)T_MAX_NAME) { (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char)); For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0'; (*available) = 3*(int)T_MAX_NAME; /* printf("\n. ++ 1 Available = %d",(*available)); */ } #endif /* (*available)--; */ /* if(*available < (int)T_MAX_NAME/2) */ /* { */ /* (*s_tree) = (char *)mRealloc(*s_tree,*pos+(int)T_MAX_NAME,sizeof(char)); */ /* (*available) = (int)T_MAX_NAME; */ /* } */ if(tree->n_root) { For(i,3) { if((fils->v[i] != pere) && (fils->b[i] != tree->e_root)) R_wtree(fils,fils->v[i],available,s_tree,tree); else p=i; } } else { For(i,3) { if(fils->v[i] != pere) R_wtree(fils,fils->v[i],available,s_tree,tree); else p=i; } } if(p < 0) { PhyML_Printf("\n== pere: %d fils=%d root=%d root->v[2]=%d root->v[1]=%d",pere->num,fils->num,tree->n_root->num,tree->n_root->v[2]->num,tree->n_root->v[1]->num); PhyML_Printf("\n== fils=%p root=%p root->v[2]=%p root->v[1]=%p",fils,tree->n_root,tree->n_root->v[2],tree->n_root->v[1]); PhyML_Printf("\n== tree->e_root=%p fils->b[0]=%p fils->b[1]=%p fils->b[2]=%p",tree->e_root,fils->b[0],fils->b[1],fils->b[2]); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } last_len = (int)strlen(*s_tree); (*s_tree)[last_len-1] = ')'; if((fils->b) && (tree->write_br_lens == YES)) { if(tree->print_boot_val) { sprintf(*s_tree+(int)strlen(*s_tree),"%d",fils->b[p]->bip_score); } else if(tree->print_alrt_val) { sprintf(*s_tree+(int)strlen(*s_tree),"%f",fils->b[p]->ratio_test); } fflush(NULL); (*s_tree)[(int)strlen(*s_tree)] = ':'; #if !(defined PHYTIME || defined INVITEE) if(!tree->n_root) { if(tree->is_mixt_tree == NO) { mean_len = fils->b[p]->l->v; } else mean_len = MIXT_Get_Mean_Edge_Len(fils->b[p],tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len)); } else { if(pere == tree->n_root) { phydbl root_pos = (fils == tree->n_root->v[2])?(tree->n_root_pos):(1.-tree->n_root_pos); if(tree->is_mixt_tree == NO) { mean_len = (tree->e_root)?(tree->e_root->l->v):(-1.0); } else mean_len = MIXT_Get_Mean_Edge_Len(tree->e_root,tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len) * root_pos); } else { if(tree->is_mixt_tree == NO) { mean_len = fils->b[p]->l->v; } else mean_len = MIXT_Get_Mean_Edge_Len(fils->b[p],tree); sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,mean_len)); } } #else if(!tree->n_root) { sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,fils->b[p]->l->v)); } else { if(tree->rates) sprintf(*s_tree+(int)strlen(*s_tree),format,MAX(0.0,tree->rates->cur_l[fils->num])); } #endif } /* strcat(*s_tree,","); */ (*s_tree)[(int)strlen(*s_tree)] = ','; #ifndef MPI (*available) -= ((int)strlen(*s_tree) - last_len); /* printf("\n2 Available = %d [%d %d]",(*available),(int)strlen(*s_tree),last_len); */ /* printf("\n2 %s [%d,%d]",*s_tree,(int)(int)strlen(*s_tree),*available); */ if(*available < 0) { PhyML_Printf("\n== available = %d",*available); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(*available < (int)T_MAX_NAME) { (*s_tree) = (char *)mRealloc(*s_tree,(int)strlen(*s_tree)+3*(int)T_MAX_NAME,sizeof(char)); For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0'; (*available) = 3*(int)T_MAX_NAME; /* printf("\n. ++ 2 Available = %d",(*available)); */ } #endif /* if(*available < (int)T_MAX_NAME/2) */ /* { */ /* (*s_tree) = (char *)mRealloc(*s_tree,*pos+(int)T_MAX_NAME,sizeof(char)); */ /* (*available) = (int)T_MAX_NAME; */ /* } */ } Free(format); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void R_wtree_Custom(t_node *pere, t_node *fils, int *available, char **s_tree, int *pos, t_tree *tree) { int i,p,ori_len; char *format; format = (char *)mCalloc(100,sizeof(char)); sprintf(format,"%%.%df",tree->bl_ndigits); /* strcpy(format,"%f"); */ p = -1; if(fils->tax) { /* printf("\n- Writing on %p",*s_tree); */ ori_len = *pos; if(OUTPUT_TREE_FORMAT == NEWICK) { if(tree->write_tax_names == YES) { if(tree->io && tree->io->long_tax_names) { strcat(*s_tree,tree->io->long_tax_names[fils->num]); (*pos) += (int)strlen(tree->io->long_tax_names[fils->num]); } else { strcat(*s_tree,fils->name); (*pos) += (int)strlen(fils->name); } } else if(tree->write_tax_names == NO) { (*pos) += sprintf(*s_tree+*pos,"%d",fils->num); } } else if(OUTPUT_TREE_FORMAT == NEXUS) { (*pos) += sprintf(*s_tree+*pos,"%d",fils->num+1); } else { PhyML_Printf("\n== Unknown tree format."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); PhyML_Printf("\n== s=%s\n",*s_tree); } if((fils->b) && (fils->b[0]) && (tree->write_br_lens == YES)) { strcat(*s_tree,":"); (*pos)++; #if !(defined PHYTIME || defined INVITEE) if(!tree->n_root) { (*pos) += sprintf(*s_tree+*pos,format,fils->b[0]->l->v); } else { if(pere == tree->n_root) { phydbl root_pos = (fils == tree->n_root->v[2])?(tree->n_root_pos):(1.-tree->n_root_pos); (*pos) += sprintf(*s_tree+*pos,format,tree->e_root->l->v * root_pos); } else { (*pos) += sprintf(*s_tree+*pos,format,fils->b[0]->l->v); } } #else if(!tree->n_root) { (*pos) += sprintf(*s_tree+*pos,format,fils->b[0]->l->v); } else { (*pos) += sprintf(*s_tree+*pos,format,tree->rates->cur_l[fils->num]); } #endif } if(tree->write_labels) { if(fils->b[0]->n_labels < 10) For(i,fils->b[0]->n_labels) { (*pos) += sprintf(*s_tree+*pos,"::%s",fils->b[0]->labels[i]); } else { (*pos) += sprintf(*s_tree+*pos,"::%d_labels",fils->b[0]->n_labels); } } strcat(*s_tree,","); (*pos)++; (*available) = (*available) - (*pos - ori_len); if(*available < 0) { PhyML_Printf("\n== s=%s\n",*s_tree); PhyML_Printf("\n== len=%d\n",strlen(*s_tree)); PhyML_Printf("\n== The sequence names in your input file might be too long."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(*available < (int)T_MAX_NAME) { (*s_tree) = (char *)mRealloc(*s_tree,*pos+3*(int)T_MAX_NAME,sizeof(char)); For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0'; (*available) = 3*(int)T_MAX_NAME; } /* printf(" %s [%d,%d]",*s_tree,(int)strlen(*s_tree),*available); */ } else { (*s_tree)[(*pos)]='('; (*s_tree)[(*pos)+1]='\0'; (*pos)++; (*available)--; if(*available < (int)T_MAX_NAME/2) { (*s_tree) = (char *)mRealloc(*s_tree,*pos+(int)T_MAX_NAME,sizeof(char)); (*available) = (int)T_MAX_NAME; } if(tree->n_root) { For(i,3) { if((fils->v[i] != pere) && (fils->b[i] != tree->e_root)) R_wtree_Custom(fils,fils->v[i],available,s_tree,pos,tree); else p=i; } } else { For(i,3) { if(fils->v[i] != pere) R_wtree_Custom(fils,fils->v[i],available,s_tree,pos,tree); else p=i; } } ori_len = *pos; if(p < 0) { PhyML_Printf("\n== fils=%p root=%p root->v[2]=%p root->v[1]=%p",fils,tree->n_root,tree->n_root->v[2],tree->n_root->v[1]); PhyML_Printf("\n== tree->e_root=%p fils->b[0]=%p fils->b[1]=%p fils->b[2]=%p",tree->e_root,fils->b[0],fils->b[1],fils->b[2]); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* printf("\n+ Writing on %p",*s_tree); */ (*s_tree)[(*pos)-1] = ')'; (*s_tree)[(*pos)] = '\0'; if((fils->b) && (tree->write_br_lens == YES)) { if(tree->print_boot_val) { (*pos) += sprintf(*s_tree+*pos,"%d",fils->b[p]->bip_score); } else if(tree->print_alrt_val) { (*pos) += sprintf(*s_tree+*pos,"%f",fils->b[p]->ratio_test); } fflush(NULL); strcat(*s_tree,":"); (*pos)++; #if !(defined PHYTIME || defined INVITEE) if(!tree->n_root) { (*pos) += sprintf(*s_tree+*pos,format,fils->b[p]->l->v); } else { if(pere == tree->n_root) { phydbl root_pos = (fils == tree->n_root->v[2])?(tree->n_root_pos):(1.-tree->n_root_pos); (*pos) += sprintf(*s_tree+*pos,format,tree->e_root->l->v * root_pos); } else { (*pos) += sprintf(*s_tree+*pos,format,fils->b[p]->l->v); } } #else if(!tree->n_root) { (*pos) += sprintf(*s_tree+*pos,format,fils->b[p]->l->v); } else { (*pos) += sprintf(*s_tree+*pos,format,tree->rates->cur_l[fils->num]); } #endif } if((tree->write_labels) && (fils->b[p]->labels != NULL)) { if(fils->b[p]->n_labels < 10) For(i,fils->b[p]->n_labels) { (*pos) += sprintf(*s_tree+*pos,"::%s",fils->b[p]->labels[i]); } else { (*pos) += sprintf(*s_tree+*pos,"::%d_labels",fils->b[p]->n_labels); } } strcat(*s_tree,","); (*pos)++; (*available) = (*available) - (*pos - ori_len); if(*available < 0) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(*available < (int)T_MAX_NAME) { (*s_tree) = (char *)mRealloc(*s_tree,*pos+3*(int)T_MAX_NAME,sizeof(char)); For(i,3*(int)T_MAX_NAME) (*s_tree)[(int)strlen(*s_tree)+i] = '\0'; (*available) = 3*(int)T_MAX_NAME; } /* printf(" %s [%d,%d]",*s_tree,(int)strlen(*s_tree),*available); */ } Free(format); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Detect_Align_File_Format(option *io) { int c; fpos_t curr_pos; fgetpos(io->fp_in_align,&curr_pos); errno = 0; while((c=fgetc(io->fp_in_align)) != EOF) { if(errno) io->data_file_format = PHYLIP; else if(c == '#') { char s[10],t[6]="NEXUS"; if(!fgets(s,6,io->fp_in_align)) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(!strcmp(t,s)) { fsetpos(io->fp_in_align,&curr_pos); io->data_file_format = NEXUS; return; } } } fsetpos(io->fp_in_align,&curr_pos); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Detect_Tree_File_Format(option *io) { int c; fpos_t curr_pos; fgetpos(io->fp_in_tree,&curr_pos); errno = 0; while((c=fgetc(io->fp_in_tree)) != EOF) { if(errno) { io->tree_file_format = PHYLIP; PhyML_Printf("\n. Detected PHYLIP tree file format."); } else if(c == '#') { char s[10],t[6]="NEXUS"; if(!fgets(s,6,io->fp_in_tree)) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(!strcmp(t,s)) { fsetpos(io->fp_in_tree,&curr_pos); io->tree_file_format = NEXUS; PhyML_Printf("\n. Detected NEXUS tree file format."); return; } } } fsetpos(io->fp_in_tree,&curr_pos); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// align **Get_Seq(option *io) { io->data = NULL; if(!io->fp_in_align) { PhyML_Printf("\n== Filehandle to '%s' seems to be closed.",io->in_align_file); Exit("\n"); } Detect_Align_File_Format(io); switch(io->data_file_format) { case PHYLIP: { io->data = Get_Seq_Phylip(io); break; } case NEXUS: { io->nex_com_list = Make_Nexus_Com(); Init_Nexus_Format(io->nex_com_list); Get_Nexus_Data(io->fp_in_align,io); Free_Nexus(io); break; } default: { PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); break; } } if(!io->data) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } else { Post_Process_Data(io); } return io->data; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Post_Process_Data(option *io) { int i,j,swap; align *data_buff; For(i,io->data[0]->len) { For(j,io->n_otu) { if((io->data[j]->state[i] == '?') || (io->data[j]->state[i] == '-')) io->data[j]->state[i] = 'X'; if((io->datatype == NT) && (io->data[j]->state[i] == 'N')) io->data[j]->state[i] = 'X'; if(io->data[j]->state[i] == 'U') io->data[j]->state[i] = 'T'; } } For(i,io->n_otu) io->data[i]->len = io->data[0]->len; /* Sequences are ordered alphabetically */ data_buff = NULL; swap = TRUE; while(swap == TRUE) { swap = FALSE; For(i,io->n_otu-1) { for(j=i+1;jn_otu;j++) { if(strcmp(io->data[i]->name,io->data[j]->name) < 0) { swap = TRUE; data_buff = io->data[i]; io->data[i] = io->data[j]; io->data[j] = data_buff; } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* align **Get_Seq_Nexus(option *io) */ /* { */ /* char *s,*ori_s; */ /* char *token; */ /* int in_comment; */ /* nexcom *curr_com; */ /* nexparm *curr_parm; */ /* int nxt_token_t,cur_token_t; */ /* s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); */ /* token = (char *)mCalloc(T_MAX_TOKEN,sizeof(char)); */ /* ori_s = s; */ /* in_comment = NO; */ /* curr_com = NULL; */ /* curr_parm = NULL; */ /* nxt_token_t = NEXUS_COM; */ /* cur_token_t = -1; */ /* while(fgets(s,T_MAX_LINE,io->fp_in_align)) */ /* { */ /* do */ /* { */ /* Get_Token(&s,token); */ /* /\* PhyML_Printf("\n. Token: '%s' next_token=%d cur_token=%d",token,nxt_token_t,cur_token_t); *\/ */ /* if(token[0] == '\0') break; */ /* if(token[0] == ';') */ /* { */ /* curr_com = NULL; */ /* curr_parm = NULL; */ /* nxt_token_t = NEXUS_COM; */ /* cur_token_t = -1; */ /* break; /\* End of command *\/ */ /* } */ /* if(nxt_token_t == NEXUS_EQUAL) */ /* { */ /* cur_token_t = NEXUS_VALUE; */ /* nxt_token_t = NEXUS_PARM; */ /* continue; */ /* } */ /* if((nxt_token_t == NEXUS_COM) && (cur_token_t != NEXUS_VALUE)) */ /* { */ /* Find_Nexus_Com(token,&curr_com,&curr_parm,io->nex_com_list); */ /* if(curr_com) */ /* { */ /* nxt_token_t = curr_com->nxt_token_t; */ /* cur_token_t = curr_com->cur_token_t; */ /* } */ /* if(cur_token_t != NEXUS_VALUE) continue; */ /* } */ /* if((nxt_token_t == NEXUS_PARM) && (cur_token_t != NEXUS_VALUE)) */ /* { */ /* Find_Nexus_Parm(token,&curr_parm,curr_com); */ /* if(curr_parm) */ /* { */ /* nxt_token_t = curr_parm->nxt_token_t; */ /* cur_token_t = curr_parm->cur_token_t; */ /* } */ /* if(cur_token_t != NEXUS_VALUE) continue; */ /* } */ /* if(cur_token_t == NEXUS_VALUE) */ /* { */ /* if((curr_parm->fp)(token,curr_parm,io)) /\* Read in parameter value *\/ */ /* { */ /* nxt_token_t = NEXUS_PARM; */ /* cur_token_t = -1; */ /* } */ /* } */ /* } */ /* while(strlen(token) > 0); */ /* } */ /* Free(ori_s); */ /* Free(token); */ /* return io->data; */ /* } */ /* /\*********************************************************\/ */ void Get_Nexus_Data(FILE *fp, option *io) { char *token; nexcom *curr_com; nexparm *curr_parm; int nxt_token_t,cur_token_t; token = (char *)mCalloc(T_MAX_TOKEN,sizeof(char)); curr_com = NULL; curr_parm = NULL; nxt_token_t = NEXUS_COM; cur_token_t = -1; do { if(!Get_Token(fp,token)) break; /* PhyML_Printf("\n+ Token: '%s' next_token=%d cur_token=%d",token,nxt_token_t,cur_token_t); */ if(token[0] == ';') { curr_com = NULL; curr_parm = NULL; nxt_token_t = NEXUS_COM; cur_token_t = -1; } if(nxt_token_t == NEXUS_EQUAL) { cur_token_t = NEXUS_VALUE; nxt_token_t = NEXUS_PARM; continue; } if((nxt_token_t == NEXUS_COM) && (cur_token_t != NEXUS_VALUE)) { Find_Nexus_Com(token,&curr_com,&curr_parm,io->nex_com_list); if(curr_com) { nxt_token_t = curr_com->nxt_token_t; cur_token_t = curr_com->cur_token_t; } if(cur_token_t != NEXUS_VALUE) continue; } if((nxt_token_t == NEXUS_PARM) && (cur_token_t != NEXUS_VALUE)) { Find_Nexus_Parm(token,&curr_parm,curr_com); if(curr_parm) { nxt_token_t = curr_parm->nxt_token_t; cur_token_t = curr_parm->cur_token_t; } if(cur_token_t != NEXUS_VALUE) continue; } if(cur_token_t == NEXUS_VALUE) { if((curr_parm->fp)(token,curr_parm,io)) /* Read in parameter value */ { nxt_token_t = NEXUS_PARM; cur_token_t = -1; } } } while(strlen(token) > 0); Free(token); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_Token(FILE *fp, char *token) { char c; c = ' '; while(c == ' ' || c == '\t' || c == '\n' || c == '\r') { c = fgetc(fp); if(c == EOF) return 0; } if(c == '"') { do { *token = c; token++; c = fgetc(fp); if(c == EOF) return 0; } while(c != '"'); *token = c; /* c = fgetc(fp); */ if(c == EOF) return 0; *(token+1) = '\0'; return 1; } if(c == '[') { Skip_Comment(fp); c = fgetc(fp); *token = c; token++; if(c == EOF) return 0; return 1; } if(c == '#') { *token = c; token++; } else if(c == ';') { *token = c; token++; } else if(c == ',') { *token = c; token++; } else if(c == '.') { *token = c; token++; } else if(c == '=') { *token = c; token++; } else if(c == '(') { *token = c; token++; } else if(c == ')') { *token = c; token++; } else if(c == '{') { *token = c; token++; } else if(c == '}') { *token = c; token++; } else if(c == '?') { *token = c; token++; } else if(c == '-') { *token = c; token++; } else { while(isgraph(c) && c != ';' && c != '-' && c != ',' && c != '=') { *(token++) = c; c = fgetc(fp); if(c == EOF) return 0; } fseek(fp,-1*sizeof(char),SEEK_CUR); } *token = '\0'; return 1; } /* void Get_Token(char *line, char *token) */ /* { */ /* while(**line == ' ' || **line == '\t') (*line)++; */ /* if(**line == '"') */ /* { */ /* do { *token = **line; (*line)++; token++; } while(**line != '"'); */ /* *token = **line; */ /* (*line)++; */ /* *(token+1) = '\0'; */ /* return; */ /* } */ /* if(**line == '[') */ /* { */ /* int in_comment; */ /* in_comment = 1; */ /* do */ /* { */ /* (*line)++; */ /* if(**line == '[') */ /* { */ /* in_comment++; */ /* } */ /* else if(**line == ']') in_comment--; */ /* } */ /* while(in_comment); */ /* (*line)++; */ /* return; */ /* } */ /* if(**line == '#') {*token = **line; (*line)++; token++; } */ /* else if(**line == ';') {*token = **line; (*line)++; token++; } */ /* else if(**line == ',') {*token = **line; (*line)++; token++; } */ /* else if(**line == '.') {*token = **line; (*line)++; token++; } */ /* else if(**line == '=') {*token = **line; (*line)++; token++; } */ /* else if(**line == '(') {*token = **line; (*line)++; token++; } */ /* else if(**line == ')') {*token = **line; (*line)++; token++; } */ /* else if(**line == '{') {*token = **line; (*line)++; token++; } */ /* else if(**line == '}') {*token = **line; (*line)++; token++; } */ /* else if(**line == '?') {*token = **line; (*line)++; token++; } */ /* else if(**line == '-') {*token = **line; (*line)++; token++; } */ /* else */ /* { */ /* while(isgraph(**line) && **line != ';' && **line != '=' && **line != ',') */ /* { */ /* *(token++) = **line; */ /* (*line)++; */ /* } */ /* } */ /* *token = '\0'; */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// align **Get_Seq_Phylip(option *io) { Read_Ntax_Len_Phylip(io->fp_in_align,&io->n_otu,&io->init_len); if(io->n_otu > N_MAX_OTU) { PhyML_Printf("\n== The number of taxa should not exceed %d",N_MAX_OTU); Exit("\n"); } if(io->interleaved) io->data = Read_Seq_Interleaved(io); else io->data = Read_Seq_Sequential(io); return io->data; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Ntax_Len_Phylip(FILE *fp ,int *n_otu, int *n_tax) { char *line; int readok; line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); readok = 0; do { if(fscanf(fp,"%s",line) == EOF) { Free(line); PhyML_Printf("\n== PhyML can't read in this alignment."); PhyML_Printf("\n== Could it be that sequence file is empty?"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } else { if(strcmp(line,"\n") && strcmp(line,"\r") && strcmp(line,"\t")) { sscanf(line,"%d",n_otu); if(*n_otu <= 0) Warn_And_Exit("\n. The number of taxa cannot be negative.\n"); if(!fscanf(fp,"%s",line)) Exit("\n"); sscanf(line,"%d",n_tax); if(*n_tax <= 0) Warn_And_Exit("\n. The sequence length cannot be negative.\n"); else readok = 1; } } }while(!readok); Free(line); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// align **Read_Seq_Sequential(option *io) { int i; char *line; align **data; /* char c; */ char *format; format = (char *)mCalloc(T_MAX_NAME,sizeof(char)); line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); data = (align **)mCalloc(io->n_otu,sizeof(align *)); /* while((c=fgetc(in))!='\n'); */ /* while(((c=fgetc(io->fp_in_align))!='\n') && (c != ' ') && (c != '\r') && (c != '\t')); */ sprintf(format, "%%%ds", T_MAX_NAME); For(i,io->n_otu) { data[i] = (align *)mCalloc(1,sizeof(align)); data[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); data[i]->state = (char *)mCalloc(io->init_len*io->state_len+1,sizeof(char)); data[i]->is_ambigu = NULL; data[i]->len = 0; if(!fscanf(io->fp_in_align,format,data[i]->name)) Exit("\n"); Check_Sequence_Name(data[i]->name); while(data[i]->len < io->init_len * io->state_len) Read_One_Line_Seq(&data,i,io->fp_in_align); if(data[i]->len != io->init_len * io->state_len) { PhyML_Printf("\n== Err. Problem with species %s's sequence (check the format).\n",data[i]->name); PhyML_Printf("\n== Observed sequence length: %d, expected length: %d\n",data[i]->len, io->init_len * io->state_len); Warn_And_Exit(""); } } For(i,io->n_otu) data[i]->state[data[i]->len] = '\0'; Restrict_To_Coding_Position(data,io); Free(format); Free(line); return data; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// align **Read_Seq_Interleaved(option *io) { int i,end,num_block; char *line; align **data; /* char c; */ char *format; fpos_t curr_pos; line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); format = (char *)mCalloc(T_MAX_NAME, sizeof(char)); data = (align **)mCalloc(io->n_otu,sizeof(align *)); /* while(((c=fgetc(io->fp_in_align))!='\n') && (c != ' ') && (c != '\r') && (c != '\t')); */ sprintf(format, "%%%ds", T_MAX_NAME); end = 0; For(i,io->n_otu) { data[i] = (align *)mCalloc(1,sizeof(align)); data[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); data[i]->state = (char *)mCalloc(io->init_len*io->state_len+1,sizeof(char)); data[i]->len = 0; data[i]->is_ambigu = NULL; if(!fscanf(io->fp_in_align,format,data[i]->name)) Exit("\n"); Check_Sequence_Name(data[i]->name); if(!Read_One_Line_Seq(&data,i,io->fp_in_align)) { end = 1; if((i != io->n_otu) && (i != io->n_otu-1)) { PhyML_Printf("\n== i:%d n_otu:%d",i,io->n_otu); PhyML_Printf("\n== Err.: problem with species %s's sequence.\n",data[i]->name); PhyML_Printf("\n== Observed sequence length: %d, expected length: %d\n",data[i]->len, io->init_len * io->state_len); Exit(""); } break; } } if(data[0]->len == io->init_len * io->state_len) end = 1; /* if(end) printf("\n. finished yet '%c'\n",fgetc(io->fp_in_align)); */ if(!end) { end = 0; num_block = 1; do { num_block++; /* interblock */ if(!fgets(line,T_MAX_LINE,io->fp_in_align)) break; if(line[0] != 13 && line[0] != 10) { PhyML_Printf("\n== Err.: one or more missing sequences in block %d.\n",num_block-1); Exit(""); } For(i,io->n_otu) if(data[i]->len != io->init_len * io->state_len) break; if(i == io->n_otu) break; For(i,io->n_otu) { /* Skip the taxon name, if any, in this interleaved block */ fgetpos(io->fp_in_align,&curr_pos); if(!fscanf(io->fp_in_align,format,line)) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(line && strcmp(line,data[i]->name)) fsetpos(io->fp_in_align,&curr_pos); if(data[i]->len > io->init_len * io->state_len) { PhyML_Printf("\n== Observed sequence length=%d expected length=%d.\n",data[i]->len,io->init_len * io->state_len); PhyML_Printf("\n== Err.: Problem with species %s's sequence.\n",data[i]->name); Exit(""); } else if(!Read_One_Line_Seq(&data,i,io->fp_in_align)) { end = 1; if((i != io->n_otu) && (i != io->n_otu-1)) { PhyML_Printf("\n== Err.: Problem with species %s's sequence.\n",data[i]->name); PhyML_Printf("\n== Observed sequence length: %d, expected length: %d.\n",data[i]->len, io->init_len * io->state_len); Exit(""); } break; } } }while(!end); } For(i,io->n_otu) data[i]->state[data[i]->len] = '\0'; For(i,io->n_otu) { if(data[i]->len != io->init_len * io->state_len) { PhyML_Printf("\n== Check sequence '%s' length (expected length: %d, observed length: %d) [OTU %d].\n",data[i]->name,io->init_len,data[i]->len,i+1); Exit(""); } } Restrict_To_Coding_Position(data,io); Free(format); Free(line); return data; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_One_Line_Seq(align ***data, int num_otu, FILE *in) { char c = ' '; int nchar = 0; while(1) { /* if((c == EOF) || (c == '\n') || (c == '\r')) break; */ if((c == 13) || (c == 10)) { /* PhyML_Printf("[%d %d]\n",c,nchar); fflush(NULL); */ if(!nchar) { c=(char)fgetc(in); continue; } else { /* PhyML_Printf("break\n"); */ break; } } else if(c == EOF) { /* PhyML_Printf("EOL\n"); */ break; } else if((c == ' ') || (c == '\t') || (c == 32)) { /* PhyML_Printf("[%d]",c); */ c=(char)fgetc(in); continue; } nchar++; Uppercase(&c); if(c == '.') { c = (*data)[0]->state[(*data)[num_otu]->len]; if(!num_otu) Warn_And_Exit("\n== Err: Symbol \".\" should not appear in the first sequence\n"); } (*data)[num_otu]->state[(*data)[num_otu]->len]=c; (*data)[num_otu]->len++; c = (char)fgetc(in); /* PhyML_Printf("[%c %d]",c,c); */ if(c == ';') break; } /* printf("\n. Exit nchar: %d [%d]\n",nchar,c==EOF); */ if(c == EOF) return 0; else return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Read_Tree_File(option *io) { t_tree *tree; if(!io->fp_in_tree) { PhyML_Printf("\n== Filehandle to '%s' seems to be closed.",io->in_tree_file); Exit("\n"); } Detect_Tree_File_Format(io); io->treelist->list_size = 0; switch(io->tree_file_format) { case PHYLIP: { do { io->treelist->tree = (t_tree **)realloc(io->treelist->tree,(io->treelist->list_size+1)*sizeof(t_tree *)); io->tree = Read_Tree_File_Phylip(io->fp_in_tree); if(!io->tree) break; if(io->treelist->list_size > 1) PhyML_Printf("\n. Reading tree %d",io->treelist->list_size+1); io->treelist->tree[io->treelist->list_size] = io->tree; io->treelist->list_size++; }while(io->tree); break; } case NEXUS: { io->nex_com_list = Make_Nexus_Com(); Init_Nexus_Format(io->nex_com_list); Get_Nexus_Data(io->fp_in_tree,io); Free_Nexus(io); break; } default: { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } if(!io->long_tax_names) { int i; tree = io->treelist->tree[0]; io->long_tax_names = (char **)mCalloc(tree->n_otu,sizeof(char *)); io->short_tax_names = (char **)mCalloc(tree->n_otu,sizeof(char *)); For(i,tree->n_otu) { io->long_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char)); io->short_tax_names[i] = (char *)mCalloc(strlen(tree->a_nodes[i]->name)+1,sizeof(char)); strcpy(io->long_tax_names[i],tree->a_nodes[i]->name); strcpy(io->short_tax_names[i],tree->a_nodes[i]->name); } } return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *Return_Tree_String_Phylip(FILE *fp_input_tree) { char *line; int i; char c; int open,maxopen; if(fp_input_tree == NULL) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } do { c=fgetc(fp_input_tree); } while((c != '(') && (c != EOF)); if(c==EOF) return NULL; line = (char *)mCalloc(1,sizeof(char)); open = 1; maxopen = open; i=0; for(;;) { if((c == ' ') || (c == '\n')) { c=fgetc(fp_input_tree); if(c == EOF || c == ';') break; else continue; } if(c == '[') { Skip_Comment(fp_input_tree); c = fgetc(fp_input_tree); if(c == EOF || c == ';') break; } line = (char *)mRealloc(line,i+2,sizeof(char)); line[i]=c; i++; c=fgetc(fp_input_tree); if(c==EOF || c==';') break; if(c=='(') open++; if(c==')') open--; if(open>maxopen) maxopen = open; } line[i] = '\0'; /* if(maxopen == 1) return NULL; */ return line; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Read_Tree_File_Phylip(FILE *fp_input_tree) { char *line; t_tree *tree; line = Return_Tree_String_Phylip(fp_input_tree); tree = Read_Tree(&line); Free(line); return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Site(calign *cdata, int num, int n_otu, char *sep, int stepsize, FILE *fp) { int i,j; PhyML_Fprintf(fp,"\n"); For(i,n_otu) { PhyML_Fprintf(fp,"%20s ",cdata->c_seq[i]->name); For(j,stepsize) PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[num+j]); PhyML_Fprintf(fp,"%s",sep); } PhyML_Fprintf(fp,"%s",sep); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Site_Lk(t_tree *tree, FILE *fp) { int site; int catg; char *s; phydbl postmean,sum; if(!tree->io->print_site_lnl) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } if(!tree->io->print_trace) { s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); PhyML_Fprintf(fp,"Note : P(D|M) is the probability of site D given the model M (i.e., the site likelihood)\n"); if(tree->mod->ras->n_catg > 1 || tree->mod->ras->invar) { PhyML_Fprintf(fp,"P*(D|M,rr[x]) is the scaled probability of site D given the model M and the relative rate\n"); PhyML_Fprintf(fp,"of evolution rr[x], where x is the class of rate to be considered.\n"); PhyML_Fprintf(fp,"The actual conditional probability is given by P*(D|M,rr[x])/2^F, where\n"); PhyML_Fprintf(fp,"F is the scaling factor (see column 'Scaler').\n"); PhyML_Fprintf(fp,"For invariant sites, P(D|M,rr[0]=0) is the actual conditional probability\n"); PhyML_Fprintf(fp,"(i.e., it is not scaled).\n"); } PhyML_Fprintf(fp,"\n\n"); sprintf(s,"Site"); PhyML_Fprintf(fp, "%-12s",s); sprintf(s,"P(D|M)"); PhyML_Fprintf(fp,"%-15s",s); sprintf(s,"Scaler"); PhyML_Fprintf(fp,"%-7s",s); sprintf(s,"Pattern"); PhyML_Fprintf(fp, "%-9s",s); if(tree->mod->ras->n_catg > 1) { For(catg,tree->mod->ras->n_catg) { sprintf(s,"P*(D|M,rr[%d]=%5.4f)",catg+1,tree->mod->ras->gamma_rr->v[catg]); PhyML_Fprintf(fp,"%-23s",s); } sprintf(s,"Posterior mean"); PhyML_Fprintf(fp,"%-22s",s); } if(tree->mod->ras->invar) { sprintf(s,"P(D|M,rr[0]=0)"); PhyML_Fprintf(fp,"%-16s",s); } sprintf(s,"NDistinctStates"); PhyML_Fprintf(fp,"%-16s",s); PhyML_Fprintf(fp,"\n"); Init_Ui_Tips(tree); For(site,tree->data->init_len) { PhyML_Fprintf(fp,"%-12d",site+1); PhyML_Fprintf(fp,"%-15g",tree->cur_site_lk[tree->data->sitepatt[site]]); PhyML_Fprintf(fp,"%-7d",tree->fact_sum_scale[tree->data->sitepatt[site]]); PhyML_Fprintf(fp,"%-9d",tree->data->sitepatt[site]); if(tree->mod->ras->n_catg > 1) { For(catg,tree->mod->ras->n_catg) { PhyML_Fprintf(fp,"%-23g",tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]]); } postmean = .0; For(catg,tree->mod->ras->n_catg) postmean += tree->mod->ras->gamma_rr->v[catg] * tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]] * tree->mod->ras->gamma_r_proba->v[catg]; sum = .0; For(catg,tree->mod->ras->n_catg) { sum += tree->unscaled_site_lk_cat[catg*tree->n_pattern + tree->data->sitepatt[site]] * tree->mod->ras->gamma_r_proba->v[catg]; } postmean /= sum; PhyML_Fprintf(fp,"%-22g",postmean); } if(tree->mod->ras->invar) { if((phydbl)tree->data->invar[tree->data->sitepatt[site]] > -0.5) PhyML_Fprintf(fp,"%-16g",tree->mod->e_frq->pi->v[tree->data->invar[tree->data->sitepatt[site]]]); else PhyML_Fprintf(fp,"%-16g",0.0); } PhyML_Fprintf(fp,"%-16d",Number_Of_Diff_States_One_Site(tree->data->sitepatt[site],tree)); PhyML_Fprintf(fp,"\n"); } Free(s); } else { For(site,tree->data->init_len) PhyML_Fprintf(fp,"%.2f\t",LOG(tree->cur_site_lk[tree->data->sitepatt[site]])); PhyML_Fprintf(fp,"\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Seq(FILE *fp, align **data, int n_otu) { int i,j; PhyML_Fprintf(fp,"%d\t%d\n",n_otu,data[0]->len); For(i,n_otu) { For(j,20) { if(j<(int)strlen(data[i]->name)) fputc(data[i]->name[j],fp); else fputc(' ',fp); } /* PhyML_Printf("%10d ",i); */ For(j,data[i]->len) { PhyML_Fprintf(fp,"%c",data[i]->state[j]); } PhyML_Fprintf(fp,"\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_CSeq(FILE *fp, int compressed, calign *cdata) { int i,j; int n_otu; n_otu = cdata->n_otu; if(cdata->format == 0) { PhyML_Fprintf(fp,"%d\t%d\n",n_otu,cdata->init_len); } else { PhyML_Fprintf(fp,"#NEXUS\n"); PhyML_Fprintf(fp,"begin data\n"); PhyML_Fprintf(fp,"dimensions ntax=%d nchar=%d;\n",n_otu,cdata->init_len); PhyML_Fprintf(fp,"format sequential datatype=dna;\n"); PhyML_Fprintf(fp,"matrix\n"); } For(i,n_otu) { For(j,50) { if(j<(int)strlen(cdata->c_seq[i]->name)) fputc(cdata->c_seq[i]->name[j],fp); else fputc(' ',fp); } if(compressed == YES) /* Print out compressed sequences */ PhyML_Fprintf(fp,"%s",cdata->c_seq[i]->state); else /* Print out uncompressed sequences */ { For(j,cdata->init_len) { PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[cdata->sitepatt[j]]); } } PhyML_Fprintf(fp,"\n"); } PhyML_Fprintf(fp,"\n"); if(cdata->format == 1) { PhyML_Fprintf(fp,";\n"); PhyML_Fprintf(fp,"END;\n"); } /* PhyML_Printf("\t"); */ /* For(j,cdata->crunch_len) */ /* PhyML_Printf("%.0f ",cdata->wght[j]); */ /* PhyML_Printf("\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_CSeq_Select(FILE *fp, int compressed, calign *cdata, t_tree *tree) { int i,j; int n_otu; phydbl eps; int slice = 14; eps = 1.E-6; n_otu = 0; For(i,cdata->n_otu) if(tree->rates->nd_t[i] < tree->rates->time_slice_lims[slice] + eps) n_otu++; PhyML_Fprintf(fp,"%d\t%d\n",n_otu,cdata->init_len); n_otu = cdata->n_otu; For(i,n_otu) { if(tree->rates->nd_t[i] < tree->rates->time_slice_lims[slice] + eps) { For(j,50) { if(j<(int)strlen(cdata->c_seq[i]->name)) fputc(cdata->c_seq[i]->name[j],fp); else fputc(' ',fp); } if(compressed == YES) /* Print out compressed sequences */ PhyML_Fprintf(fp,"%s",cdata->c_seq[i]->state); else /* Print out uncompressed sequences */ { For(j,cdata->init_len) { PhyML_Fprintf(fp,"%c",cdata->c_seq[i]->state[cdata->sitepatt[j]]); } } PhyML_Fprintf(fp,"\n"); } } if(cdata->format == 1) { PhyML_Fprintf(fp,";\n"); PhyML_Fprintf(fp,"END;\n"); } /* PhyML_Printf("\t"); */ /* For(j,cdata->crunch_len) */ /* PhyML_Printf("%.0f ",cdata->wght[j]); */ /* PhyML_Printf("\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Dist(matrix *mat) { int i,j; For(i,mat->n_otu) { PhyML_Printf("%s ",mat->name[i]); For(j,mat->n_otu) PhyML_Printf("%9.6f ",mat->dist[i][j]); PhyML_Printf("\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Node(t_node *a, t_node *d, t_tree *tree) { int i; int dir; dir = -1; For(i,3) if(a->v[i] == d) {dir = i; break;} PhyML_Printf("Node nums: %3d %3d (dir:%3d) (anc:%3d) ta:%12f td:%12f;", a->num,d->num,dir,a->anc?a->anc->num:(-1), tree->rates?tree->rates->nd_t[a->num]:-1., tree->rates?tree->rates->nd_t[d->num]:-1.); PhyML_Printf("Node names = '%10s' '%10s' ; ",a->name,d->name); For(i,3) if(a->v[i] == d) { if(a->b[i]) { PhyML_Printf("Branch num = %3d%c (%3d %3d) %f", a->b[i]->num,a->b[i]==tree->e_root?'*':' ',a->b[i]->left->num, a->b[i]->rght->num,a->b[i]->l->v); if(a->b[i]->left->tax) PhyML_Printf(" WARNING LEFT->TAX!"); break; } } PhyML_Printf("\n"); if(d->tax) return; else For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) Print_Node(d,d->v[i],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Node_Brief(t_node *a, t_node *d, t_tree *tree, FILE *fp) { int i; int dir; dir = -1; For(i,3) if(a->v[i] == d) {dir = i; break;} PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"Node nums: %3d %3d (dir:%3d)", a->num,d->num,dir); PhyML_Fprintf(fp,"\tnames = '%10s' '%10s' ; ",a->name,d->name); For(i,3) if(a->v[i] == d) { if(a->b[i]) { PhyML_Fprintf(fp,"Branch num = %3d%c (%3d %3d) length:%10f", a->b[i]->num,a->b[i]==tree->e_root?'*':' ',a->b[i]->left->num, a->b[i]->rght->num,a->b[i]->l->v); if(a->b[i]->left->tax) PhyML_Printf(" WARNING LEFT->TAX!"); break; } } if(d->tax) return; else For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) Print_Node_Brief(d,d->v[i],tree,fp); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Model(t_mod *mod) { int i,j,k; PhyML_Printf("\n. name=%s",mod->modelname->s); PhyML_Printf("\n. string=%s",mod->custom_mod_string); PhyML_Printf("\n. mod_num=%d",mod->mod_num); PhyML_Printf("\n. ns=%d",mod->ns); PhyML_Printf("\n. n_catg=%d",mod->ras->n_catg); PhyML_Printf("\n. kappa=%f",mod->kappa->v); PhyML_Printf("\n. alpha=%f",mod->ras->alpha->v); PhyML_Printf("\n. lambda=%f",mod->lambda->v); PhyML_Printf("\n. pinvar=%f",mod->ras->pinvar->v); PhyML_Printf("\n. br_len_mult=%f",mod->br_len_mult->v); PhyML_Printf("\n. whichmodel=%d",mod->whichmodel); PhyML_Printf("\n. update_eigen=%d",mod->update_eigen); PhyML_Printf("\n. bootstrap=%d",mod->bootstrap); PhyML_Printf("\n. n_diff_rr=%d",mod->r_mat->n_diff_rr); PhyML_Printf("\n. invar=%d",mod->ras->invar); PhyML_Printf("\n. use_m4mod=%d",mod->use_m4mod); PhyML_Printf("\n. gamma_median=%d",mod->ras->gamma_median); PhyML_Printf("\n. state_len=%d",mod->io->state_len); PhyML_Printf("\n. log_l=%d",mod->log_l); PhyML_Printf("\n. l_min=%f",mod->l_min); PhyML_Printf("\n. l_max=%f",mod->l_max); PhyML_Printf("\n. free_mixt_rates=%d",mod->ras->free_mixt_rates); PhyML_Printf("\n. gamma_mgf_bl=%d",mod->gamma_mgf_bl); PhyML_Printf("\n. Pi\n"); For(i,mod->ns) PhyML_Printf(" %f ",mod->e_frq->pi->v[i]); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %f ",mod->e_frq->pi_unscaled->v[i]); PhyML_Printf("\n. Rates\n"); For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_r_proba->v[i]); PhyML_Printf("\n"); For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_r_proba_unscaled->v[i]); PhyML_Printf("\n"); For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_rr->v[i]); PhyML_Printf("\n"); For(i,mod->ras->n_catg) PhyML_Printf(" %f ",mod->ras->gamma_rr_unscaled->v[i]); PhyML_Printf("\n. Qmat \n"); if(mod->whichmodel == CUSTOM) { fflush(NULL); For(i,6) {PhyML_Printf(" %12f ",mod->r_mat->rr->v[i]); fflush(NULL);} For(i,6) {PhyML_Printf(" %12f ",mod->r_mat->rr_val->v[i]); fflush(NULL);} For(i,6) {PhyML_Printf(" %12d ",mod->r_mat->rr_num->v[i]); fflush(NULL);} For(i,6) {PhyML_Printf(" %12d ",mod->r_mat->n_rr_per_cat->v[i]); fflush(NULL);} } For(i,mod->ns) { PhyML_Printf(" "); For(j,4) PhyML_Printf("%8.5f ",mod->r_mat->qmat->v[i*4+j]); PhyML_Printf("\n"); } PhyML_Printf("\n. Freqs"); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %12f ",mod->user_b_freq->v[i]); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %12f ",mod->e_frq->pi->v[i]); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %12f ",mod->e_frq->pi_unscaled->v[i]); PhyML_Printf("\n. Eigen\n"); For(i,2*mod->ns) PhyML_Printf(" %f ",mod->eigen->space[i]); PhyML_Printf("\n"); For(i,2*mod->ns) PhyML_Printf(" %f ",mod->eigen->space_int[i]); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %f ",mod->eigen->e_val[i]); PhyML_Printf("\n"); For(i,mod->ns) PhyML_Printf(" %f ",mod->eigen->e_val_im[i]); PhyML_Printf("\n"); For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->r_e_vect[i]); PhyML_Printf("\n"); For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->r_e_vect_im[i]); PhyML_Printf("\n"); For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->l_e_vect[i]); PhyML_Printf("\n"); For(i,mod->ns*mod->ns) PhyML_Printf(" %f ",mod->eigen->q[i]); PhyML_Printf("\n"); PhyML_Printf("\n. Pij"); For(k,mod->ras->n_catg) { PMat(0.01*mod->ras->gamma_rr->v[k],mod,mod->ns*mod->ns*k,mod->Pij_rr->v); PhyML_Printf("\n. l=%f\n",0.01*mod->ras->gamma_rr->v[k]); For(i,mod->ns) { PhyML_Printf(" "); For(j,mod->ns) PhyML_Printf("%8.5f ",mod->Pij_rr->v[k*mod->ns*mod->ns+i*mod->ns+j]); PhyML_Printf("\n"); } } PhyML_Printf("\n"); fflush(NULL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Mat(matrix *mat) { int i,j; PhyML_Printf("%d",mat->n_otu); PhyML_Printf("\n"); For(i,mat->n_otu) { For(j,13) { if(j>=(int)strlen(mat->name[i])) putchar(' '); else putchar(mat->name[i][j]); } For(j,mat->n_otu) { char s[2]="-"; if(mat->dist[i][j] < .0) PhyML_Printf("%12s",s); else PhyML_Printf("%12f",mat->dist[i][j]); } PhyML_Printf("\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// FILE *Openfile(char *filename, int mode) { /* mode = 0 -> read */ /* mode = 1 -> write */ /* mode = 2 -> append */ FILE *fp; char *s; int open_test=0; /* s = (char *)mCalloc(T_MAX_FILE,sizeof(char)); */ /* strcpy(s,filename); */ s = filename; fp = NULL; switch(mode) { case 0 : { while(!(fp = (FILE *)fopen(s,"r")) && ++open_test<10) { PhyML_Printf("\n. Can't open file '%s', enter a new name : ",s); Getstring_Stdin(s); } break; } case 1 : { fp = (FILE *)fopen(s,"w"); break; } case 2 : { fp = (FILE *)fopen(s,"a"); break; } default : break; } /* Free(s); */ return fp; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Fp_Out(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option *io, int n_data_set, int num_tree, int add_citation) { char *s; div_t hour,min; int i; /* For(i,2*tree->n_otu-3) fprintf(fp_out,"\n. * Edge %3d: %f",i,tree->a_edges[i]->l); */ if((!n_data_set) || (!num_tree)) { rewind(fp_out); Print_Banner_Small(fp_out); } PhyML_Fprintf(fp_out,"\n. Sequence filename: \t\t\t%s", Basename(io->in_align_file)); PhyML_Fprintf(fp_out,"\n. Data set: \t\t\t\t#%d",n_data_set); if(io->mod->s_opt->random_input_tree) PhyML_Fprintf(fp_out,"\n. Random init tree: \t\t\t#%d",num_tree+1); else if(io->n_trees > 1) PhyML_Fprintf(fp_out,"\n. Starting tree number: \t\t#%d",num_tree+1); if(io->mod->s_opt->opt_topo) { if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tNNIs"); else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tSPRs"); else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Fprintf(fp_out,"\n. Tree topology search : \t\tBest of NNIs and SPRs"); } else { PhyML_Fprintf(fp_out,"\n. Tree topology: \t\t\tfixed"); } /* was after Sequence file ; moved here FLT */ s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); if(io->in_tree == 2) { strcat(strcat(strcat(s,"user tree ("),io->in_tree_file),")"); } else { if(!io->mod->s_opt->random_input_tree) { if(io->in_tree == 0) strcat(s,"BioNJ"); if(io->in_tree == 1) strcat(s,"parsimony"); } else { strcat(s,"random tree"); } } PhyML_Fprintf(fp_out,"\n. Initial tree: \t\t\t%s",s); Free(s); if(tree->io->datatype == NT) { PhyML_Fprintf(fp_out,"\n. Model of nucleotides substitution: \t%s",tree->mod->modelname->s); if(io->mod->whichmodel == CUSTOM) PhyML_Fprintf(fp_out," (%s)",io->mod->custom_mod_string); } else if(tree->io->datatype == AA) { PhyML_Fprintf(fp_out,"\n. Model of amino acids substitution: \t%s",tree->mod->modelname->s); if(io->mod->whichmodel == CUSTOMAA) PhyML_Fprintf(fp_out," (%s)",tree->mod->aa_rate_mat_file->s); } else { fprintf(fp_out,"\n. Substitution model: \t\t\t%s",tree->mod->modelname->s); } PhyML_Fprintf(fp_out,"\n. Number of taxa: \t\t\t%d",tree->n_otu);/*added FLT*/ PhyML_Fprintf(fp_out,"\n. Log-likelihood: \t\t\t%.5f",tree->c_lnL);/*was last ; moved here FLT*/ Unconstraint_Lk(tree); PhyML_Fprintf(fp_out,"\n. Unconstrained likelihood: \t\t%.5f",tree->unconstraint_lk); PhyML_Fprintf(fp_out,"\n. Parsimony: \t\t\t\t%d",tree->c_pars); PhyML_Fprintf(fp_out,"\n. Tree size: \t\t\t\t%.5f",Get_Tree_Size(tree)); /* if(tree->mod->ras->n_catg > 1 && tree->mod->ras->free_mixt_rates == NO) */ if(tree->mod->ras->free_mixt_rates == NO) { PhyML_Fprintf(fp_out,"\n. Discrete gamma model: \t\t%s","Yes"); PhyML_Fprintf(fp_out,"\n - Number of classes: \t\t\t%d",tree->mod->ras->n_catg); PhyML_Fprintf(fp_out,"\n - Gamma shape parameter: \t\t%.3f",tree->mod->ras->alpha->v); For(i,tree->mod->ras->n_catg) { PhyML_Fprintf(fp_out,"\n - Relative rate in class %d: \t\t%.5f [freq=%4f] \t\t",i+1,tree->mod->ras->gamma_rr->v[i],tree->mod->ras->gamma_r_proba->v[i]); } } else if(tree->mod->ras->free_mixt_rates == YES) { int *rk; rk = Ranks(tree->mod->ras->gamma_rr->v,tree->mod->ras->n_catg); PhyML_Fprintf(fp_out,"\n. FreeRate model: \t\t\t%s","Yes"); PhyML_Fprintf(fp_out,"\n - Number of classes: \t\t\t%d",tree->mod->ras->n_catg); For(i,tree->mod->ras->n_catg) { PhyML_Fprintf(fp_out,"\n - Relative rate in class %d: \t\t%.5f [freq=%4f] \t\t",i+1,tree->mod->ras->gamma_rr->v[rk[i]],tree->mod->ras->gamma_r_proba->v[rk[i]]); } Free(rk); } if(tree->mod->ras->invar) PhyML_Fprintf(fp_out,"\n. Proportion of invariant: \t\t%.3f",tree->mod->ras->pinvar->v); if(tree->mod->gamma_mgf_bl == YES) PhyML_Fprintf(fp_out,"\n. Variance of branch lengths: \t\t%f",tree->mod->l_var_sigma); /*was before Discrete gamma model ; moved here FLT*/ if((tree->mod->whichmodel == K80) || (tree->mod->whichmodel == HKY85) || (tree->mod->whichmodel == F84)) PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio: \t%.3f",tree->mod->kappa->v); else if(tree->mod->whichmodel == TN93) { PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio for purines: \t\t%.3f", tree->mod->kappa->v*2.*tree->mod->lambda->v/(1.+tree->mod->lambda->v)); PhyML_Fprintf(fp_out,"\n. Transition/transversion ratio for pyrimidines: \t%.3f", tree->mod->kappa->v*2./(1.+tree->mod->lambda->v)); } if(tree->io->datatype == NT) { PhyML_Fprintf(fp_out,"\n. Nucleotides frequencies:"); PhyML_Fprintf(fp_out,"\n - f(A)=%8.5f",tree->mod->e_frq->pi->v[0]); PhyML_Fprintf(fp_out,"\n - f(C)=%8.5f",tree->mod->e_frq->pi->v[1]); PhyML_Fprintf(fp_out,"\n - f(G)=%8.5f",tree->mod->e_frq->pi->v[2]); PhyML_Fprintf(fp_out,"\n - f(T)=%8.5f",tree->mod->e_frq->pi->v[3]); } /*****************************************/ if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) { int i,j; Update_Qmat_GTR(tree->mod->r_mat->rr->v, tree->mod->r_mat->rr_val->v, tree->mod->r_mat->rr_num->v, tree->mod->e_frq->pi->v, tree->mod->r_mat->qmat->v); PhyML_Fprintf(fp_out,"\n"); PhyML_Fprintf(fp_out,". GTR relative rate parameters : \n"); PhyML_Fprintf(fp_out," A <-> C %8.5f\n", tree->mod->r_mat->rr->v[0]); PhyML_Fprintf(fp_out," A <-> G %8.5f\n", tree->mod->r_mat->rr->v[1]); PhyML_Fprintf(fp_out," A <-> T %8.5f\n", tree->mod->r_mat->rr->v[2]); PhyML_Fprintf(fp_out," C <-> G %8.5f\n", tree->mod->r_mat->rr->v[3]); PhyML_Fprintf(fp_out," C <-> T %8.5f\n", tree->mod->r_mat->rr->v[4]); PhyML_Fprintf(fp_out," G <-> T %8.5f\n",tree->mod->r_mat->rr->v[5]); PhyML_Fprintf(fp_out,"\n. Instantaneous rate matrix : "); PhyML_Fprintf(fp_out,"\n [A---------C---------G---------T------]\n"); For(i,4) { PhyML_Fprintf(fp_out," "); For(j,4) PhyML_Fprintf(fp_out,"%8.5f ",tree->mod->r_mat->qmat->v[i*4+j]); PhyML_Fprintf(fp_out,"\n"); } PhyML_Fprintf(fp_out,"\n"); } /*****************************************/ if(io->ratio_test == 1) { PhyML_Fprintf(fp_out,". aLRT statistics to test branches"); } else if(io->ratio_test == 2) { PhyML_Fprintf(fp_out,". aLRT branch supports (cubic approximation, mixture of Chi2s distribution)"); } PhyML_Fprintf(fp_out,"\n"); PhyML_Fprintf(fp_out,"\n. Run ID:\t\t\t\t%s", (io->append_run_ID) ? (io->run_id_string): ("none")); PhyML_Fprintf(fp_out,"\n. Random seed:\t\t\t\t%d", io->r_seed); PhyML_Fprintf(fp_out,"\n. Subtree patterns aliasing:\t\t%s",io->do_alias_subpatt?"yes":"no"); PhyML_Fprintf(fp_out,"\n. Version:\t\t\t\t%s", VERSION); hour = div(t_end-t_beg,3600); min = div(t_end-t_beg,60 ); min.quot -= hour.quot*60; PhyML_Fprintf(fp_out,"\n. Time used:\t\t\t\t%dh%dm%ds (%d seconds)", hour.quot,min.quot,(int)(t_end-t_beg)%60,(int)(t_end-t_beg)); if(add_citation == YES) { PhyML_Fprintf(fp_out,"\n\n"); PhyML_Fprintf(fp_out," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); PhyML_Fprintf(fp_out," Suggested citations:\n"); PhyML_Fprintf(fp_out," S. Guindon, JF. Dufayard, V. Lefort, M. Anisimova, W. Hordijk, O. Gascuel\n"); PhyML_Fprintf(fp_out," \"New algorithms and methods to estimate maximum-likelihood phylogenies: assessing the performance of PhyML 3.0.\"\n"); PhyML_Fprintf(fp_out," Systematic Biology. 2010. 59(3):307-321.\n"); PhyML_Fprintf(fp_out,"\n"); PhyML_Fprintf(fp_out," S. Guindon & O. Gascuel\n"); PhyML_Fprintf(fp_out," \"A simple, fast, and accurate algorithm to estimate large phylogenies by maximum likelihood\"\n"); PhyML_Fprintf(fp_out," Systematic Biology. 2003. 52(5):696-704.\n"); PhyML_Fprintf(fp_out," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); } else { PhyML_Fprintf(fp_out,"\n\n"); PhyML_Fprintf(fp_out," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); PhyML_Fprintf(fp_out,"\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*FLT wrote this function*/ void Print_Fp_Out_Lines(FILE *fp_out, time_t t_beg, time_t t_end, t_tree *tree, option *io, int n_data_set) { char *s; /*div_t hour,min;*/ if (n_data_set==1) { PhyML_Fprintf(fp_out,". Sequence file : [%s]\n\n", Basename(io->in_align_file)); if((tree->io->datatype == NT) || (tree->io->datatype == AA)) { (tree->io->datatype == NT)? (PhyML_Fprintf(fp_out,". Model of nucleotides substitution : %s\n\n",io->mod->modelname->s)): (PhyML_Fprintf(fp_out,". Model of amino acids substitution : %s\n\n",io->mod->modelname->s)); } s = (char *)mCalloc(100,sizeof(char)); switch(io->in_tree) { case 0: { strcpy(s,"BioNJ"); break; } case 1: { strcpy(s,"parsimony"); break; } case 2: { strcpy(s,"user tree ("); strcat(s,io->in_tree_file); strcat(s,")"); break; } } PhyML_Fprintf(fp_out,". Initial tree : [%s]\n\n",s); Free(s); PhyML_Fprintf(fp_out,"\n"); /*headline 1*/ PhyML_Fprintf(fp_out, ". Data\t"); PhyML_Fprintf(fp_out,"Nb of \t"); PhyML_Fprintf(fp_out,"Likelihood\t"); PhyML_Fprintf(fp_out, "Discrete \t"); if(tree->mod->ras->n_catg > 1) PhyML_Fprintf(fp_out, "Number of \tGamma shape\t"); PhyML_Fprintf(fp_out,"Proportion of\t"); if(tree->mod->whichmodel <= 6) PhyML_Fprintf(fp_out,"Transition/ \t"); PhyML_Fprintf(fp_out,"Nucleotides frequencies \t"); if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) PhyML_Fprintf(fp_out,"Instantaneous rate matrix \t"); /* PhyML_Fprintf(fp_out,"Time\t");*/ PhyML_Fprintf(fp_out, "\n"); /*headline 2*/ PhyML_Fprintf(fp_out, " set\t"); PhyML_Fprintf(fp_out,"taxa\t"); PhyML_Fprintf(fp_out,"loglk \t"); PhyML_Fprintf(fp_out, "gamma model\t"); if(tree->mod->ras->n_catg > 1) PhyML_Fprintf(fp_out, "categories\tparameter \t"); PhyML_Fprintf(fp_out,"invariant \t"); if(tree->mod->whichmodel <= 6) PhyML_Fprintf(fp_out,"transversion\t"); PhyML_Fprintf(fp_out,"f(A) f(C) f(G) f(T) \t"); if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) PhyML_Fprintf(fp_out,"[A---------C---------G---------T------]\t"); /* PhyML_PhyML_Fprintf(fp_out,"used\t");*/ PhyML_Fprintf(fp_out, "\n"); /*headline 3*/ if(tree->mod->whichmodel == TN93) { PhyML_Fprintf(fp_out," \t \t \t \t"); if(tree->mod->ras->n_catg > 1) PhyML_Fprintf(fp_out," \t \t"); PhyML_Fprintf(fp_out," \t"); PhyML_Fprintf(fp_out,"purines pyrimid.\t"); PhyML_Fprintf(fp_out, "\n"); } PhyML_Fprintf(fp_out, "\n"); } /*line items*/ PhyML_Fprintf(fp_out," #%d\t",n_data_set); PhyML_Fprintf(fp_out,"%d \t",tree->n_otu); PhyML_Fprintf(fp_out,"%.5f\t",tree->c_lnL); PhyML_Fprintf(fp_out,"%s \t", (tree->mod->ras->n_catg>1)?("Yes"):("No ")); if(tree->mod->ras->n_catg > 1) { PhyML_Fprintf(fp_out,"%d \t",tree->mod->ras->n_catg); PhyML_Fprintf(fp_out,"%.3f \t",tree->mod->ras->alpha->v); } /*if(tree->mod->ras->invar)*/ PhyML_Fprintf(fp_out,"%.3f \t",tree->mod->ras->pinvar->v); if(tree->mod->whichmodel <= 5) { PhyML_Fprintf(fp_out,"%.3f \t",tree->mod->kappa->v); } else if(tree->mod->whichmodel == TN93) { PhyML_Fprintf(fp_out,"%.3f ", tree->mod->kappa->v*2.*tree->mod->lambda->v/(1.+tree->mod->lambda->v)); PhyML_Fprintf(fp_out,"%.3f\t", tree->mod->kappa->v*2./(1.+tree->mod->lambda->v)); } if(tree->io->datatype == NT) { PhyML_Fprintf(fp_out,"%8.5f ",tree->mod->e_frq->pi->v[0]); PhyML_Fprintf(fp_out,"%8.5f ",tree->mod->e_frq->pi->v[1]); PhyML_Fprintf(fp_out,"%8.5f ",tree->mod->e_frq->pi->v[2]); PhyML_Fprintf(fp_out,"%8.5f\t",tree->mod->e_frq->pi->v[3]); } /* hour = div(t_end-t_beg,3600); min = div(t_end-t_beg,60 ); min.quot -= hour.quot*60; PhyML_Fprintf(fp_out,"%dh%dm%ds\t", hour.quot,min.quot,(int)(t_end-t_beg)%60); if(t_end-t_beg > 60) PhyML_Fprintf(fp_out,". -> %d seconds\t",(int)(t_end-t_beg)); */ /*****************************************/ if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) { int i,j; For(i,4) { if (i!=0) { /*format*/ PhyML_Fprintf(fp_out," \t \t \t \t"); if(tree->mod->ras->n_catg > 1) PhyML_Fprintf(fp_out," \t \t"); PhyML_Fprintf(fp_out," \t \t"); } For(j,4) PhyML_Fprintf(fp_out,"%8.5f ",tree->mod->r_mat->qmat->v[i*4+j]); if (i<3) PhyML_Fprintf(fp_out,"\n"); } } /*****************************************/ PhyML_Fprintf(fp_out, "\n\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Freq(t_tree *tree) { switch(tree->io->datatype) { case NT: { PhyML_Printf("A : %f\n",tree->mod->e_frq->pi->v[0]); PhyML_Printf("C : %f\n",tree->mod->e_frq->pi->v[1]); PhyML_Printf("G : %f\n",tree->mod->e_frq->pi->v[2]); PhyML_Printf("T : %f\n",tree->mod->e_frq->pi->v[3]); /* PhyML_Printf("U : %f\n",tree->mod->e_frq->pi->v[4]); */ /* PhyML_Printf("M : %f\n",tree->mod->e_frq->pi->v[5]); */ /* PhyML_Printf("R : %f\n",tree->mod->e_frq->pi->v[6]); */ /* PhyML_Printf("W : %f\n",tree->mod->e_frq->pi->v[7]); */ /* PhyML_Printf("S : %f\n",tree->mod->e_frq->pi->v[8]); */ /* PhyML_Printf("Y : %f\n",tree->mod->e_frq->pi->v[9]); */ /* PhyML_Printf("K : %f\n",tree->mod->e_frq->pi->v[10]); */ /* PhyML_Printf("B : %f\n",tree->mod->e_frq->pi->v[11]); */ /* PhyML_Printf("D : %f\n",tree->mod->e_frq->pi->v[12]); */ /* PhyML_Printf("H : %f\n",tree->mod->e_frq->pi->v[13]); */ /* PhyML_Printf("V : %f\n",tree->mod->e_frq->pi->v[14]); */ /* PhyML_Printf("N : %f\n",tree->mod->e_frq->pi->v[15]); */ break; } case AA: { PhyML_Printf("A : %f\n",tree->mod->e_frq->pi->v[0]); PhyML_Printf("R : %f\n",tree->mod->e_frq->pi->v[1]); PhyML_Printf("N : %f\n",tree->mod->e_frq->pi->v[2]); PhyML_Printf("D : %f\n",tree->mod->e_frq->pi->v[3]); PhyML_Printf("C : %f\n",tree->mod->e_frq->pi->v[4]); PhyML_Printf("Q : %f\n",tree->mod->e_frq->pi->v[5]); PhyML_Printf("E : %f\n",tree->mod->e_frq->pi->v[6]); PhyML_Printf("G : %f\n",tree->mod->e_frq->pi->v[7]); PhyML_Printf("H : %f\n",tree->mod->e_frq->pi->v[8]); PhyML_Printf("I : %f\n",tree->mod->e_frq->pi->v[9]); PhyML_Printf("L : %f\n",tree->mod->e_frq->pi->v[10]); PhyML_Printf("K : %f\n",tree->mod->e_frq->pi->v[11]); PhyML_Printf("M : %f\n",tree->mod->e_frq->pi->v[12]); PhyML_Printf("F : %f\n",tree->mod->e_frq->pi->v[13]); PhyML_Printf("P : %f\n",tree->mod->e_frq->pi->v[14]); PhyML_Printf("S : %f\n",tree->mod->e_frq->pi->v[15]); PhyML_Printf("T : %f\n",tree->mod->e_frq->pi->v[16]); PhyML_Printf("W : %f\n",tree->mod->e_frq->pi->v[17]); PhyML_Printf("Y : %f\n",tree->mod->e_frq->pi->v[18]); PhyML_Printf("V : %f\n",tree->mod->e_frq->pi->v[19]); PhyML_Printf("N : %f\n",tree->mod->e_frq->pi->v[20]); break; } default : {break;} } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Settings(option *io) { int answer; char *s; s = (char *)mCalloc(100,sizeof(char)); PhyML_Printf("\n\n\n"); PhyML_Printf("\n\n"); PhyML_Printf(" .......................... \n"); PhyML_Printf(" ooooooooooooooooooooooooooooo CURRENT SETTINGS ooooooooooooooooooooooooooooooooooo\n"); PhyML_Printf(" .......................... \n"); PhyML_Printf("\n . Sequence filename:\t\t\t\t %s", Basename(io->in_align_file)); if(io->datatype == NT) strcpy(s,"dna"); else if(io->datatype == AA) strcpy(s,"aa"); else strcpy(s,"generic"); PhyML_Printf("\n . Data type:\t\t\t\t\t %s",s); PhyML_Printf("\n . Alphabet size:\t\t\t\t %d",io->mod->ns); PhyML_Printf("\n . Sequence format:\t\t\t\t %s", io->interleaved ? "interleaved": "sequential"); PhyML_Printf("\n . Number of data sets:\t\t\t\t %d", io->n_data_sets); PhyML_Printf("\n . Nb of bootstrapped data sets:\t\t\t %d", io->mod->bootstrap); if (io->mod->bootstrap > 0) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t no"); else { if(io->ratio_test == 1) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t yes (aLRT statistics)"); else if(io->ratio_test == 2) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t yes (Chi2-based parametric branch supports)"); else if(io->ratio_test == 3) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t yes (Minimum of SH-like and Chi2-based branch supports)"); else if(io->ratio_test == 4) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t yes (SH-like branch supports)"); else if(io->ratio_test == 5) PhyML_Printf("\n . Compute approximate likelihood ratio test:\t yes (aBayes branch supports)"); } PhyML_Printf("\n . Model name:\t\t\t\t\t %s", io->mod->modelname->s); if(io->datatype == AA && io->mod->whichmodel == CUSTOMAA) PhyML_Printf(" (%s)",io->mod->aa_rate_mat_file->s); if (io->datatype == NT) { if ((io->mod->whichmodel == K80) || (io->mod->whichmodel == HKY85)|| (io->mod->whichmodel == F84) || (io->mod->whichmodel == TN93)) { if(io->mod->s_opt && io->mod->s_opt->opt_kappa) PhyML_Printf("\n . Ts/tv ratio:\t\t\t\t\t estimated"); else PhyML_Printf("\n . Ts/tv ratio:\t\t\t\t\t %f", io->mod->kappa->v); } } if(io->mod->s_opt && io->mod->s_opt->opt_pinvar) PhyML_Printf("\n . Proportion of invariable sites:\t\t estimated"); else PhyML_Printf("\n . Proportion of invariable sites:\t\t %f", io->mod->ras->pinvar->v); PhyML_Printf("\n . Number of subst. rate categs:\t\t\t %d", io->mod->ras->n_catg); if(io->mod->ras->n_catg > 1) { if(io->mod->ras->free_mixt_rates == NO) { if(io->mod->s_opt && io->mod->s_opt->opt_alpha) PhyML_Printf("\n . Gamma distribution parameter:\t\t\t estimated"); else PhyML_Printf("\n . Gamma distribution parameter:\t\t\t %f", io->mod->ras->alpha->v); PhyML_Printf("\n . 'Middle' of each rate class:\t\t\t %s",(io->mod->ras->gamma_median)?("median"):("mean")); } } if(io->datatype == AA) PhyML_Printf("\n . Amino acid equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("empirical"):("model")); else if(io->datatype == NT) { if((io->mod->whichmodel != JC69) && (io->mod->whichmodel != K80) && (io->mod->whichmodel != F81)) { if(io->mod->s_opt && !io->mod->s_opt->user_state_freq) { PhyML_Printf("\n . Nucleotide equilibrium frequencies:\t\t %s", (io->mod->s_opt->opt_state_freq) ? ("ML"):("empirical")); } else { PhyML_Printf("\n . Nucleotide equilibrium frequencies:\t\t %s","user-defined"); } } } PhyML_Printf("\n . Optimise tree topology:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_topo) ? "yes": "no"); switch(io->in_tree) { case 0: { strcpy(s,"BioNJ"); break; } case 1: { strcpy(s,"parsimony"); break; } case 2: { strcpy(s,"user tree ("); strcat(s,Basename(io->in_tree_file)); strcat(s,")"); break; } } if(io->mod->s_opt && io->mod->s_opt->opt_topo) { if(io->mod->s_opt->topo_search == NNI_MOVE) PhyML_Printf("\n . Tree topology search:\t\t\t\t NNIs"); else if(io->mod->s_opt->topo_search == SPR_MOVE) PhyML_Printf("\n . Tree topology search:\t\t\t\t SPRs"); else if(io->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR) PhyML_Printf("\n . Tree topology search:\t\t\t\t Best of NNIs and SPRs"); PhyML_Printf("\n . Starting tree:\t\t\t\t %s",s); PhyML_Printf("\n . Add random input tree:\t\t\t %s", (io->mod->s_opt->random_input_tree) ? "yes": "no"); if(io->mod->s_opt->random_input_tree) PhyML_Printf("\n . Number of random starting trees:\t\t %d", io->mod->s_opt->n_rand_starts); } else if(io->mod->s_opt && !io->mod->s_opt->random_input_tree) PhyML_Printf("\n . Evaluated tree:\t\t\t\t \"%s\"",s); PhyML_Printf("\n . Optimise branch lengths:\t\t\t %s", (io->mod->s_opt && io->mod->s_opt->opt_bl) ? "yes": "no"); answer = 0; if(io->mod->s_opt && (io->mod->s_opt->opt_alpha || io->mod->s_opt->opt_kappa || io->mod->s_opt->opt_lambda || io->mod->s_opt->opt_pinvar || io->mod->s_opt->opt_rr)) answer = 1; PhyML_Printf("\n . Optimise substitution model parameters:\t %s", (answer) ? "yes": "no"); PhyML_Printf("\n . Run ID:\t\t\t\t\t %s", (io->append_run_ID) ? (io->run_id_string): ("none")); PhyML_Printf("\n . Random seed:\t\t\t\t\t %d", io->r_seed); PhyML_Printf("\n . Subtree patterns aliasing:\t\t\t %s",io->do_alias_subpatt?"yes":"no"); PhyML_Printf("\n . Version:\t\t\t\t\t %s", VERSION); PhyML_Printf("\n\n oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); PhyML_Printf("\n\n"); fflush(NULL); Free(s); } void Print_Banner(FILE *fp) { PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," --- PhyML %s --- \n",VERSION); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," A simple, fast, and accurate algorithm to estimate large phylogenies by maximum likelihood \n"); PhyML_Fprintf(fp," Stephane Guindon & Olivier Gascuel \n"); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," http://www.atgc-montpellier.fr/phyml \n"); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," Copyright CNRS - Universite Montpellier II \n"); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Banner_Small(FILE *fp) { PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); PhyML_Fprintf(fp," --- PhyML %s --- \n",VERSION); PhyML_Fprintf(fp," http://www.atgc-montpellier.fr/phyml \n"); PhyML_Fprintf(fp," Copyright CNRS - Universite Montpellier II \n"); PhyML_Fprintf(fp," oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Data_Set_Number(option *io, FILE *fp) { PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp," \n"); PhyML_Fprintf(fp," [ Data set number %3d ] \n",io->curr_gt+1); PhyML_Fprintf(fp," \n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Lk(t_tree *tree, char *string) { t_tree *loc_tree; loc_tree = tree; /*! Rewind back to the first mixt_tree */ while(loc_tree->prev) loc_tree = loc_tree->prev; time(&(loc_tree->t_current)); PhyML_Printf("\n. (%5d sec) [%15.4f] %s", (int)(loc_tree->t_current-loc_tree->t_beg),loc_tree->c_lnL, string); #ifndef QUIET fflush(NULL); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Pars(t_tree *tree) { time(&(tree->t_current)); PhyML_Printf("\n. (%5d sec) [%5d]",(int)(tree->t_current-tree->t_beg),tree->c_pars); #ifndef QUIET fflush(NULL); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Lk_And_Pars(t_tree *tree) { time(&(tree->t_current)); PhyML_Printf("\n. (%5d sec) [%15.4f] [%5d]", (int)(tree->t_current-tree->t_beg), tree->c_lnL,tree->c_pars); #ifndef QUIET fflush(NULL); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Qmat(phydbl *daa, phydbl *pi, FILE *fp) { int i,j; phydbl sum; double val; assert(fp); rewind(fp); for(i=1;i<20;i++) { For(j,19) { /* if(!fscanf(fp,"%lf",&(daa[i*20+j]))) Exit("\n"); */ if(!fscanf(fp,"%lf",&val)) { PhyML_Printf("\n== Rate matrix file does not appear to have a proper format. Please refer to the documentation."); Exit("\n"); } daa[i*20+j] = (phydbl)val; daa[j*20+i] = daa[i*20+j]; if(j == i-1) break; } } For(i,20) { if(!fscanf(fp,"%lf",&val)) Exit("\n"); pi[i] = (phydbl)val; } sum = .0; For(i,20) sum += pi[i]; if(FABS(sum - 1.) > 1.E-06) { PhyML_Printf("\n. Sum of amino-acid frequencies: %f",sum); PhyML_Printf("\n. Scaling amino-acid frequencies...\n"); For(i,20) pi[i] /= sum; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Qmat_AA(phydbl *daa, phydbl *pi) { int i,j,cpt; cpt = 0; For(i,20) { for(j=0;ja_nodes[0], tree->a_nodes[0]->v[0], tree->a_nodes[0]->b[0], fp, tree); /* mean_div_left = .0; */ /* For(k,ns) */ /* { */ /* mean_div_left += (k+1) * tree->a_edges[j]->div_post_pred_left[k]; */ /* } */ /* mean_div_rght = .0; */ /* For(k,ns) mean_div_rght += (k+1) * tree->a_edges[j]->div_post_pred_rght[k]; */ /* mean_div_left /= (phydbl)tree->data->init_len; */ /* mean_div_rght /= (phydbl)tree->data->init_len; */ /* PhyML_Fprintf(fp,"%4d 0 %f\n",j,mean_div_left); */ /* PhyML_Fprintf(fp,"%4d 1 %f\n",j,mean_div_rght); */ /* mean_div_left = .0; */ /* For(k,ns) mean_div_left += tree->a_edges[j]->div_post_pred_left[k]; */ /* mean_div_rght = .0; */ /* For(k,ns) */ /* { */ /* mean_div_rght += tree->a_edges[j]->div_post_pred_rght[k]; */ /* } */ /* if((mean_div_left != tree->data->init_len) || (mean_div_rght != tree->data->init_len)) */ /* { */ /* PhyML_Printf("\n. mean_div_left = %f mean_div_rght = %f init_len = %d", */ /* mean_div_left,mean_div_rght,tree->data->init_len); */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Diversity_Pre(t_node *a, t_node *d, t_edge *b, FILE *fp, t_tree *tree) { int k,ns; ns = -1; if(d->tax) return; else { if(tree->io->datatype == NT) ns = 4; else if(tree->io->datatype == AA) ns = 20; if(d == b->left) For(k,ns) PhyML_Fprintf(fp,"%4d 0 %2d %4d\n",b->num,k,b->div_post_pred_left[k]); else For(k,ns) PhyML_Fprintf(fp,"%4d 1 %2d %4d\n",b->num,k,b->div_post_pred_rght[k]); For(k,3) if(d->v[k] != a) Print_Diversity_Pre(d,d->v[k],d->b[k],fp,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Tip_Partials(t_tree* tree, t_node* d) { if(!d->tax) { fprintf(stdout,"Node %d is not a Taxa\n",d->num);fflush(stdout); return; } assert(d->b[0]->rght == d); assert(d->b[0]->rght->tax); fprintf(stdout,"Taxa/Node %d\n",d->num); int site, i; for(site=0;siten_pattern;++site) { fprintf(stdout,"[%d: ",site); for(i=0;imod->ns;++i) { int tip_partial = d->b[0]->p_lk_tip_r[site*tree->mod->ns + i]; fprintf(stdout,"%d",tip_partial);fflush(stdout); } fprintf(stdout,"] ");fflush(stdout); } fprintf(stdout,"\n");fflush(stdout); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Edge_PMats(t_tree* tree, t_edge* b) { phydbl *Pij; #ifdef BEAGLE Pij = (phydbl*)malloc(tree->mod->ns * tree->mod->ns * tree->mod->ras->n_catg * sizeof(phydbl)); if (NULL==Pij) Warn_And_Exit(__PRETTY_FUNCTION__); int ret = beagleGetTransitionMatrix(tree->b_inst, b->Pij_rr_idx, Pij); if(ret<0){ fprintf(stderr, "beagleGetTransitionMatrix() on instance %i failed:%i\n\n",tree->b_inst,ret); Free(Pij); Exit(""); } #else Pij = b->Pij_rr; #endif fprintf(stdout,"\nflattened P-Matrices (for each rate category) state*state*num_rates[%d*%d*%d] for branch num:%i\n",tree->mod->ns,tree->mod->ns,tree->mod->ras->n_catg, b->num); int i; for(i=0;imod->ns * tree->mod->ns * tree->mod->ras->n_catg;++i){ fprintf(stdout,"%f,",Pij[i]); fflush(stdout); } fprintf(stdout,"\n"); fflush(stdout); #ifdef BEAGLE Free(Pij); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_All_Edge_PMats(t_tree* tree) { int i; for(i=0;i < 2*tree->n_otu-3;++i) Print_Edge_PMats(tree, tree->a_edges[i]); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Edge_Likelihoods(t_tree* tree, t_edge* b, bool scientific/*Print in scientific notation?*/) { int catg, site, j; char* fmt = scientific ? "[%d,%d,%d]%e ":"[%d,%d,%d]%f "; //rate category, site, state, likelihood phydbl* lk_left = b->p_lk_left; phydbl* lk_right = b->p_lk_rght; fprintf(stdout,"\n");fflush(stdout); if(NULL!=lk_left)//not a tip? { fprintf(stdout,"Partial Likelihoods on LEFT subtree of Branch %d [rate,site,state]:\n",b->num); for(catg=0;catgmod->ras->n_catg;++catg) for(site=0;siten_pattern;++site) for(j=0;jmod->ns;++j) #ifdef BEAGLE fprintf(stdout,fmt,catg,site,j,lk_left[catg*tree->n_pattern*tree->mod->ns + site*tree->mod->ns + j]); #else fprintf(stdout,fmt,catg,site,j,lk_left[catg*tree->mod->ns + site*tree->mod->ras->n_catg*tree->mod->ns + j]); #endif fflush(stdout); } else //is a tip { fprintf(stdout,"Likelihoods on LEFT tip of Branch %d [site,state]:\n",b->num); for(site=0;siten_pattern;++site) for(j=0;jmod->ns;++j) fprintf(stdout,"[%d,%d]%d ",site,j,b->p_lk_tip_l[site*tree->mod->ns + j]); fflush(stdout); } fprintf(stdout,"\n");fflush(stdout); if(NULL!=lk_right)//not a tip? { fprintf(stdout,"Partial Likelihoods on RIGHT subtree of Branch %d [rate,site,state]:\n",b->num); for(catg=0;catgmod->ras->n_catg;++catg) for(site=0;siten_pattern;++site) for(j=0;jmod->ns;++j) #ifdef BEAGLE fprintf(stdout,fmt,catg,site,j,lk_right[catg*tree->n_pattern*tree->mod->ns + site*tree->mod->ns + j]); #else fprintf(stdout,fmt,catg,site,j,lk_right[catg*tree->mod->ns + site*tree->mod->ras->n_catg*tree->mod->ns + j]); #endif fflush(stdout); } else //is a tip { fprintf(stdout,"Likelihoods on RIGHT tip of Branch %d [site,state]:\n",b->num); for(site=0;siten_pattern;++site) for(j=0;jmod->ns;++j) fprintf(stdout,"[%d,%d]%d ",site,j,b->p_lk_tip_r[site*tree->mod->ns + j]); fflush(stdout); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_All_Edge_Likelihoods(t_tree* tree) { int i; for(i=0;i < 2*tree->n_otu-3; ++i) Print_Edge_Likelihoods(tree, tree->a_edges[i],false); fflush(NULL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Dump_Arr_S(short int* arr, int num) { int i; if(NULL==arr) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n== Trying to print NULL array"); return; } fprintf(stdout,"["); for(i=0;in_otu-3; ++i) { fprintf(stdout,"Edge %d, LeftNode %d, RightNode %d\n",tree->a_edges[i]->num,tree->a_edges[i]->left->num,tree->a_edges[i]->rght->num);fflush(stdout); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Read_User_Tree(calign *cdata, t_mod *mod, option *io) { t_tree *tree; PhyML_Printf("\n. Reading tree..."); fflush(NULL); if(io->n_trees == 1) rewind(io->fp_in_tree); tree = Read_Tree_File_Phylip(io->fp_in_tree); if(!tree) Exit("\n== Input tree not found..."); /* Add branch lengths if necessary */ if(!tree->has_branch_lengths) Add_BioNJ_Branch_Lengths(tree,cdata,mod); return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Time_Info(time_t t_beg, time_t t_end) { div_t hour,min; hour = div(t_end-t_beg,3600); min = div(t_end-t_beg,60 ); min.quot -= hour.quot*60; PhyML_Printf("\n\n. Time used %dh%dm%ds\n", hour.quot,min.quot,(int)(t_end-t_beg)%60); PhyML_Printf("\noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PhyML_Printf(char *format, ...) { va_list ptr; #ifdef MPI if(Global_myRank == 0) { va_start (ptr, format); vprintf (format, ptr); va_end(ptr); } #else va_start (ptr, format); vprintf (format, ptr); va_end(ptr); #endif /* fflush (NULL); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PhyML_Fprintf(FILE *fp, char *format, ...) { va_list ptr; #ifdef MPI if(Global_myRank == 0) { va_start (ptr, format); vfprintf (fp,format, ptr); va_end(ptr); } #else va_start (ptr, format); vfprintf (fp,format, ptr); va_end(ptr); #endif /* fflush (NULL); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Read_Clade_Priors(char *file_name, t_tree *tree) { FILE *fp; char *s,*line; int n_clade_priors; int clade_size; char **clade_list; int i,pos; phydbl prior_low,prior_up; int node_num; PhyML_Printf("\n"); PhyML_Printf("\n. Reading prior on node ages.\n"); line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); clade_list = (char **)mCalloc(tree->n_otu,sizeof(char *)); For(i,tree->n_otu) clade_list[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); fp = Openfile(file_name,0); n_clade_priors = 0; do { if(!fgets(line,T_MAX_LINE,fp)) break; clade_size = 0; pos = 0; do { i = 0; while(line[pos] == ' ') pos++; while((line[pos] != ' ') && (line[pos] != '\n') && line[pos] != '#') { s[i] = line[pos]; i++; pos++; } s[i] = '\0'; /* PhyML_Printf("\n. s = %s\n",s); */ if(line[pos] == '\n' || line[pos] == '#') break; pos++; if(strcmp(s,"|")) { strcpy(clade_list[clade_size],s); clade_size++; } else break; } while(1); if(line[pos] != '#' && line[pos] != '\n') { phydbl val1, val2; /* sscanf(line+pos,"%lf %lf",&prior_up,&prior_low); */ sscanf(line+pos,"%lf %lf",&val1,&val2); prior_up = (phydbl)val1; prior_low = (phydbl)val2; node_num = -1; if(!strcmp("@root@",clade_list[0])) node_num = tree->n_root->num; else node_num = Find_Clade(clade_list, clade_size, tree); n_clade_priors++; if(node_num < 0) { PhyML_Printf("\n"); PhyML_Printf("\n"); PhyML_Printf("\n. ................................................................."); PhyML_Printf("\n. WARNING: could not find any clade in the tree referred to with the following taxon names:"); For(i,clade_size) PhyML_Printf("\n. \"%s\"",clade_list[i]); PhyML_Printf("\n. ................................................................."); /* sleep(3); */ } else { tree->rates->t_has_prior[node_num] = YES; tree->rates->t_prior_min[node_num] = MIN(prior_low,prior_up); tree->rates->t_prior_max[node_num] = MAX(prior_low,prior_up); /* Sergei to add stuff here re calibration object */ if(FABS(prior_low - prior_up) < 1.E-6 && tree->a_nodes[node_num]->tax == YES) tree->rates->nd_t[node_num] = prior_low; PhyML_Printf("\n"); PhyML_Printf("\n. [%3d]..................................................................",n_clade_priors); PhyML_Printf("\n. Node %4d matches the clade referred to with the following taxon names:",node_num); For(i,clade_size) PhyML_Printf("\n. - \"%s\"",clade_list[i]); PhyML_Printf("\n. Lower bound set to: %15f time units.",MIN(prior_low,prior_up)); PhyML_Printf("\n. Upper bound set to: %15f time units.",MAX(prior_low,prior_up)); PhyML_Printf("\n. ......................................................................."); } } } while(1); PhyML_Printf("\n. Read prior information on %d %s.",n_clade_priors,n_clade_priors > 1 ? "clades":"clade"); if(!n_clade_priors) { PhyML_Printf("\n== PhyTime could not find any prior on node age."); PhyML_Printf("\n== This is likely due to a problem in the calibration "); PhyML_Printf("\n== file format. Make sure, for instance, that there is "); PhyML_Printf("\n== a blank character between the end of the last name"); PhyML_Printf("\n== of each clade and the character `|'. Otherwise, "); PhyML_Printf("\n== please refer to the example file.\n"); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } For(i,tree->n_otu) Free(clade_list[i]); Free(clade_list); Free(line); Free(s); fclose(fp); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// option *Get_Input(int argc, char **argv) { option *io; t_mod *mod; t_opt *s_opt; m4 *m4mod; int rv; rv = 1; io = (option *)Make_Input(); mod = (t_mod *)Make_Model_Basic(); s_opt = (t_opt *)Make_Optimiz(); m4mod = (m4 *)M4_Make_Light(); Set_Defaults_Input(io); Set_Defaults_Model(mod); Set_Defaults_Optimiz(s_opt); io->mod = mod; io->mod->m4mod = m4mod; mod->io = io; mod->s_opt = s_opt; #ifdef MPI rv = Read_Command_Line(io,argc,argv); #elif (defined PHYTIME || defined INVITEE) rv = Read_Command_Line(io,argc,argv); #else putchar('\n'); switch (argc) { case 1: { Launch_Interface(io); break; } default: { rv = Read_Command_Line(io,argc,argv); } } #endif if(rv) return io; else return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Set_Whichmodel(int select) { int wm; wm = -1; switch(select) { case 1: { wm = JC69; break; } case 2: { wm = K80; break; } case 3: { wm = F81; break; } case 4: { wm = HKY85; break; } case 5: { wm = F84; break; } case 6: { wm = TN93; break; } case 7: { wm = GTR; break; } case 8: { wm = CUSTOM; break; } case 11: { wm = WAG; break; } case 12: { wm = DAYHOFF; break; } case 13: { wm = JTT; break; } case 14: { wm = BLOSUM62; break; } case 15: { wm = MTREV; break; } case 16: { wm = RTREV; break; } case 17: { wm = CPREV; break; } case 18: { wm = DCMUT; break; } case 19: { wm = VT; break; } case 20: { wm = MTMAM; break; } case 21: { wm = MTART; break; } case 22: { wm = HIVW; break; } case 23: { wm = HIVB; break; } case 24: { wm = FLU; break; } case 25: { wm = CUSTOMAA; break; } case 26: { wm = LG; break; } case 27: { wm = AB; break; } default: { PhyML_Printf("\n== Model number %d is unknown. Please use a valid model name",select); Exit("\n"); break; } } return wm; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Data_Structure(int final, FILE *fp, t_tree *mixt_tree) { int n_partition_elem; char *s; t_tree *tree,*cpy_mixt_tree; int c,cc,cc_efrq,cc_rmat,cc_lens; char *param; int *link_efrq,*link_rmat,*link_lens; phydbl r_mat_weight_sum, e_frq_weight_sum; PhyML_Fprintf(fp,"\n. Starting tree: %s", mixt_tree->io->in_tree == 2?mixt_tree->io->in_tree_file:"BioNJ"); PhyML_Fprintf(fp,"\n. Tree topology search: %s", mixt_tree->io->mod->s_opt->opt_topo==YES? mixt_tree->io->mod->s_opt->topo_search==SPR_MOVE?"spr": mixt_tree->io->mod->s_opt->topo_search==NNI_MOVE?"nni": "spr+nni":"no"); cpy_mixt_tree = mixt_tree; n_partition_elem = 1; tree = mixt_tree; do { tree = tree->next_mixt; if(!tree) break; n_partition_elem++; } while(1); s = (char *)mCalloc(2,sizeof(char)); s[0] = ' '; s[1] = '\0'; tree = mixt_tree; do { s = (char *)mRealloc(s,(int)(strlen(s)+strlen(tree->io->in_align_file)+2+2),sizeof(char)); strcat(s,tree->io->in_align_file); strcat(s,", "); tree = tree->next_mixt; if(!tree) break; } while(1); s[(int)strlen(s)-2]=' '; s[(int)strlen(s)-1]='\0'; if(final == NO) PhyML_Fprintf(fp,"\n. Processing %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s); if(final == YES) PhyML_Fprintf(fp,"\n. Processed %d data %s (%s)",n_partition_elem,n_partition_elem>1?"sets":"set",s); Free(s); if(final == YES) PhyML_Fprintf(fp,"\n. Final log-likelihood: %f",mixt_tree->c_lnL); r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight); e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight); do { int class = 0; PhyML_Fprintf(fp,"\n\n"); PhyML_Fprintf(fp,"\n _______________________________________________________________________ "); PhyML_Fprintf(fp,"\n| |"); PhyML_Fprintf(fp,"\n| %40s (partition element %2d) |",mixt_tree->io->in_align_file,mixt_tree->dp); PhyML_Fprintf(fp,"\n|_______________________________________________________________________|"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n. Number of rate classes:\t\t%12d",mixt_tree->mod->ras->n_catg+(mixt_tree->mod->ras->invar ?1:0)); if(mixt_tree->mod->ras->n_catg > 1) { PhyML_Fprintf(fp,"\n. Model of rate variation:\t\t%12s", mixt_tree->mod->ras->free_mixt_rates?"FreeRates": mixt_tree->mod->ras->invar?"Gamma+Inv":"Gamma"); if(mixt_tree->mod->ras->free_mixt_rates == NO) { PhyML_Fprintf(fp,"\n. Gamma shape parameter value:\t\t%12.2f",mixt_tree->mod->ras->alpha->v); PhyML_Fprintf(fp,"\n Optimise: \t\t\t\t%12s",mixt_tree->mod->s_opt->opt_alpha==YES?"yes":"no"); } if(mixt_tree->mod->ras->invar == YES) { PhyML_Fprintf(fp,"\n. Proportion of invariable sites:\t%12.2f",mixt_tree->mod->ras->pinvar->v); PhyML_Fprintf(fp,"\n Optimise: \t\t\t\t%12s",mixt_tree->mod->s_opt->opt_pinvar==YES?"yes":"no"); } } PhyML_Fprintf(fp,"\n. Relative average rate:\t\t%12f",mixt_tree->mod->br_len_mult->v); tree = mixt_tree; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n. Mixture class %d",class+1); if(mixt_tree->mod->ras->n_catg > 1) { if(tree->mod->ras->invar == NO) { PhyML_Fprintf(fp,"\n Relative substitution rate:\t%12f",mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number]); PhyML_Fprintf(fp,"\n Rel. rate freq. (> 0 rates):\t%12f",mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number]); PhyML_Fprintf(fp,"\n Rate class number:\t\t%12d",tree->mod->ras->parent_class_number); } else { PhyML_Fprintf(fp,"\n Relative substitution rate:\t%12f",0.0); PhyML_Fprintf(fp,"\n Relative rate freq.:\t\t%12f",mixt_tree->mod->ras->pinvar->v); } } PhyML_Fprintf(fp,"\n Substitution model:\t\t%12s",tree->mod->modelname->s); if(tree->mod->whichmodel == CUSTOM) PhyML_Fprintf(fp,"\n Substitution model code:\t%12s",tree->mod->custom_mod_string->s); if(tree->mod->whichmodel == CUSTOMAA) PhyML_Fprintf(fp,"\n Rate matrix file name:\t%12s",tree->mod->aa_rate_mat_file->s); if(tree->mod->whichmodel == K80 || tree->mod->whichmodel == HKY85 || tree->mod->whichmodel == TN93) { PhyML_Fprintf(fp,"\n Value of the ts/tv raqtio:\t%12f",tree->mod->kappa->v); PhyML_Fprintf(fp,"\n Optimise ts/tv ratio:\t%12s",tree->mod->s_opt->opt_kappa?"yes":"no"); } else if(tree->mod->whichmodel == GTR || tree->mod->whichmodel == CUSTOM) { PhyML_Fprintf(fp,"\n Optimise subst. rates:\t%12s",tree->mod->s_opt->opt_rr?"yes":"no"); if(final == YES) { PhyML_Fprintf(fp,"\n Subst. rate A<->C:\t\t%12.2f",tree->mod->r_mat->rr->v[0]); PhyML_Fprintf(fp,"\n Subst. rate A<->G:\t\t%12.2f",tree->mod->r_mat->rr->v[1]); PhyML_Fprintf(fp,"\n Subst. rate A<->T:\t\t%12.2f",tree->mod->r_mat->rr->v[2]); PhyML_Fprintf(fp,"\n Subst. rate C<->G:\t\t%12.2f",tree->mod->r_mat->rr->v[3]); PhyML_Fprintf(fp,"\n Subst. rate C<->T:\t\t%12.2f",tree->mod->r_mat->rr->v[4]); PhyML_Fprintf(fp,"\n Subst. rate G<->T:\t\t%12.2f",tree->mod->r_mat->rr->v[5]); } } PhyML_Fprintf(fp,"\n Rate matrix weight:\t\t%12f",tree->mod->r_mat_weight->v / r_mat_weight_sum); if(tree->io->datatype == NT && tree->mod->whichmodel != JC69 && tree->mod->whichmodel != K80) { PhyML_Fprintf(fp,"\n Optimise nucletide freq.:\t%12s",tree->mod->s_opt->opt_state_freq?"yes":"no"); if(final == YES) { PhyML_Fprintf(fp,"\n Freq(A):\t\t\t%12.2f",tree->mod->e_frq->pi->v[0]); PhyML_Fprintf(fp,"\n Freq(C):\t\t\t%12.2f",tree->mod->e_frq->pi->v[1]); PhyML_Fprintf(fp,"\n Freq(G):\t\t\t%12.2f",tree->mod->e_frq->pi->v[2]); PhyML_Fprintf(fp,"\n Freq(T):\t\t\t%12.2f",tree->mod->e_frq->pi->v[3]); } } else if(tree->io->datatype == AA) { char *s; s = (char *)mCalloc(50,sizeof(char)); if(tree->mod->s_opt->opt_state_freq == YES) { strcpy(s,"Empirical"); } else { strcpy(s,"Model"); } PhyML_Fprintf(fp,"\n Amino-acid freq.:\t\t%12s",s); Free(s); } PhyML_Fprintf(fp,"\n Equ. freq. weight:\t\t%12f",tree->mod->e_frq_weight->v / e_frq_weight_sum); class++; tree = tree->next; if(tree && tree->is_mixt_tree == YES) break; } while(tree); mixt_tree = mixt_tree->next_mixt; if(!mixt_tree) break; } while(1); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; c++; tree = tree->next; } while(tree); link_efrq = (int *)mCalloc(c,sizeof(int)); link_lens = (int *)mCalloc(c,sizeof(int)); link_rmat = (int *)mCalloc(c,sizeof(int)); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n _______________________________________________________________________ "); PhyML_Fprintf(fp,"\n| |"); PhyML_Fprintf(fp,"\n| Model summary table |"); PhyML_Fprintf(fp,"\n|_______________________________________________________________________|"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); /* PhyML_Fprintf(fp," "); */ PhyML_Fprintf(fp," ------------------"); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"---"); tree = tree->next; } while(tree); param = (char *)mCalloc(30,sizeof(char)); PhyML_Fprintf(fp,"\n"); strcpy(param,"Partition element "); PhyML_Fprintf(fp," %18s",param); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"%2d ",tree->mixt_tree->dp); tree = tree->next; } while(tree); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp," ------------------"); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"---"); tree = tree->next; } while(tree); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; link_rmat[c] = -1; link_lens[c] = -1; link_efrq[c] = -1; tree = tree->next; c++; } while(tree); mixt_tree = cpy_mixt_tree; cc_efrq = 97; cc_rmat = 97; cc_lens = 97; cc = 0; do { if(mixt_tree->is_mixt_tree) mixt_tree = mixt_tree->next; if(link_efrq[cc] < 0) { link_efrq[cc] = cc_efrq; tree = mixt_tree->next; c = cc+1; if(tree) { do { if(tree->is_mixt_tree) tree = tree->next; if(mixt_tree->mod->e_frq == tree->mod->e_frq) link_efrq[c] = cc_efrq; tree = tree->next; c++; } while(tree); } cc_efrq++; } if(link_lens[cc] < 0) { link_lens[cc] = cc_lens; tree = mixt_tree->next; c = cc+1; if(tree) { do { if(tree->is_mixt_tree) tree = tree->next; if(mixt_tree->a_edges[0]->l == tree->a_edges[0]->l) link_lens[c] = cc_lens; tree = tree->next; c++; } while(tree); } cc_lens++; } if(link_rmat[cc] < 0) { link_rmat[cc] = cc_rmat; tree = mixt_tree->next; c = cc+1; if(tree) { do { if(tree->is_mixt_tree) tree = tree->next; if(mixt_tree->mod->r_mat == tree->mod->r_mat && mixt_tree->mod->whichmodel == tree->mod->whichmodel && !strcmp(mixt_tree->mod->custom_mod_string->s, tree->mod->custom_mod_string->s) && !strcmp(mixt_tree->mod->aa_rate_mat_file->s, tree->mod->aa_rate_mat_file->s)) link_rmat[c] = cc_rmat; tree = tree->next; c++; } while(tree); } cc_rmat++; } cc++; mixt_tree = mixt_tree->next; } while(mixt_tree); PhyML_Fprintf(fp,"\n"); strcpy(param,"State frequencies "); PhyML_Fprintf(fp," %18s",param); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"%2c ",link_efrq[c]); tree = tree->next; c++; } while(tree); PhyML_Fprintf(fp,"\n"); strcpy(param,"Branch lengths "); PhyML_Fprintf(fp," %18s",param); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"%2c ",link_lens[c]); tree = tree->next; c++; } while(tree); PhyML_Fprintf(fp,"\n"); strcpy(param,"Rate matrix "); PhyML_Fprintf(fp," %18s",param); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"%2c ",link_rmat[c]); tree = tree->next; c++; } while(tree); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp," ------------------"); tree = cpy_mixt_tree; c = 0; do { if(tree->is_mixt_tree) tree = tree->next; PhyML_Fprintf(fp,"---"); tree = tree->next; } while(tree); PhyML_Fprintf(fp,"\n"); if(final == YES) { tree = cpy_mixt_tree; c = 0; do { PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n. Tree estimated from data partition %d",c++); Br_Len_Involving_Invar(tree->next); Rescale_Br_Len_Multiplier_Tree(tree->next); s = Write_Tree(tree->next,NO); /*! tree->next is not a mixt_tree so edge lengths are not averaged over when writing the tree out. */ PhyML_Fprintf(fp,"\n %s",s); Br_Len_Not_Involving_Invar(tree->next); Unscale_Br_Len_Multiplier_Tree(tree->next); Free(s); tree = tree->next_mixt; } while(tree); } Free(param); Free(link_efrq); Free(link_rmat); Free(link_lens); mixt_tree = cpy_mixt_tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// option *PhyML_XML(char *xml_filename) { FILE *fp; xml_node *root,*p_elem,*m_elem,*parent,*instance; option *io,*dum; void *buff; t_mod *mod,*iomod; t_tree *tree,*mixt_tree,*root_tree; int select; char *component; int i,j,n_components; int first_m_elem; int class_number; scalar_dbl **lens,**lens_var,**ori_lens,**lens_old,**lens_var_old,**ori_lens_old,**ori_lens_var,**ori_lens_var_old; t_ds *ds; char *outputfile; char *alignment; char *s; int lens_size; int first; int *class_num; fp = fopen(xml_filename,"r"); if(!fp) { PhyML_Printf("\n== Could not find the XML file '%s'.\n",xml_filename); Exit("\n"); } root = XML_Load_File(fp); if(!root) { PhyML_Printf("\n== Encountered an issue while loading the XML file.\n"); Exit("\n"); } class_num = (int *)mCalloc(N_MAX_MIXT_CLASSES,sizeof(int)); For(i,N_MAX_MIXT_CLASSES) class_num[i] = i; component = (char *)mCalloc(T_MAX_NAME,sizeof(char)); m_elem = NULL; p_elem = root; io = NULL; mixt_tree = NULL; root_tree = NULL; mod = NULL; tree = NULL; lens = NULL; lens_var = NULL; lens_old = NULL; lens_var_old = NULL; select = -1; class_number = -1; ds = NULL; lens_size = 0; ori_lens = NULL; ori_lens_old = NULL; ori_lens_var = NULL; ori_lens_var_old = NULL; first = YES; dum = (option *)mCalloc(1,sizeof(option)); dum->use_xml = YES; // Make sure there are no duplicates in node's IDs XML_Check_Duplicate_ID(root); int count = 0; XML_Count_Number_Of_Node_With_Name("topology",&count,root); if(count > 1) { PhyML_Printf("\n== There should not more than one 'topology' node."); PhyML_Printf("\n== Found %d. Please fix your XML file",count); Exit("\n"); } else if(count < 1) { PhyML_Printf("\n== There should be at least one 'topology' node."); PhyML_Printf("\n== Found none. Please fix your XML file"); Exit("\n"); } p_elem = XML_Search_Node_Name("phyml",NO,p_elem); /*! Input file */ outputfile = XML_Get_Attribute_Value(p_elem,"output.file"); if(!outputfile) { PhyML_Printf("\n== The 'outputfile' attribute in 'phyml' tag is mandatory."); PhyML_Printf("\n== Please amend your XML file accordingly."); Exit("\n"); } io = (option *)Make_Input(); Set_Defaults_Input(io); s = XML_Get_Attribute_Value(p_elem,"run.id"); if(s) { io->append_run_ID = YES; strcpy(io->run_id_string,s); } strcpy(io->out_file,outputfile); strcpy(io->out_tree_file,outputfile); if(io->append_run_ID) { strcat(io->out_tree_file,"_"); strcat(io->out_tree_file,io->run_id_string); } strcat(io->out_tree_file,"_phyml_tree"); strcpy(io->out_stats_file,outputfile); if(io->append_run_ID) { strcat(io->out_stats_file,"_"); strcat(io->out_stats_file,io->run_id_string); } strcat(io->out_stats_file,"_phyml_stats"); io->fp_out_tree = Openfile(io->out_tree_file,1); io->fp_out_stats = Openfile(io->out_stats_file,1); s = XML_Get_Attribute_Value(p_elem,"print.trace"); if(s) { select = XML_Validate_Attr_Int(s,6, "true","yes","y", "false","no","n"); if(select < 3) { io->print_trace = YES; strcpy(io->out_trace_file,outputfile); if(io->append_run_ID) { strcat(io->out_trace_file,"_"); strcat(io->out_trace_file,io->run_id_string); } strcat(io->out_trace_file,"_phyml_trace"); io->fp_out_trace = Openfile(io->out_trace_file,1); } } s = XML_Get_Attribute_Value(p_elem,"branch.test"); if(s) { if(!strcmp(s,"aLRT")) { io->ratio_test = ALRTSTAT; } else if(!strcmp(s,"aBayes")) { io->ratio_test = ABAYES; } else if(!strcmp(s,"SH")) { io->ratio_test = SH; } else if(!strcmp(s,"no") || !strcmp(s,"none")) { io->ratio_test = 0; } else { PhyML_Printf("\n== '%s' is not a valid option for 'branch.test'.",s); PhyML_Printf("\n== Please use 'aLRT' or 'aBayes' or 'SH'."); Exit("\n"); } } s = XML_Get_Attribute_Value(p_elem,"quiet"); if(s) { select = XML_Validate_Attr_Int(s,6, "true","yes","y", "false","no","n"); if(select < 3) io->quiet = YES; } s = XML_Get_Attribute_Value(p_elem,"memory.check"); if(s) { select = XML_Validate_Attr_Int(s,6, "true","yes","y", "false","no","n"); if(select >= 3) io->mem_question = NO; } /*! Read all partitionelem nodes and mixturelem nodes in each of them */ do { p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem); if(p_elem == NULL) break; buff = (option *)Make_Input(); Set_Defaults_Input(buff); io->next = buff; io->next->prev = io; io = io->next; if(first == YES) { io = io->prev; io->next = NULL; Free_Input(buff); first = NO; } /*! Set the datatype (required when compressing data) */ char *dt = NULL; dt = XML_Get_Attribute_Value(p_elem,"data.type"); if(!dt) { PhyML_Printf("\n== Please specify the type of data ('aa' or 'nt') for partition element '%s'", XML_Get_Attribute_Value(p_elem,"id")); PhyML_Printf("\n== Syntax: 'data.type=\"aa\"' or 'data.type=\"nt\"'"); Exit("\n"); } select = XML_Validate_Attr_Int(dt,2,"aa","nt"); switch(select) { case 0: { io->datatype = AA; break; } case 1: { io->datatype = NT; break; } default: { PhyML_Printf("\n== Unknown data type. Must be either 'aa' or 'nt'."); Exit("\n"); } } char *format = NULL; format = XML_Get_Attribute_Value(p_elem,"format"); if(format) { if(!strcmp(format,"interleave") || !strcmp(format,"interleaved")) { io->interleaved = YES; } else if(!strcmp(format,"sequential")) { io->interleaved = NO; } } /*! Attach a model to this io struct */ io->mod = (t_mod *)Make_Model_Basic(); Set_Defaults_Model(io->mod); io->mod->ras->n_catg = 1; io->mod->io = io; iomod = io->mod; /*! Attach an optimization structure to this model */ iomod->s_opt = (t_opt *)Make_Optimiz(); Set_Defaults_Optimiz(iomod->s_opt); iomod->s_opt->opt_kappa = NO; iomod->s_opt->opt_lambda = NO; iomod->s_opt->opt_rr = NO; /*! Input file */ alignment = XML_Get_Attribute_Value(p_elem,"file.name"); if(!alignment) { PhyML_Printf("\n== 'file.name' tag is mandatory. Please amend your"); PhyML_Printf("\n== XML file accordingly."); Exit("\n"); } strcpy(io->in_align_file,alignment); /*! Open pointer to alignment */ io->fp_in_align = Openfile(io->in_align_file,0); /*! Load sequence file */ io->data = Get_Seq(io); /*! Close pointer to alignment */ fclose(io->fp_in_align); /*! Compress alignment */ io->cdata = Compact_Data(io->data,io); /*! Free uncompressed alignment */ Free_Seq(io->data,io->n_otu); /*! Create new mixture tree */ buff = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata); if(mixt_tree) { mixt_tree->next_mixt = buff; mixt_tree->next_mixt->prev_mixt = mixt_tree; mixt_tree = mixt_tree->next_mixt; mixt_tree->dp = mixt_tree->prev_mixt->dp+1; } else mixt_tree = buff; /*! Connect mixt_tree to io struct */ mixt_tree->io = io; /*! Connect mixt_tree to model struct */ mixt_tree->mod = iomod; /*! mixt_tree is a mixture tree */ mixt_tree->is_mixt_tree = YES; /*! mixt_tree is a mixture tree */ mixt_tree->mod->is_mixt_mod = YES; /*! Connect mixt_tree to compressed data */ mixt_tree->data = io->cdata; /*! Set total number of patterns */ mixt_tree->n_pattern = io->cdata->crunch_len; /*! Remove branch lengths from mixt_tree */ For(i,2*mixt_tree->n_otu-1) { Free_Scalar_Dbl(mixt_tree->a_edges[i]->l); Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_old); Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var); Free_Scalar_Dbl(mixt_tree->a_edges[i]->l_var_old); } /*! Connect last tree of the mixture for the previous partition element to the next mixture tree */ if(tree) { tree->next = mixt_tree; mixt_tree->prev = tree; } /*! Do the same for the model */ if(mod) { mod->next = iomod; iomod->prev = mod; } if(!root_tree) root_tree = mixt_tree; /*! Tree size scaling factor */ char *scale_tree = NULL; scale_tree = XML_Get_Attribute_Value(p_elem,"optimise.tree.scale"); if(scale_tree) { int select; select = XML_Validate_Attr_Int(scale_tree,6, "true","yes","y", "false","no","n"); if(select < 3) mixt_tree->mod->s_opt->opt_br_len_mult = YES; } scale_tree = NULL; scale_tree = XML_Get_Attribute_Value(p_elem,"tree.scale"); if(scale_tree) { char *scale_val; scale_val = XML_Get_Attribute_Value(p_elem,"tree.scale"); if(scale_val) { mixt_tree->mod->br_len_mult->v = String_To_Dbl(scale_val); mixt_tree->mod->br_len_mult_unscaled->v = String_To_Dbl(scale_val); Free(scale_val); } } /*! Process all the mixtureelem tags in this partition element */ n_components = 0; m_elem = p_elem; first_m_elem = 0; mod = NULL; tree = NULL; class_number = 0; do { m_elem = XML_Search_Node_Name("mixtureelem",YES,m_elem); if(m_elem == NULL) break; if(!strcmp(m_elem->name,"mixtureelem")) { first_m_elem++; /*! Rewind tree and model when processing a new mixtureelem node */ if(first_m_elem > 1) { while(tree->prev && tree->prev->is_mixt_tree == NO) { tree = tree->prev; } while(mod->prev && mod->prev->is_mixt_mod == NO) { mod = mod->prev; } } /*! Read and process model components */ char *list; list = XML_Get_Attribute_Value(m_elem,"list"); j = 0; For(i,(int)strlen(list)) if(list[i] == ',') j++; if(j != n_components && first_m_elem > 1) { PhyML_Printf("\n== Discrepancy in the number of elements in nodes 'mixtureelem' partitionelem id '%s'",p_elem->id); PhyML_Printf("\n== Check 'mixturelem' node with list '%s'",list); Exit("\n"); } n_components = j; i = j = 0; component[0] = '\0'; while(1) { if(list[j] == ',' || j == (int)strlen(list)) { /*! Reading a new component */ if(first_m_elem == YES) /* Only true when processing the first mixtureelem node */ { t_tree *this_tree; t_mod *this_mod; /*! Create new tree */ this_tree = (t_tree *)Make_Tree_From_Scratch(io->cdata->n_otu,io->cdata); /*! Update the number of mixtures */ iomod->n_mixt_classes++; if(tree) { tree->next = this_tree; tree->next->prev = tree; } else { mixt_tree->next = this_tree; mixt_tree->next->prev = mixt_tree; } tree = this_tree; tree->mixt_tree = mixt_tree; /*! Create a new model */ this_mod = (t_mod *)Make_Model_Basic(); Set_Defaults_Model(this_mod); this_mod->ras->n_catg = 1; /*! All br_len_multiplier point to the corresponding */ /*! parameter in the relevant mixt_tree */ Free_Scalar_Dbl(this_mod->br_len_mult); this_mod->br_len_mult = iomod->br_len_mult; if(mod) { mod->next = this_mod; mod->next->prev = mod; } else { this_mod->prev = iomod; } mod = this_mod; if(!iomod->next) iomod->next = mod; mod->io = io; mod->s_opt = (t_opt *)Make_Optimiz(); Set_Defaults_Optimiz(mod->s_opt); mod->s_opt->opt_alpha = NO; mod->s_opt->opt_pinvar = NO; tree->data = io->cdata; tree->n_pattern = io->cdata->crunch_len; tree->io = io; tree->mod = mod; if(tree->n_pattern != tree->prev->n_pattern) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } /*! Read a component */ component[i] = '\0'; if(j != (int)strlen(list)-1) i = 0; /*! Find which node this ID corresponds to */ instance = XML_Search_Node_ID(component,YES,root); if(!instance) { PhyML_Printf("\n== Could not find a node with id:'%s'.",component); PhyML_Printf("\n== Problem with 'mixtureelem' node, list '%s'.",list); Exit("\n"); } if(!instance->parent) { PhyML_Printf("\n== Node '%s' with id:'%s' has no parent.",instance->name,component); Exit("\n"); } parent = instance->parent; //////////////////////////////////////// // SUBSTITUTION MODEL // //////////////////////////////////////// if(!strcmp(parent->name,"ratematrices")) { /* ! First time we process this 'instance' node which has this 'ratematrices' parent */ if(instance->ds->obj == NULL) { Make_Ratematrice_From_XML_Node(instance, io, mod); ds = instance->ds; /*! Connect the data structure n->ds to mod->r_mat */ ds->obj = (t_rmat *)(mod->r_mat); /*! Create and connect the data structure n->ds->next to mod->kappa */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (scalar_dbl *)(mod->kappa); /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_kappa */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->s_opt->opt_kappa); /*! Create and connect the data structure n->ds->next to mod->s_opt->opt_rr */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->s_opt->opt_rr); /*! Create and connect the data structure n->ds->next to mod->whichmodel */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->whichmodel); /*! Create and connect the data structure n->ds->next to mod->modelname */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (t_string *)(mod->modelname); /*! Create and connect the data structure n->ds->next to mod->ns */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->ns); /*! Create and connect the data structure n->ds->next to mod->modelname */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (t_string *)(mod->custom_mod_string); /*! Create and connect the data structure n->ds->next to mod->fp_aa_rate_mat */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (FILE *)(mod->fp_aa_rate_mat); /*! Create and connect the data structure n->ds->next to mod->aa_rate_mat_file */ ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (t_string *)mod->aa_rate_mat_file; } else { /*! Connect to already extisting r_mat & kappa structs. */ t_ds *ds; ds = instance->ds; Free(mod->r_mat); mod->r_mat = (t_rmat *)ds->obj; ds = ds->next; Free_Scalar_Dbl(mod->kappa); mod->kappa = (scalar_dbl *)ds->obj; ds = ds->next; mod->s_opt->opt_kappa = *((int *)ds->obj); ds = ds->next; mod->s_opt->opt_rr = *((int *)ds->obj); ds = ds->next; mod->whichmodel = *((int *)ds->obj); ds = ds->next; Free_String(mod->modelname); mod->modelname = (t_string *)ds->obj; ds = ds->next; mod->ns = *((int *)ds->obj); ds = ds->next; Free_String(mod->custom_mod_string); mod->custom_mod_string = (t_string *)ds->obj; ds = ds->next; mod->fp_aa_rate_mat = (FILE *)ds->obj; ds = ds->next; Free_String(mod->aa_rate_mat_file); mod->aa_rate_mat_file = (t_string *)ds->obj; } } //////////////////////////////////////// // STATE FREQS // //////////////////////////////////////// else if(!strcmp(parent->name,"equfreqs")) { /* If n->ds == NULL, the corrresponding node data structure, n->ds, has not */ /* been initialized. If not, do nothing. */ if(instance->ds->obj == NULL) { Make_Efrq_From_XML_Node(instance,io,mod); t_ds *ds; ds = instance->ds; ds->obj = (t_efrq *)mod->e_frq; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->s_opt->opt_state_freq); ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&mod->s_opt->user_state_freq); ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (vect_dbl *)(mod->user_b_freq); } else { /* Connect the data structure n->ds to mod->e_frq */ ds = instance->ds; mod->e_frq = (t_efrq *)ds->obj; ds = ds->next; mod->s_opt->opt_state_freq = *((int *)ds->obj); ds = ds->next; mod->s_opt->user_state_freq = *((int *)ds->obj); ds = ds->next; Free_Vect_Dbl(mod->user_b_freq); mod->user_b_freq = (vect_dbl *)ds->obj; } } ////////////////////////////////////////// // TOPOLOGY // ////////////////////////////////////////// else if(!strcmp(parent->name,"topology")) { if(parent->ds->obj == NULL) Make_Topology_From_XML_Node(instance,io,iomod); ds = parent->ds; int buff; ds->obj = (int *)(& buff); } ////////////////////////////////////////// // RAS // ////////////////////////////////////////// else if(!strcmp(parent->name,"siterates")) { char *rate_value = NULL; /* scalar_dbl *r; */ phydbl val; /*! First time we process this 'siterates' node, check that its format is valid. and process it afterwards. */ if(parent->ds->obj == NULL) { class_number = 0; Make_RAS_From_XML_Node(parent,iomod); ds = parent->ds; ds->obj = (t_ras *)iomod->ras; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&iomod->s_opt->opt_alpha); ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&iomod->s_opt->opt_free_mixt_rates); } else /*! Connect ras struct to already defined one. Same for opt_alpha & opt_free_mixt_rates */ { if(iomod->ras != (t_ras *)parent->ds->obj) Free_RAS(iomod->ras); iomod->ras = (t_ras *)parent->ds->obj; iomod->s_opt->opt_alpha = *((int *)parent->ds->next->obj); iomod->s_opt->opt_free_mixt_rates = *((int *)parent->ds->next->next->obj); } rate_value = XML_Get_Attribute_Value(instance,"init.value"); val = 1.; if(rate_value) val = String_To_Dbl(rate_value); if(instance->ds->obj == NULL) { instance->ds->obj = (phydbl *)(&val); instance->ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); instance->ds->next->obj = (int *)(class_num + class_number); iomod->ras->gamma_rr->v[class_number] = val; iomod->ras->gamma_rr_unscaled->v[class_number] = val; iomod->ras->init_rr = NO; if(Are_Equal(val,0.0,1E-20) == NO) class_number++; } /*! Note: ras is already connected to the relevant t_ds stucture. No need to connect ras->gamma_rr or ras->p_invar */ /*! Invariant */ if(Are_Equal(val,0.0,1E-20)) { mod->ras->invar = YES; } else { mod->ras->parent_class_number = *((int *)instance->ds->next->obj); } xml_node *orig_w = NULL; orig_w = XML_Search_Node_Attribute_Value("appliesto",instance->id,YES,instance->parent); if(orig_w) { char *weight; weight = XML_Get_Attribute_Value(orig_w,"value"); if(mod->ras->invar == YES) { iomod->ras->pinvar->v = String_To_Dbl(weight); } else { int class; class = *((int *)instance->ds->next->obj); iomod->ras->gamma_r_proba->v[class] = String_To_Dbl(weight); iomod->ras->init_r_proba = NO; } } } ////////////////////////////////////////////// // BRANCH LENGTHS // ////////////////////////////////////////////// else if(!strcmp(parent->name,"branchlengths")) { int i; int n_otu; n_otu = tree->n_otu; if(instance->ds->obj == NULL) { if(!lens) { ori_lens = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *)); ori_lens_old = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *)); ori_lens_var = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *)); ori_lens_var_old = (scalar_dbl **)mCalloc(2*tree->n_otu-1,sizeof(scalar_dbl *)); lens = ori_lens; lens_old = ori_lens_old; lens_var = ori_lens_var; lens_var_old = ori_lens_var_old; lens_size = 2*tree->n_otu-1; } else { ori_lens = (scalar_dbl **)mRealloc(ori_lens,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *)); ori_lens_old = (scalar_dbl **)mRealloc(ori_lens_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *)); ori_lens_var = (scalar_dbl **)mRealloc(ori_lens_var,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *)); ori_lens_var_old = (scalar_dbl **)mRealloc(ori_lens_var_old,2*tree->n_otu-1+lens_size,sizeof(scalar_dbl *)); lens = ori_lens + lens_size;; lens_old = ori_lens_old + lens_size;; lens_var = ori_lens_var + lens_size;; lens_var_old = ori_lens_var_old + lens_size;; lens_size += 2*tree->n_otu-1; } For(i,2*tree->n_otu-1) { lens[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(lens[i]); lens_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(lens_old[i]); lens_var[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(lens_var[i]); lens_var_old[i] = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(lens_var_old[i]); Free_Scalar_Dbl(tree->a_edges[i]->l); Free_Scalar_Dbl(tree->a_edges[i]->l_old); Free_Scalar_Dbl(tree->a_edges[i]->l_var); Free_Scalar_Dbl(tree->a_edges[i]->l_var_old); if(tree->prev && tree->prev->a_edges[i]->l == mixt_tree->a_edges[i]->l && tree->prev->is_mixt_tree == NO) { PhyML_Printf("\n== %p %p",tree->a_edges[i]->l,mixt_tree->a_edges[i]->l); PhyML_Printf("\n== Only one set of edge lengths is allowed "); PhyML_Printf("\n== in a 'partitionelem'. Please fix your XML file."); Exit("\n"); } } char *opt_bl = NULL; opt_bl = XML_Get_Attribute_Value(instance,"optimise.lens"); if(opt_bl) { if(!strcmp(opt_bl,"yes") || !strcmp(opt_bl,"true")) { iomod->s_opt->opt_bl = YES; } else { iomod->s_opt->opt_bl = NO; } } ds = instance->ds; ds->obj = (scalar_dbl **)lens; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (scalar_dbl **)lens_old; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (scalar_dbl **)lens_var; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (scalar_dbl **)lens_var_old; ds->next = (t_ds *)mCalloc(1,sizeof(t_ds)); ds = ds->next; ds->obj = (int *)(&iomod->s_opt->opt_bl); } else { For(i,2*tree->n_otu-1) { Free_Scalar_Dbl(tree->a_edges[i]->l); Free_Scalar_Dbl(tree->a_edges[i]->l_old); Free_Scalar_Dbl(tree->a_edges[i]->l_var); Free_Scalar_Dbl(tree->a_edges[i]->l_var_old); } ds = instance->ds; lens = (scalar_dbl **)ds->obj; ds = ds->next; lens_old = (scalar_dbl **)ds->obj; ds = ds->next; lens_var = (scalar_dbl **)ds->obj; ds = ds->next; lens_var_old = (scalar_dbl **)ds->obj; ds = ds->next; iomod->s_opt->opt_bl = *((int *)ds->obj); } if(n_otu != tree->n_otu) { PhyML_Printf("\n== All the data sets should display the same number of sequences."); PhyML_Printf("\n== Found at least one data set with %d sequences and one with %d sequences.",n_otu,tree->n_otu); Exit("\n"); } For(i,2*tree->n_otu-1) { tree->a_edges[i]->l = lens[i]; mixt_tree->a_edges[i]->l = lens[i]; tree->a_edges[i]->l_old = lens_old[i]; mixt_tree->a_edges[i]->l_old = lens_old[i]; tree->a_edges[i]->l_var = lens_var[i]; mixt_tree->a_edges[i]->l_var = lens_var[i]; tree->a_edges[i]->l_var_old = lens_var_old[i]; mixt_tree->a_edges[i]->l_var_old = lens_var_old[i]; } } /////////////////////////////////////////////// /////////////////////////////////////////////// /////////////////////////////////////////////// if(first_m_elem > 1) // Done with this component, move to the next tree and model { if(tree->next) tree = tree->next; if(mod->next) mod = mod->next; } } else if(list[j] != ' ') { component[i] = list[j]; i++; } j++; if(j == (int)strlen(list)+1) break; } // end of mixtureelem processing } // end of partitionelem processing } while(1); } while(1); if(ori_lens) Free(ori_lens); if(ori_lens_old) Free(ori_lens_old); if(ori_lens_var) Free(ori_lens_var); if(ori_lens_var_old) Free(ori_lens_var_old); while(io->prev != NULL) io = io->prev; while(mixt_tree->prev != NULL) mixt_tree = mixt_tree->prev; /*! Finish making the models */ mod = mixt_tree->mod; do { Make_Model_Complete(mod); mod = mod->next; } while(mod); Check_Taxa_Sets(mixt_tree); Check_Mandatory_XML_Node(root,"phyml"); Check_Mandatory_XML_Node(root,"topology"); Check_Mandatory_XML_Node(root,"branchlengths"); Check_Mandatory_XML_Node(root,"ratematrices"); Check_Mandatory_XML_Node(root,"equfreqs"); Check_Mandatory_XML_Node(root,"siterates"); Check_Mandatory_XML_Node(root,"partitionelem"); Check_Mandatory_XML_Node(root,"mixtureelem"); if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1; char *most_likely_tree = NULL; phydbl best_lnL = UNLIKELY; int num_rand_tree; For(num_rand_tree,io->mod->s_opt->n_rand_starts) { /*! Initialize the models */ mod = mixt_tree->mod; do { Init_Model(mod->io->cdata,mod,io); mod = mod->next; } while(mod); /* printf("\n%f %f %f %f", */ /* mixt_tree->mod->ras->gamma_r_proba->v[0], */ /* mixt_tree->mod->ras->gamma_r_proba->v[1], */ /* mixt_tree->mod->ras->gamma_r_proba->v[2], */ /* mixt_tree->mod->ras->gamma_r_proba->v[3]); */ /* Exit("\n"); */ Print_Data_Structure(NO,stdout,mixt_tree); t_tree *bionj_tree = NULL; switch(mixt_tree->io->in_tree) { case 2: /*! user-defined input tree */ { if(!mixt_tree->io->fp_in_tree) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } /*! Copy the user tree to all the tree structures */ tree = Read_User_Tree(mixt_tree->io->cdata, mixt_tree->mod, mixt_tree->io); break; } case 1: case 0: { if(!bionj_tree) { /*! Build a BioNJ tree from the analysis of the first partition element */ tree = Dist_And_BioNJ(mixt_tree->data, mixt_tree->mod, mixt_tree->io); bionj_tree = (t_tree *)Make_Tree_From_Scratch(mixt_tree->n_otu,mixt_tree->data); Copy_Tree(tree,bionj_tree); } else { tree = (t_tree *)Make_Tree_From_Scratch(mixt_tree->n_otu,mixt_tree->data); Copy_Tree(bionj_tree,tree); } break; } } Copy_Tree(tree,mixt_tree); Free_Tree(tree); if(bionj_tree) Free_Tree(bionj_tree); if(io->mod->s_opt->random_input_tree) { PhyML_Printf("\n\n. [%3d/%3d]",num_rand_tree+1,io->mod->s_opt->n_rand_starts); Random_Tree(mixt_tree); } tree = mixt_tree; do { if(tree != mixt_tree) Copy_Tree(mixt_tree,tree); Connect_CSeqs_To_Nodes(tree->data,io,tree); tree = tree->next; } while(tree); /*! Initialize t_beg in each mixture tree */ tree = mixt_tree; do { time(&(tree->t_beg)); tree = tree->next_mixt; } while(tree); Prepare_Tree_For_Lk(mixt_tree); MIXT_Chain_All(mixt_tree); /*! Check that all the edges in a mixt_tree at pointing to a single set of lengths */ tree = mixt_tree; do { MIXT_Check_Single_Edge_Lens(tree); tree = tree->next_mixt; } while(tree); /*! Turn all branches to ON state */ tree = mixt_tree; do { MIXT_Turn_Branches_OnOff(ON,tree); tree = tree->next_mixt; } while(tree); tree = mixt_tree; do { if(tree->next_mixt) { tree->mod->next_mixt = tree->next_mixt->mod; tree->next_mixt->mod->prev_mixt = tree->mod; } tree = tree->next_mixt; } while(tree); /* TO DO 1) REMOVE ROOT X 2) ALLOW MORE THAN ONE VECTOR OF BRANCH LENGTHS -> NEED TO LOOK CAREFULY AT WHAT IT MEANS FOR SPR, SIMULTANEOUS NNI MOVES PRUNE AND REGRAFT... X 3) Branch lengths in Prune and Regarft -> make sure you don't apply change several times 4) Make sure you can't have the same branch lengths with distinct data types 5) Finish rewritting Opt_Free_Param X 6) Make sure you can have only one set of branch lengths per partition 7) BIONJ starting tree X 8) When iomod->ras->invar = YES, check that only one mod has mod->ras->invar = YES; 9) Reflect changes on simu.c to spr.c, especially regarding invariants 10) Rough_SPR to replace SPR_Shuffle and first step in nni (refining tree) 11) Tree corresponding to invar class is never really used (except for testing whether tree->mod->ras->invar==YES). Do we need to use memory for this? X 12) Check that mixt_tree->mod->ras->n_catg corresponds to the same number of trees in the mixture (do that for each mixt_tree). 13) Change tree->a_edges to tree->a_edges (t is for type a is for array) 14) Change tree->a_nodes to tree->a_nodes (t is for type a is for array) X 15) tstv should be shared! Check the following: // Connect the data structure n->ds to mod->r_mat mod->r_mat = (t_rmat *)instance->ds->obj; mod->kappa = (scalar_dbl *)instance->ds->next->obj; 16) Replace s_opt struct by opt flag for each param? X 17) Check the sequences and tree have the same number of otus X 18) Avoid transformation to lower case of attribute values when processing XML. X 19) Break mixture: break nodes and branches too. X 20) Check alrt.c X 21) Set_Alias_Subpatt X 22) Check that all partition elements have the same set of taxa. 23) What if ratematrices are not specified ? Default is ok? X 24) Set upper and lower bounds on Br_Len_Brent */ MIXT_Check_Invar_Struct_In_Each_Partition_Elem(mixt_tree); MIXT_Check_RAS_Struct_In_Each_Partition_Elem(mixt_tree); Set_Both_Sides(YES,mixt_tree); if(mixt_tree->mod->s_opt->opt_topo) { if(mixt_tree->mod->s_opt->topo_search == NNI_MOVE) Simu_Loop(mixt_tree); else if(mixt_tree->mod->s_opt->topo_search == SPR_MOVE) Speed_Spr_Loop(mixt_tree); else Best_Of_NNI_And_SPR(mixt_tree); } else { if(mixt_tree->mod->s_opt->opt_subst_param || mixt_tree->mod->s_opt->opt_bl) { Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX); } else { Lk(NULL,mixt_tree); } } PhyML_Printf("\n\n. Log-likelihood = %f",mixt_tree->c_lnL); if((num_rand_tree == io->mod->s_opt->n_rand_starts-1) && (io->mod->s_opt->random_input_tree)) { num_rand_tree--; io->mod->s_opt->random_input_tree = NO; } Br_Len_Involving_Invar(mixt_tree); Rescale_Br_Len_Multiplier_Tree(mixt_tree); /*! Print the tree estimated using the current random (or BioNJ) starting tree */ if(io->mod->s_opt->n_rand_starts > 1) { Print_Tree(io->fp_out_trees,mixt_tree); fflush(NULL); } if(mixt_tree->c_lnL > best_lnL) { best_lnL = mixt_tree->c_lnL; if(most_likely_tree) Free(most_likely_tree); if(io->ratio_test) aLRT(mixt_tree); most_likely_tree = Write_Tree(mixt_tree,NO); mixt_tree->lock_topo = NO; } /*! Initialize t_end in each mixture tree */ tree = mixt_tree; do { time(&(tree->t_current)); tree = tree->next_mixt; } while(tree); Print_Data_Structure(YES,mixt_tree->io->fp_out_stats,mixt_tree); Free_Spr_List(mixt_tree); Free_Triplet(mixt_tree->triplet_struct); Free_Tree_Pars(mixt_tree); Free_Tree_Lk(mixt_tree); } /*! Print the most likely tree in the output file */ if(!mixt_tree->io->quiet) PhyML_Printf("\n\n. Printing the most likely tree in file '%s'...\n", Basename(mixt_tree->io->out_tree_file)); PhyML_Fprintf(mixt_tree->io->fp_out_tree,"%s\n",most_likely_tree); Free(component); /*! Bootstrap analysis */ MIXT_Bootstrap(most_likely_tree,root); while(io->prev != NULL) io = io->prev; Free(most_likely_tree); tree = mixt_tree; do { Free_Cseq(tree->data); tree = tree->next_mixt; } while(tree); tree = mixt_tree; do { Free_Optimiz(tree->mod->s_opt); tree = tree->next; } while(tree); Free_Model_Complete(mixt_tree->mod); Free_Model_Basic(mixt_tree->mod); Free_Tree(mixt_tree); if(io->fp_out_trees) fclose(io->fp_out_trees); if(io->fp_out_tree) fclose(io->fp_out_tree); if(io->fp_out_stats) fclose(io->fp_out_stats); Free_Input(io); XML_Free_XML_Tree(root); Free(class_num); fclose(fp); return(dum); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Check that the same nodes in the different mixt_trees are connected to the same taxa */ void Check_Taxa_Sets(t_tree *mixt_tree) { t_tree *tree; int i; tree = mixt_tree; do { if(tree->next) { For(i,tree->n_otu) { if(strcmp(tree->a_nodes[i]->name,tree->next->a_nodes[i]->name)) { PhyML_Printf("\n== There seems to be a problem in one (or more) of your"); PhyML_Printf("\n== sequence alignments. PhyML could not match taxon"); PhyML_Printf("\n== '%s' found in file '%s' with any of the taxa",tree->a_nodes[i]->name,tree->io->in_align_file); PhyML_Printf("\n== listed in file '%s'.",tree->next->io->in_align_file); Exit("\n"); } } } tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod) { char *model = NULL; int select; model = XML_Get_Attribute_Value(instance,"model"); if(model == NULL) { PhyML_Printf("\n== Poorly formated XML file."); PhyML_Printf("\n== Attribute 'model' is mandatory in a node."); Exit("\n"); } select = XML_Validate_Attr_Int(model,27, "xxxxx", //0 "JC69", //1 "K80", //2 "F81", //3 "HKY85", //4 "F84", //5 "TN93", //6 "GTR", //7 "CUSTOM", //8 "xxxxx", //9 "xxxxx", //10 "WAG", //11 "DAYHOFF", //12 "JTT", //13 "BLOSUM62", //14 "MTREV", //15 "RTREV", //16 "CPREV", //17 "DCMUT", //18 "VT", //19 "MTMAM", //20 "MTART", //21 "HIVW", //22 "HIVB", //23 "FLU", //24 "CUSTOMAA", //25 "LG", //26 "AB" ); //27 if(select < 9) { mod->ns = 4; if(io->datatype != NT) { PhyML_Printf("\n== Data type and selected model are incompatible"); Exit("\n"); } } else { mod->ns = 20; if(io->datatype != AA) { PhyML_Printf("\n== Data type and selected model are incompatible"); Exit("\n"); } } io->mod->ns = mod->ns; mod->r_mat = (t_rmat *)Make_Rmat(mod->ns); Init_Rmat(mod->r_mat); /*! Set model number & name */ mod->whichmodel = Set_Whichmodel(select); Set_Model_Name(mod); if(mod->whichmodel == K80 || mod->whichmodel == HKY85 || mod->whichmodel == TN93) { char *tstv,*opt_tstv; tstv = XML_Get_Attribute_Value(instance,"tstv"); if(tstv) { mod->s_opt->opt_kappa = NO; mod->kappa->v = String_To_Dbl(tstv); } else { mod->s_opt->opt_kappa = YES; } opt_tstv = XML_Get_Attribute_Value(instance,"optimise.tstv"); if(opt_tstv) { if(!strcmp(opt_tstv,"true") || !strcmp(opt_tstv,"yes")) { mod->s_opt->opt_kappa = YES; } else { mod->s_opt->opt_kappa = NO; } } } else { mod->s_opt->opt_kappa = NO; } if(mod->whichmodel == GTR || mod->whichmodel == CUSTOM) { char *opt_rr; opt_rr = XML_Get_Attribute_Value(instance,"optimise.rr"); if(opt_rr) { if(!strcmp(opt_rr,"yes") || !strcmp(opt_rr,"true")) { mod->s_opt->opt_rr = YES; } } } /*! Custom model for nucleotide sequences. Read the corresponding code. */ if(mod->whichmodel == CUSTOM) { char *model_code = NULL; model_code = XML_Get_Attribute_Value(instance,"model.code"); if(!model_code) { PhyML_Printf("\n== No valid 'model.code' attribute could be found.\n"); PhyML_Printf("\n== Please fix your XML file.\n"); Exit("\n"); } else { strcpy(mod->custom_mod_string->s,model_code); } } /*! Custom model for amino-acids. Read in the rate matrix file */ if(mod->whichmodel == CUSTOMAA) { char *r_mat_file; r_mat_file = XML_Get_Attribute_Value(instance,"ratematrix.file"); if(!r_mat_file) { PhyML_Printf("\n== No valid 'ratematrix.file' attribute could be found."); PhyML_Printf("\n== Please fix your XML file.\n"); Exit("\n"); } else { mod->fp_aa_rate_mat = Openfile(r_mat_file,0); strcpy(mod->aa_rate_mat_file->s,r_mat_file); } /* Free(r_mat_file); */ } char *buff; buff = XML_Get_Attribute_Value(instance->parent,"optimise.weights"); if(buff && (!strcmp(buff,"yes") || !strcmp(buff,"true"))) { mod->s_opt->opt_rmat_weight = YES; } else { mod->s_opt->opt_rmat_weight = NO; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod) { char *buff; mod->e_frq = (t_efrq *)Make_Efrq(mod->ns); Init_Efrq(mod->e_frq); buff = XML_Get_Attribute_Value(instance,"optimise.freqs"); if(buff) { if(!strcmp(buff,"yes") || !strcmp(buff,"true")) { if(io->datatype == AA) { PhyML_Printf("\n== Option 'optimise.freqs' set to 'yes' (or 'true')"); PhyML_Printf("\n== is not allowed with amino-acid data."); Exit("\n"); } mod->s_opt->opt_state_freq = YES; } Free(buff); } buff = XML_Get_Attribute_Value(instance,"aa.freqs"); if(buff) { if(!strcmp(buff,"empirical")) { if(io->datatype == AA) { mod->s_opt->opt_state_freq = YES; } else if(io->datatype == NT) { mod->s_opt->opt_state_freq = NO; } } /* Free(buff); */ } buff = XML_Get_Attribute_Value(instance,"base.freqs"); if(buff) { if(io->datatype == AA) { PhyML_Printf("\n== Option 'base.freqs' is not allowed with amino-acid data."); Exit("\n"); } else { phydbl A,C,G,T; sscanf(buff,"%lf,%lf,%lf,%lf",&A,&C,&G,&T); mod->user_b_freq->v[0] = (phydbl)A; mod->user_b_freq->v[1] = (phydbl)C; mod->user_b_freq->v[2] = (phydbl)G; mod->user_b_freq->v[3] = (phydbl)T; mod->s_opt->user_state_freq = YES; mod->s_opt->opt_state_freq = NO; } } buff = XML_Get_Attribute_Value(instance->parent,"optimise.weights"); if(buff && (!strcmp(buff,"yes") || !strcmp(buff,"true"))) { mod->s_opt->opt_efrq_weight = YES; } else { mod->s_opt->opt_efrq_weight = NO; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Topology_From_XML_Node(xml_node *instance, option *io, t_mod *mod) { // Starting tree char *init_tree; init_tree = XML_Get_Attribute_Value(instance,"init.tree"); if(!init_tree) { PhyML_Printf("\n== Attribute 'init.tree=bionj|user|random' is mandatory"); PhyML_Printf("\n== Please amend your XML file accordingly."); Exit("\n"); } if(!strcmp(init_tree,"user") || !strcmp(init_tree,"User")) { char *starting_tree = NULL; starting_tree = XML_Get_Attribute_Value(instance,"file.name"); if(!Filexists(starting_tree)) { PhyML_Printf("\n== The tree file '%s' could not be found.",starting_tree); Exit("\n"); } else { strcpy(io->in_tree_file,starting_tree); io->in_tree = 2; io->fp_in_tree = Openfile(io->in_tree_file,0); } } else if(!strcmp(init_tree,"random") || !strcmp(init_tree,"Random")) { char *n_rand_starts = NULL; io->mod->s_opt->random_input_tree = YES; n_rand_starts = XML_Get_Attribute_Value(instance,"n.rand.starts"); if(n_rand_starts) { mod->s_opt->n_rand_starts = atoi(n_rand_starts); if(mod->s_opt->n_rand_starts < 1) Exit("\n== Number of random starting trees must be > 0.\n\n"); } strcpy(io->out_trees_file,io->in_align_file); strcat(io->out_trees_file,"_phyml_rand_trees"); if(io->append_run_ID) { strcat(io->out_trees_file,"_"); strcat(io->out_trees_file,io->run_id_string); } io->fp_out_trees = Openfile(io->out_trees_file,1); } else if(!strcmp(init_tree,"parsimony") || !strcmp(init_tree,"Parsimony")) { io->in_tree = 1; } // Estimate tree topology char *optimise = NULL; optimise = XML_Get_Attribute_Value(instance,"optimise.tree"); if(optimise) { int select; select = XML_Validate_Attr_Int(optimise,6, "true","yes","y", "false","no","n"); if(select > 2) io->mod->s_opt->opt_topo = NO; else { char *search; int select; search = XML_Get_Attribute_Value(instance,"search"); if(search == NULL) { io->mod->s_opt->topo_search = SPR_MOVE; io->mod->s_opt->opt_topo = YES; } else { select = XML_Validate_Attr_Int(search,4,"spr","nni","best","none"); switch(select) { case 0: { io->mod->s_opt->topo_search = SPR_MOVE; io->mod->s_opt->opt_topo = YES; break; } case 1: { io->mod->s_opt->topo_search = NNI_MOVE; io->mod->s_opt->opt_topo = YES; break; } case 2: { io->mod->s_opt->topo_search = BEST_OF_NNI_AND_SPR; io->mod->s_opt->opt_topo = YES; break; } case 3: { io->mod->s_opt->opt_topo = NO; break; } default: { PhyML_Printf("\n== Topology search option '%s' is not valid.",search); Exit("\n"); break; } } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod) { xml_node *w; char *family; int select; mod->ras->n_catg = 0; XML_Check_Siterates_Node(parent); w = XML_Search_Node_Name("weights",YES,parent); if(w) { family = XML_Get_Attribute_Value(w,"family"); select = XML_Validate_Attr_Int(family,3,"gamma","gamma+inv","freerates"); switch(select) { case 0:// Gamma model { char *alpha,*alpha_opt; mod->s_opt->opt_pinvar = NO; mod->ras->invar = NO; alpha = XML_Get_Attribute_Value(w,"alpha"); if(alpha) { if(!strcmp(alpha,"estimate") || !strcmp(alpha,"estimated") || !strcmp(alpha,"optimise") || !strcmp(alpha,"optimised")) { mod->s_opt->opt_alpha = YES; } else { mod->s_opt->opt_alpha = NO; mod->ras->alpha->v = String_To_Dbl(alpha); } } alpha_opt = XML_Get_Attribute_Value(w,"optimise.alpha"); if(alpha_opt) { if(!strcmp(alpha_opt,"yes") || !strcmp(alpha_opt,"true")) { mod->s_opt->opt_alpha = YES; } else { mod->s_opt->opt_alpha = NO; } } mod->ras->n_catg = XML_Get_Number_Of_Classes_Siterates(parent); Make_RAS_Complete(mod->ras); break; } case 1: // Gamma+Inv model { char *alpha,*pinv,*alpha_opt,*pinv_opt; mod->ras->invar = YES; mod->s_opt->opt_pinvar = YES; alpha = XML_Get_Attribute_Value(w,"alpha"); if(alpha) { if(!strcmp(alpha,"estimate") || !strcmp(alpha,"estimated") || !strcmp(alpha,"optimise") || !strcmp(alpha,"optimised")) { mod->s_opt->opt_alpha = YES; } else { mod->s_opt->opt_alpha = NO; mod->ras->alpha->v = String_To_Dbl(alpha);; } } alpha_opt = XML_Get_Attribute_Value(w,"optimise.alpha"); if(alpha_opt) { if(!strcmp(alpha_opt,"yes") || !strcmp(alpha_opt,"true")) { mod->s_opt->opt_alpha = YES; } else { mod->s_opt->opt_alpha = NO; } } pinv = XML_Get_Attribute_Value(w,"pinv"); if(pinv) { if(!strcmp(pinv,"estimate") || !strcmp(pinv,"estimated") || !strcmp(pinv,"optimise") || !strcmp(pinv,"optimised")) { mod->s_opt->opt_pinvar = YES; } else { mod->s_opt->opt_pinvar = NO; mod->ras->pinvar->v = String_To_Dbl(pinv);; } } pinv_opt = XML_Get_Attribute_Value(w,"optimise.pinv"); if(pinv_opt) { if(!strcmp(pinv_opt,"yes") || !strcmp(pinv_opt,"true")) { mod->s_opt->opt_pinvar = YES; } else { mod->s_opt->opt_pinvar = NO; } } mod->ras->n_catg = XML_Get_Number_Of_Classes_Siterates(parent); break; } case 2: // FreeRate model { char *opt_freerates; mod->ras->free_mixt_rates = YES; mod->s_opt->opt_free_mixt_rates = YES; opt_freerates = XML_Get_Attribute_Value(w,"optimise.freerates"); if(opt_freerates) { if(!strcmp(opt_freerates,"yes") || !strcmp(opt_freerates,"true")) { mod->s_opt->opt_free_mixt_rates = YES; } else { mod->s_opt->opt_free_mixt_rates = NO; } } mod->ras->n_catg = XML_Get_Number_Of_Classes_Siterates(parent); break; } default: { PhyML_Printf("\n== family: %s",family); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } int nc = XML_Get_Number_Of_Classes_Siterates(parent); if(w && nc != mod->ras->n_catg) { PhyML_Printf("\n== component '%s'. The number of classes ",parent->id); PhyML_Printf("\n== specified in the component should be "); PhyML_Printf("\n== the same as that of nodes. Please fix"); PhyML_Printf("\n== your XML file accordingly."); Exit("\n"); } if(!w) mod->ras->n_catg = nc; Make_RAS_Complete(mod->ras); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Generic_Exit(const char *file, int line, const char *function) { PhyML_Printf("\n== Err. in file '%s' (line %d), function '%s'",file,line,function); Exit("\n"); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phyml-3.2.0/src/io.h000066400000000000000000000103311263450375500142240ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef IO_H #define IO_H #include "utilities.h" t_tree *Read_Tree(char **s_tree); void R_rtree(char *s_tree_a,char *s_tree_d,t_node *a,t_tree *tree,int *n_int,int *n_ext); void Read_Branch_Label(char *s_d,char *s_a,t_edge *b); void Read_Branch_Length(char *s_d,char *s_a,t_tree *tree); void Read_Node_Name(t_node *d,char *s_tree_d,t_tree *tree); void Clean_Multifurcation(char **subtrees,int current_deg,int end_deg); char **Sub_Trees(char *tree,int *degree); int Next_Par(char *s,int pos); void Print_Tree(FILE *fp,t_tree *tree); char *Write_Tree(t_tree *tree,int custom); void R_wtree(t_node *pere,t_node *fils,int *available,char **s_tree,t_tree *tree); void R_wtree_Custom(t_node *pere,t_node *fils,int *available,char **s_tree,int *pos,t_tree *tree); void Detect_Align_File_Format(option *io); void Detect_Tree_File_Format(option *io); align **Get_Seq(option *io); void Get_Nexus_Data(FILE *fp,option *io); int Get_Token(FILE *fp,char *token); align **Get_Seq_Phylip(option *io); void Read_Ntax_Len_Phylip(FILE *fp,int *n_otu,int *n_tax); align **Read_Seq_Sequential(option *io); align **Read_Seq_Interleaved(option *io); int Read_One_Line_Seq(align ***data,int num_otu,FILE *in); t_tree *Read_Tree_File(option *io); char *Return_Tree_String_Phylip(FILE *fp_input_tree); t_tree *Read_Tree_File_Phylip(FILE *fp_input_tree); void Print_Site_Lk(t_tree *tree,FILE *fp); void Print_Seq(FILE *fp, align **data, int n_otu); void Print_CSeq(FILE *fp,int compressed,calign *cdata); void Print_CSeq_Select(FILE *fp,int compressed,calign *cdata,t_tree *tree); void Print_Dist(matrix *mat); void Print_Node(t_node *a,t_node *d,t_tree *tree); void Print_Model(t_mod *mod); void Print_Mat(matrix *mat); FILE *Openfile(char *filename,int mode); void Print_Fp_Out(FILE *fp_out,time_t t_beg,time_t t_end,t_tree *tree,option *io,int n_data_set,int num_tree, int add_citation); void Print_Fp_Out_Lines(FILE *fp_out,time_t t_beg,time_t t_end,t_tree *tree,option *io,int n_data_set); void Print_Freq(t_tree *tree); void Print_Settings(option *io); void Print_Banner(FILE *fp); void Print_Banner_Small(FILE *fp); void Print_Data_Set_Number(option *io,FILE *fp); void Print_Lk(t_tree *tree,char *string); void Print_Pars(t_tree *tree); void Print_Lk_And_Pars(t_tree *tree); void Read_Qmat(phydbl *daa,phydbl *pi,FILE *fp); void Print_Qmat_AA(phydbl *daa,phydbl *pi); void Print_Square_Matrix_Generic(int n,phydbl *mat); void Print_Diversity(FILE *fp,t_tree *tree); void Print_Diversity_Pre(t_node *a,t_node *d,t_edge *b,FILE *fp,t_tree *tree); t_tree *Read_User_Tree(calign *cdata,t_mod *mod,option *io); void Print_Time_Info(time_t t_beg,time_t t_end); void PhyML_Printf(char *format,...); void PhyML_Fprintf(FILE *fp,char *format,...); void Read_Clade_Priors(char *file_name,t_tree *tree); option *Get_Input(int argc,char **argv); void Print_Data_Structure(int final, FILE *fp, t_tree *root); int Set_Whichmodel(int select); void Print_Site(calign *cdata, int num, int n_otu, char *sep, int stepsize, FILE *fp); option *PhyML_XML(char *xml_filename); void Check_Taxa_Sets(t_tree *mixt_tree); void Make_Ratematrice_From_XML_Node(xml_node *instance, option *io, t_mod *mod); void Make_Efrq_From_XML_Node(xml_node *instance, option *io, t_mod *mod); void Make_Topology_From_XML_Node(xml_node *instance, option *io, t_mod *mod); void Make_RAS_From_XML_Node(xml_node *parent, t_mod *mod); void Post_Process_Data(option *io); int *Return_Int(int in); void Print_All_Edge_PMats(t_tree* tree); void Print_All_Edge_Likelihoods(t_tree* tree); void Print_Edge_Likelihoods(t_tree* tree, t_edge* b, bool scientific); void Print_Edge_PMats(t_tree* tree, t_edge* b); void Print_Tip_Partials(t_tree* tree, t_node* d); void Dump_Arr_D(phydbl* arr, int num); void Dump_Arr_S(short int* arr, int num); void Dump_Arr_I(int* arr, int num); void Print_Tree_Structure(t_tree* tree); void Print_Node_Brief(t_node *a, t_node *d, t_tree *tree, FILE *fp); void Generic_Exit(const char *file, int line, const char *function); #endif phyml-3.2.0/src/lk.c000066400000000000000000004052711263450375500142310ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "assert.h" #include "lk.h" #ifdef BEAGLE #include "beagle_utils.h" #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_Nucleotides_Float(char state, int pos, phydbl *p_lk) { switch(state) { case 'A' : p_lk[pos+0]=1.; p_lk[pos+1]=p_lk[pos+2]=p_lk[pos+3]=.0; break; case 'C' : p_lk[pos+1]=1.; p_lk[pos+0]=p_lk[pos+2]=p_lk[pos+3]=.0; break; case 'G' : p_lk[pos+2]=1.; p_lk[pos+1]=p_lk[pos+0]=p_lk[pos+3]=.0; break; case 'T' : p_lk[pos+3]=1.; p_lk[pos+1]=p_lk[pos+2]=p_lk[pos+0]=.0; break; case 'U' : p_lk[pos+3]=1.; p_lk[pos+1]=p_lk[pos+2]=p_lk[pos+0]=.0; break; case 'M' : p_lk[pos+0]=p_lk[pos+1]=1.; p_lk[pos+2]=p_lk[pos+3]=.0; break; case 'R' : p_lk[pos+0]=p_lk[pos+2]=1.; p_lk[pos+1]=p_lk[pos+3]=.0; break; case 'W' : p_lk[pos+0]=p_lk[pos+3]=1.; p_lk[pos+1]=p_lk[pos+2]=.0; break; case 'S' : p_lk[pos+1]=p_lk[pos+2]=1.; p_lk[pos+0]=p_lk[pos+3]=.0; break; case 'Y' : p_lk[pos+1]=p_lk[pos+3]=1.; p_lk[pos+0]=p_lk[pos+2]=.0; break; case 'K' : p_lk[pos+2]=p_lk[pos+3]=1.; p_lk[pos+0]=p_lk[pos+1]=.0; break; case 'B' : p_lk[pos+1]=p_lk[pos+2]=p_lk[pos+3]=1.; p_lk[pos+0]=.0; break; case 'D' : p_lk[pos+0]=p_lk[pos+2]=p_lk[pos+3]=1.; p_lk[pos+1]=.0; break; case 'H' : p_lk[pos+0]=p_lk[pos+1]=p_lk[pos+3]=1.; p_lk[pos+2]=.0; break; case 'V' : p_lk[pos+0]=p_lk[pos+1]=p_lk[pos+2]=1.; p_lk[pos+3]=.0; break; case 'N' : case 'X' : case '?' : case 'O' : case '-' : p_lk[pos+0]=p_lk[pos+1]=p_lk[pos+2]=p_lk[pos+3]=1.;break; default : { PhyML_Printf("\n== Unknown character state : %c\n",state); Exit("\n== Init failed (data type supposed to be DNA)\n"); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_Nucleotides_Int(char state, int pos, short int *p_pars) { switch(state) { case 'A' : p_pars[pos+0]=1; p_pars[pos+1]=p_pars[pos+2]=p_pars[pos+3]=0; break; case 'C' : p_pars[pos+1]=1; p_pars[pos+0]=p_pars[pos+2]=p_pars[pos+3]=0; break; case 'G' : p_pars[pos+2]=1; p_pars[pos+1]=p_pars[pos+0]=p_pars[pos+3]=0; break; case 'T' : p_pars[pos+3]=1; p_pars[pos+1]=p_pars[pos+2]=p_pars[pos+0]=0; break; case 'U' : p_pars[pos+3]=1; p_pars[pos+1]=p_pars[pos+2]=p_pars[pos+0]=0; break; case 'M' : p_pars[pos+0]=p_pars[pos+1]=1; p_pars[pos+2]=p_pars[pos+3]=0; break; case 'R' : p_pars[pos+0]=p_pars[pos+2]=1; p_pars[pos+1]=p_pars[pos+3]=0; break; case 'W' : p_pars[pos+0]=p_pars[pos+3]=1; p_pars[pos+1]=p_pars[pos+2]=0; break; case 'S' : p_pars[pos+1]=p_pars[pos+2]=1; p_pars[pos+0]=p_pars[pos+3]=0; break; case 'Y' : p_pars[pos+1]=p_pars[pos+3]=1; p_pars[pos+0]=p_pars[pos+2]=0; break; case 'K' : p_pars[pos+2]=p_pars[pos+3]=1; p_pars[pos+0]=p_pars[pos+1]=0; break; case 'B' : p_pars[pos+1]=p_pars[pos+2]=p_pars[pos+3]=1; p_pars[pos+0]=0; break; case 'D' : p_pars[pos+0]=p_pars[pos+2]=p_pars[pos+3]=1; p_pars[pos+1]=0; break; case 'H' : p_pars[pos+0]=p_pars[pos+1]=p_pars[pos+3]=1; p_pars[pos+2]=0; break; case 'V' : p_pars[pos+0]=p_pars[pos+1]=p_pars[pos+2]=1; p_pars[pos+3]=0; break; case 'N' : case 'X' : case '?' : case 'O' : case '-' : p_pars[pos+0]=p_pars[pos+1]=p_pars[pos+2]=p_pars[pos+3]=1;break; default : { PhyML_Printf("\n. Unknown character state : %c\n",state); Exit("\n. Init failed (data type supposed to be DNA)\n"); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk) { int i; For(i,20) p_lk[pos+i] = .0; switch(aa){ case 'A' : p_lk[pos+0]= 1.; break;/* Alanine */ case 'R' : p_lk[pos+1]= 1.; break;/* Arginine */ case 'N' : p_lk[pos+2]= 1.; break;/* Asparagine */ case 'D' : p_lk[pos+3]= 1.; break;/* Aspartic acid */ case 'C' : p_lk[pos+4]= 1.; break;/* Cysteine */ case 'Q' : p_lk[pos+5]= 1.; break;/* Glutamine */ case 'E' : p_lk[pos+6]= 1.; break;/* Glutamic acid */ case 'G' : p_lk[pos+7]= 1.; break;/* Glycine */ case 'H' : p_lk[pos+8]= 1.; break;/* Histidine */ case 'I' : p_lk[pos+9]= 1.; break;/* Isoleucine */ case 'L' : p_lk[pos+10]=1.; break;/* Leucine */ case 'K' : p_lk[pos+11]=1.; break;/* Lysine */ case 'M' : p_lk[pos+12]=1.; break;/* Methionine */ case 'F' : p_lk[pos+13]=1.; break;/* Phenylalanin */ case 'P' : p_lk[pos+14]=1.; break;/* Proline */ case 'S' : p_lk[pos+15]=1.; break;/* Serine */ case 'T' : p_lk[pos+16]=1.; break;/* Threonine */ case 'W' : p_lk[pos+17]=1.; break;/* Tryptophan */ case 'Y' : p_lk[pos+18]=1.; break;/* Tyrosine */ case 'V' : p_lk[pos+19]=1.; break;/* Valine */ case 'B' : p_lk[pos+2]= 1.; break;/* Asparagine */ case 'Z' : p_lk[pos+5]= 1.; break;/* Glutamine */ case 'X' : case '?' : case '-' : For(i,20) p_lk[pos+i] = 1.; break; default : { PhyML_Printf("\n. Unknown character state : %c\n",aa); Exit("\n. Init failed (data type supposed to be amino-acids)\n"); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars) { int i; For(i,20) p_pars[pos+i] = .0; switch(aa){ case 'A' : p_pars[pos+0] = 1; break;/* Alanine */ case 'R' : p_pars[pos+1] = 1; break;/* Arginine */ case 'N' : p_pars[pos+2] = 1; break;/* Asparagine */ case 'D' : p_pars[pos+3] = 1; break;/* Aspartic acid */ case 'C' : p_pars[pos+4] = 1; break;/* Cysteine */ case 'Q' : p_pars[pos+5] = 1; break;/* Glutamine */ case 'E' : p_pars[pos+6] = 1; break;/* Glutamic acid */ case 'G' : p_pars[pos+7] = 1; break;/* Glycine */ case 'H' : p_pars[pos+8] = 1; break;/* Histidine */ case 'I' : p_pars[pos+9] = 1; break;/* Isoleucine */ case 'L' : p_pars[pos+10] = 1; break;/* Leucine */ case 'K' : p_pars[pos+11] = 1; break;/* Lysine */ case 'M' : p_pars[pos+12] = 1; break;/* Methionine */ case 'F' : p_pars[pos+13] = 1; break;/* Phenylalanin */ case 'P' : p_pars[pos+14] = 1; break;/* Proline */ case 'S' : p_pars[pos+15] = 1; break;/* Serine */ case 'T' : p_pars[pos+16] = 1; break;/* Threonine */ case 'W' : p_pars[pos+17] = 1; break;/* Tryptophan */ case 'Y' : p_pars[pos+18] = 1; break;/* Tyrosine */ case 'V' : p_pars[pos+19] = 1; break;/* Valine */ case 'B' : p_pars[pos+2] = 1; break;/* Asparagine */ case 'Z' : p_pars[pos+5] = 1; break;/* Glutamine */ case 'X' : case '?' : case '-' : For(i,20) p_pars[pos+i] = 1; break; default : { PhyML_Printf("\n. Unknown character state : %c\n",aa); Exit("\n. Init failed (data type supposed to be amino-acids)\n"); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_Generic_Float(char *state, int ns, int state_len, int pos, phydbl *p_lk) { int i; int state_int; For(i,ns) p_lk[pos+i] = 0.; if(Is_Ambigu(state,GENERIC,state_len)) For(i,ns) p_lk[pos+i] = 1.; else { char format[6]; sprintf(format,"%%%dd",state_len); if(!sscanf(state,format,&state_int)) { PhyML_Printf("\n== state='%c'",state); PhyML_Printf("\n== Err in file %s at line %d (function '%s')\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(state_int > ns) { PhyML_Printf("\n. %s %d cstate: %.2s istate: %d state_len: %d.\n",__FILE__,__LINE__,state,state_int,state_len); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } p_lk[pos+state_int] = 1.; /* PhyML_Printf("\n. %s %d cstate: %.2s istate: %d state_len: %d ns: %d pos: %d",__FILE__,__LINE__,state,state_int,state_len,ns,pos); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_Tips_At_One_Site_Generic_Int(char *state, int ns, int state_len, int pos, short int *p_pars) { int i; int state_int; For(i,ns) p_pars[pos+i] = 0; if(Is_Ambigu(state,GENERIC,state_len)) For(i,ns) p_pars[pos+i] = 1; else { char format[6]; sprintf(format,"%%%dd",state_len); if(!sscanf(state,format,&state_int)) { PhyML_Printf("\n. state='%c'",state); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } if(state_int > ns) { PhyML_Printf("\n. %s %d cstate: %.2s istate: %d state_len: %d.\n",__FILE__,__LINE__,state,state_int,state_len); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } p_pars[pos+state_int] = 1; /* PhyML_Printf("\n* %s %d cstate: %.2s istate: %d state_len: %d ns: %d pos: %d",__FILE__,__LINE__,state,state_int,state_len,ns,pos); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_All_Partial_Lk_Scale(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d) { Update_P_Lk(tree,b_fcus,d); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree) */ /* { */ /* int i,dir; */ /* if(tree->is_mixt_tree == YES) */ /* { */ /* MIXT_Post_Order_Lk(a,d,tree); */ /* return; */ /* } */ /* dir = -1; */ /* if(d->tax) */ /* { */ /* Get_All_Partial_Lk_Scale(tree,d->b[0],a,d); */ /* return; */ /* } */ /* else */ /* { */ /* For(i,3) */ /* { */ /* if(d->v[i] != a) */ /* Post_Order_Lk(d,d->v[i],tree); */ /* else dir = i; */ /* } */ /* Get_All_Partial_Lk_Scale(tree,d->b[dir],a,d); */ /* } */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Post_Order_Lk(t_node *a, t_node *d, t_tree *tree) { int i,dir; dir = -1; if(d->tax) return; else { if(tree->is_mixt_tree) { MIXT_Post_Order_Lk(a,d,tree); return; } if(tree->n_root) { For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) Post_Order_Lk(d,d->v[i],tree); else dir = i; } } else { For(i,3) { if(d->v[i] != a) Post_Order_Lk(d,d->v[i],tree); else dir = i; } } if(tree->ignore_root == NO && d->b[dir] == tree->e_root) { if(d == tree->n_root->v[1]) Get_All_Partial_Lk_Scale(tree,tree->n_root->b[1],tree->n_root,d); else Get_All_Partial_Lk_Scale(tree,tree->n_root->b[2],tree->n_root,d); } else { Get_All_Partial_Lk_Scale(tree,d->b[dir],a,d); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Pre_Order_Lk(t_node *a, t_node *d, t_tree *tree) { int i; if(d->tax) return; else { if(tree->is_mixt_tree) { MIXT_Pre_Order_Lk(a,d,tree); return; } if(tree->n_root) { For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { Get_All_Partial_Lk_Scale(tree,d->b[i],d->v[i],d); Pre_Order_Lk(d,d->v[i],tree); } } } else { For(i,3) { if(d->v[i] != a) { Get_All_Partial_Lk_Scale(tree,d->b[i],d->v[i],d); Pre_Order_Lk(d,d->v[i],tree); } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Lk(t_edge *b, t_tree *tree) { int br; if(b == NULL && tree->mod->s_opt->curr_opt_free_rates == YES) { tree->mod->s_opt->curr_opt_free_rates = NO; Optimize_Free_Rate_Weights(tree,YES,YES); tree->mod->s_opt->curr_opt_free_rates = YES; } if(tree->is_mixt_tree) { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif return MIXT_Lk(b,tree); } tree->old_lnL = tree->c_lnL; #ifdef PHYREX PHYREX_Ldsk_To_Tree(tree); #endif #if (defined PHYTIME || defined INVITEE || defined PHYREX) if((tree->rates) && (tree->rates->bl_from_rt)) RATES_Update_Cur_Bl(tree); #endif if(tree->rates && tree->io->lk_approx == NORMAL) { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif tree->c_lnL = Lk_Normal_Approx(tree); return tree->c_lnL; } if(!b) Set_Model_Parameters(tree->mod); Set_Br_Len_Var(tree); if(tree->mod->s_opt->skip_tree_traversal == NO) { if(!b)//Update the PMat for all edges { For(br,2*tree->n_otu-3) { Update_PMat_At_Given_Edge(tree->a_edges[br],tree); } if(tree->n_root && tree->ignore_root == NO) { Update_PMat_At_Given_Edge(tree->n_root->b[1],tree); Update_PMat_At_Given_Edge(tree->n_root->b[2],tree); } } else//Update the PMat for a specific edge { Update_PMat_At_Given_Edge(b,tree); } if(!b) { if(tree->n_root) { if(tree->ignore_root == NO) { Post_Order_Lk(tree->n_root,tree->n_root->v[1],tree); Post_Order_Lk(tree->n_root,tree->n_root->v[2],tree); Update_P_Lk(tree,tree->n_root->b[1],tree->n_root); Update_P_Lk(tree,tree->n_root->b[2],tree->n_root); if(tree->both_sides == YES) { Pre_Order_Lk(tree->n_root,tree->n_root->v[2],tree); Pre_Order_Lk(tree->n_root,tree->n_root->v[1],tree); } } else { Post_Order_Lk(tree->e_root->rght,tree->e_root->left,tree); Post_Order_Lk(tree->e_root->left,tree->e_root->rght,tree); if(tree->both_sides == YES) { Pre_Order_Lk(tree->e_root->rght,tree->e_root->left,tree); Pre_Order_Lk(tree->e_root->left,tree->e_root->rght,tree); } } } else { Post_Order_Lk(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); if(tree->both_sides == YES) Pre_Order_Lk(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); } } } if(!b) { if(tree->n_root) { if(tree->ignore_root == NO) b = (tree->n_root->v[1]->tax == NO)?(tree->n_root->b[2]):(tree->n_root->b[1]); else b = tree->e_root; } else b = tree->a_nodes[0]->b[0]; } tree->c_lnL = .0; tree->sum_min_sum_scale = .0; #ifdef BEAGLE calc_edgelks_beagle(b, tree); #else int n_patterns,ambiguity_check,state; n_patterns = tree->n_pattern; For(tree->curr_site,n_patterns) { ambiguity_check = -1; state = -1; if(tree->data->wght[tree->curr_site] > SMALL) { if((b->rght->tax) && (tree->mod->s_opt->greedy == NO)) { ambiguity_check = b->rght->c_seq->is_ambigu[tree->curr_site]; if(ambiguity_check == NO) { state = b->rght->c_seq->d_state[tree->curr_site]; } } if(tree->mod->use_m4mod) ambiguity_check = YES; Lk_Core(state,ambiguity_check,b,tree); /* fprintf(stdout,"site %d lnL: %g:%d %g\n",tree->curr_site,tree->c_lnL_sorted[tree->curr_site],tree->data->wght[tree->curr_site],tree->c_lnL); */ /* fflush(stdout); */ } } #endif /* Qksort(tree->c_lnL_sorted,NULL,0,n_patterns-1); */ /* tree->c_lnL = .0; */ /* For(tree->curr_site,n_patterns) */ /* { */ /* tree->c_lnL += tree->c_lnL_sorted[tree->curr_site]; */ /* } */ Adjust_Min_Diff_Lk(tree); // Print_All_Edge_PMats(tree); // Print_All_Edge_Likelihoods(tree); // DUMP_D(tree->c_lnL); return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Core of the likelihood calculcation. Assume that the partial likelihoods on both sides of t_edge *b are up-to-date. Calculate the log-likelihood at one site. */ phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree) { phydbl log_site_lk; phydbl site_lk_cat/*rate specific site lk*/, site_lk, inv_site_lk; int fact_sum_scale; phydbl sum; int catg/*Index of the current rate classes*/,ns/*size of the state-space*/,k,l,site/*index of the current site in the MSA*/; int dim1,dim2,dim3; int exponent; int num_prec_issue; #ifdef BEAGLE dim1 = tree->n_pattern * tree->mod->ns; #else dim1 = tree->mod->ras->n_catg * tree->mod->ns;//Dimension of a matrix L that holds rate-specific character likelihoods. IOW, L[ij] is the likelihood of character j in rate class i #endif dim2 = tree->mod->ns; dim3 = tree->mod->ns * tree->mod->ns;//Dimensions of the transition prob. matrix log_site_lk = .0; site_lk = .0; site_lk_cat = .0; site = tree->curr_site; ns = tree->mod->ns; /* Skip this if no tree traveral was required, i.e. likelihood in each class of the mixture is already up to date */ if(tree->mod->s_opt->skip_tree_traversal == NO) { /* Actual likelihood calculation */ /* For all classes of rates */ For(catg,tree->mod->ras->n_catg) { site_lk_cat = .0; /* b is an external edge */ if((b->rght->tax) && (!tree->mod->s_opt->greedy)) /* By convention, tips are always on the right of an external edge */ { if(!ambiguity_check)/* If the character observed at the tip is NOT ambiguous: ns x 1 terms to consider */ { sum = .0; For(l,ns) { sum += b->Pij_rr[(catg*dim3)+(state*dim2)+l] * b->p_lk_left[(site*dim1)+(catg*dim2)+l]; } site_lk_cat += sum * tree->mod->e_frq->pi->v[state]; } else /* If the character observed at the tip is ambiguous: ns x ns terms to consider */ { For(k,ns) { sum = .0; if(b->p_lk_tip_r[site*dim2+k] > .0) /* Only bother ascending into the subtrees if the likelihood of state k, at site "site*dim2" is > 0 */ { For(l,ns) { sum += b->Pij_rr[(catg*dim3)+(k*dim2)+l] * b->p_lk_left[(site*dim1)+(catg*dim2)+l]; } site_lk_cat += sum * tree->mod->e_frq->pi->v[k] * b->p_lk_tip_r[site*dim2+k]; } } } } else /* b is an internal edge: ns x ns terms to consider */ { For(k,ns) { sum = .0; if(b->p_lk_rght[(site*dim1)+(catg*dim2)+k] > .0) //Only bother descending into the subtrees if the likelihood of state k, at site "site*dim2" is > 0 { For(l,ns) { sum += b->Pij_rr[(catg*dim3)+(k*dim2)+l] * //"catg*dim3" offsets into a rate-specific flat 4*4 DNA matrix P. Then, P[i,j] is given by "k*4+l" b->p_lk_left[(site*dim1)+(catg*dim2)+l];//"site*dim1" offsets into a rate-specific flat num_rates*4 matrix L. Then, L[i,j] is given by "catg*dim2+l" } site_lk_cat += sum * tree->mod->e_frq->pi->v[k] * b->p_lk_rght[(site*dim1)+(catg*dim2)+k]; } } } tree->site_lk_cat[catg] = site_lk_cat; } /* site likelihood for all rate classes */ Pull_Scaling_Factors(site,b,tree); } fact_sum_scale = tree->fact_sum_scale[site]; //Likelihood of the site; is the sum of the individual rate specific likelihoods site_lk = .0; For(catg,tree->mod->ras->n_catg) { site_lk += tree->unscaled_site_lk_cat[catg*tree->n_pattern + site]* tree->mod->ras->gamma_r_proba->v[catg]; //density } if(tree->mod->ras->invar == YES) { num_prec_issue = NO; inv_site_lk = Invariant_Lk(fact_sum_scale,site,&num_prec_issue,tree); if(num_prec_issue == YES) // inv_site_lk >> site_lk { site_lk = inv_site_lk * tree->mod->ras->pinvar->v; } else { site_lk = site_lk * (1. - tree->mod->ras->pinvar->v) + inv_site_lk * tree->mod->ras->pinvar->v; } } log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale; // log_site_lk = log(site_lk_scaled / 2^(left_subtree+right_subtree)) // Calculation of the site likelihood (using scaling factors)... int piecewise_exponent; phydbl multiplier; if(fact_sum_scale >= 0) { tree->cur_site_lk[site] = site_lk; exponent = -fact_sum_scale; do { piecewise_exponent = MAX(exponent,-63); multiplier = 1. / (phydbl)((unsigned long long)(1) << -piecewise_exponent); tree->cur_site_lk[site] *= multiplier; exponent -= piecewise_exponent; } while(exponent != 0); } else { //In some cases fact_sum_scale can be negative. If you rescale the partials of two independent subtrees and make some of //these numbers large in order to avoid underflow, then there is a chance that when multiplied them together you will //get an overflow, in which case fact_sum_scale can become negative. tree->cur_site_lk[site] = site_lk; exponent = fact_sum_scale; do { piecewise_exponent = MIN(exponent,63); multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent); tree->cur_site_lk[site] *= multiplier; exponent -= piecewise_exponent; } while(exponent != 0); } // ... or using the log-likelihood if(isinf(site_lk) || isnan(site_lk)) { tree->cur_site_lk[site] = EXP(log_site_lk); } if(isinf(log_site_lk) || isnan(log_site_lk)) { PhyML_Printf("\n== Site = %d",site); PhyML_Printf("\n== Invar = %d",tree->data->invar[site]); PhyML_Printf("\n== Mixt = %d",tree->is_mixt_tree); PhyML_Printf("\n== Lk = %G log(Lk) = %f < %G",site_lk,log_site_lk,-BIG); For(catg,tree->mod->ras->n_catg) PhyML_Printf("\n== rr=%f p=%f",tree->mod->ras->gamma_rr->v[catg],tree->mod->ras->gamma_r_proba->v[catg]); PhyML_Printf("\n== Pinv = %G",tree->mod->ras->pinvar->v); PhyML_Printf("\n== Bl mult = %G",tree->mod->br_len_mult->v); PhyML_Printf("\n== fact_sum_scale = %d",fact_sum_scale); PhyML_Printf("\n== n_catg: %d",tree->mod->ras->n_catg); if(tree->mod->whichmodel == GTR || tree->mod->whichmodel == CUSTOM) { int i,j; PhyML_Printf("\n== Rate matrix\n"); For(i,tree->mod->ns) { For(j,tree->mod->ns) { PhyML_Printf("%12G ",i,tree->mod->r_mat->qmat->v[i*4+j]); } PhyML_Printf("\n"); } fflush(NULL); PhyML_Printf("\n== Relative rates\n"); For(i,tree->mod->ns*(tree->mod->ns-1)/2) { PhyML_Printf("\n== rr[%3d]: %12G %12G",i,tree->mod->r_mat->rr->v[i],tree->mod->r_mat->rr_val->v[i]); } fflush(NULL); } /* int i; */ /* For(i,2*tree->n_otu-3) */ /* { */ /* PhyML_Printf("\n. b%3d->l->v = %f %f [%G] %f %f %f %f [%s]",i, */ /* tree->a_edges[i]->l->v, */ /* tree->a_edges[i]->gamma_prior_mean, */ /* tree->a_edges[i]->gamma_prior_var, */ /* tree->rates->nd_t[tree->a_edges[i]->left->num], */ /* tree->rates->nd_t[tree->a_edges[i]->rght->num], */ /* tree->rates->br_r[tree->a_edges[i]->left->num], */ /* tree->rates->br_r[tree->a_edges[i]->rght->num], */ /* tree->a_edges[i] == tree->e_root ? "YES" : "NO"); */ /* fflush(NULL); */ /* } */ Print_Site(tree->data,site,tree->n_otu,"\n",tree->mod->io->state_len,stdout); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } /* Multiply log likelihood by the number of times this site pattern is found in the data */ tree->c_lnL_sorted[site] = tree->data->wght[site]*log_site_lk; tree->c_lnL += tree->data->wght[site]*log_site_lk; return log_site_lk; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* phydbl Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree) */ /* { */ /* int n_patterns; */ /* if(tree->is_mixt_tree) return MIXT_Lk_At_Given_Edge(tree); */ /* n_patterns = tree->n_pattern; */ /* #ifdef PHYTIME */ /* if((tree->rates) && (tree->rates->bl_from_rt)) RATES_Update_Cur_Bl(tree); */ /* #endif */ /* Check_Br_Len_Bounds(tree); */ /* if(tree->rates && tree->io->lk_approx == NORMAL) */ /* { */ /* tree->c_lnL = Lk_Normal_Approx(tree); */ /* return tree->c_lnL; */ /* } */ /* Update_PMat_At_Given_Edge(b_fcus,tree); */ /* if(b_fcus->left->tax) */ /* { */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* tree->c_lnL = .0; */ /* tree->sum_min_sum_scale = .0; */ /* For(tree->curr_site,n_patterns) */ /* if(tree->data->wght[tree->curr_site] > SMALL) */ /* Lk_Core(b_fcus,tree); */ /* /\* Qksort(tree->c_lnL_sorted,NULL,0,n_patterns-1); *\/ */ /* /\* tree->c_lnL = .0; *\/ */ /* /\* For(tree->curr_site,n_patterns) *\/ */ /* /\* { *\/ */ /* /\* tree->c_lnL += tree->c_lnL_sorted[tree->curr_site]; *\/ */ /* /\* } *\/ */ /* Adjust_Min_Diff_Lk(tree); */ /* return tree->c_lnL; */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Rate_Correction(int exponent, phydbl *site_lk_cat, t_tree *tree) { int piecewise_exponent; phydbl multiplier; if(exponent >= 0) { /*! Multiply by 2^exponent */ do { piecewise_exponent = MIN(exponent,63); multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent); (*site_lk_cat) *= multiplier; exponent -= piecewise_exponent; } while(exponent != 0); } else { do { piecewise_exponent = MAX(exponent,-63); multiplier = 1. / (phydbl)((unsigned long long)(1) << -piecewise_exponent); (*site_lk_cat) *= multiplier; exponent -= piecewise_exponent; } while(exponent != 0); } if(isinf(*site_lk_cat)) { PhyML_Printf("\n== Numerical precision issue alert."); PhyML_Printf("\n== exponent: %d site_lk_cat: %f", exponent,*site_lk_cat); PhyML_Printf("\n== File %s at line %d\n\n",__FILE__,__LINE__); (*site_lk_cat) = BIG / 10; } if(*site_lk_cat < SMALL) { if(tree->mod->ras->n_catg == 1) { PhyML_Printf("\n== site_lk_cat = %G",*site_lk_cat); PhyML_Printf("\n== exponent: %d", exponent); PhyML_Printf("\n== Numerical precision issue alert."); PhyML_Printf("\n== File %s at line %d (funtction '%s')\n",__FILE__,__LINE__,__FUNCTION__); PhyML_Printf("\n== %s",Write_Tree(tree,NO)); Exit("\n"); } (*site_lk_cat) = .0; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the scaled likelihood for invariable sites phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree) { int exponent,piecewise_exponent; phydbl multiplier; phydbl inv_site_lk = 0.; (*num_prec_issue) = NO; /* The substitution model does include invariable sites */ if(tree->mod->ras->invar == YES) { /* The site is invariant */ if(tree->data->invar[site] > -0.5) { inv_site_lk = tree->mod->e_frq->pi->v[tree->data->invar[site]]; /* printf("\n. inv_site_lk = %f [%c] [%d]",inv_site_lk,tree->data->c_seq[0]->state[site],tree->data->invar[site]); */ if(tree->apply_lk_scaling == YES) { exponent = fact_sum_scale; do { piecewise_exponent = MIN(exponent,63); multiplier = (phydbl)((unsigned long long)(1) << piecewise_exponent); inv_site_lk *= multiplier; exponent -= piecewise_exponent; } while(exponent != 0); } /* Update the value of site_lk */ if(isinf(inv_site_lk)) // P(D|r=0) >> P(D|r>0) => assume P(D) = P(D|r=0)P(r=0) { int i; PhyML_Printf("\n== fact_sum_scale: %d",fact_sum_scale); PhyML_Printf("\n== pi: %f",tree->mod->e_frq->pi->v[tree->data->invar[site]]); For(i,tree->mod->ns) PhyML_Printf("\n== pi %d: %f",i,tree->mod->e_frq->pi->v[i]); PhyML_Printf("\n== Numerical precision issue alert."); PhyML_Printf("\n== File %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); (*num_prec_issue) = YES; } } } return inv_site_lk; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Update partial likelihood on edge b on the side of b where node d lies. */ void Update_P_Lk(t_tree *tree, t_edge *b, t_node *d) { if(tree->is_mixt_tree) { MIXT_Update_P_Lk(tree,b,d); return; } if((tree->io->do_alias_subpatt == YES) && (tree->update_alias_subpatt == YES)) Alias_One_Subpatt((d==b->left)?(b->rght):(b->left),d,tree); if(d->tax) return; #ifdef BEAGLE update_beagle_partials(tree, b, d); #else if(tree->mod->use_m4mod == NO) { if(tree->io->datatype == NT) { Update_P_Lk_Nucl(tree,b,d); } else if(tree->io->datatype == AA) { Update_P_Lk_AA(tree,b,d); } else { Update_P_Lk_Generic(tree,b,d); } } else { Update_P_Lk_Generic(tree,b,d); } #endif // Print_Edge_Likelihoods(tree, b, false); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifndef BEAGLE void Update_P_Lk_Generic(t_tree *tree, t_edge *b, t_node *d) { /* | |<- b | d / \ / \ / \ n_v1 n_v2 */ t_node *n_v1, *n_v2; phydbl p1_lk1,p2_lk2; phydbl *p_lk,*p_lk_v1,*p_lk_v2; phydbl *Pij1,*Pij2; int *sum_scale, *sum_scale_v1, *sum_scale_v2; int sum_scale_v1_val, sum_scale_v2_val; int i,j; int catg,site; int n_patterns; short int ambiguity_check_v1,ambiguity_check_v2; int state_v1,state_v2; int NsNg, Ns, NsNs; phydbl curr_scaler; int curr_scaler_pow, piecewise_scaler_pow; phydbl p_lk_lim_inf; phydbl smallest_p_lk; int *p_lk_loc; p_lk_lim_inf = (phydbl)P_LK_LIM_INF; NsNg = tree->mod->ras->n_catg * tree->mod->ns; Ns = tree->mod->ns; NsNs = tree->mod->ns * tree->mod->ns; state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; sum_scale_v1_val = sum_scale_v2_val = 0; p1_lk1 = p2_lk2 = .0; if(d->tax) { PhyML_Printf("\n== t_node %d is a leaf...",d->num); PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } n_patterns = tree->n_pattern; n_v1 = n_v2 = NULL; p_lk = p_lk_v1 = p_lk_v2 = NULL; Pij1 = Pij2 = NULL; sum_scale_v1 = sum_scale_v2 = NULL; p_lk_loc = NULL; Set_All_P_Lk(&n_v1,&n_v2, &p_lk,&sum_scale,&p_lk_loc, &Pij1,&p_lk_v1,&sum_scale_v1, &Pij2,&p_lk_v2,&sum_scale_v2, d,b,tree); /* For every site in the alignment */ For(site,n_patterns) { state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; if(tree->mod->s_opt->greedy == NO) { /* n_v1 and n_v2 are tip nodes */ if(n_v1 && n_v1->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v1 = n_v1->c_seq->is_ambigu[site]; /* if(ambiguity_check_v1 == NO) state_v1 = Get_State_From_P_Pars(n_v1->b[0]->p_lk_tip_r,site*Ns,tree); */ if(ambiguity_check_v1 == NO) state_v1 = n_v1->c_seq->d_state[site]; } if(n_v2 && n_v2->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site]; /* ambiguity_check_v2 = tree->data->c_seq[n_v2->num]->is_ambigu[site]; */ /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_P_Pars(n_v2->b[0]->p_lk_tip_r,site*Ns,tree); */ if(ambiguity_check_v2 == NO) state_v2 = n_v2->c_seq->d_state[site]; } } if(tree->mod->use_m4mod) { ambiguity_check_v1 = YES; ambiguity_check_v2 = YES; } if(p_lk_loc[site] < site) /* Have we seen this pattern before? */ { Copy_P_Lk(p_lk,p_lk_loc[site],site,tree); Copy_Scale(sum_scale,p_lk_loc[site],site,tree); } else { /* For all the rate classes */ For(catg,tree->mod->ras->n_catg) { if(tree->mod->ras->skip_rate_cat[catg] == YES) continue; smallest_p_lk = BIG; /* For all the states at node d */ For(i,tree->mod->ns) { p1_lk1 = .0; if(n_v1) { /* n_v1 is a tip */ if((n_v1->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v1 == NO) { /* For the (non-ambiguous) state at node n_v1 */ p1_lk1 = Pij1[catg*NsNs+i*Ns+state_v1]; } else { /* For all the states at node n_v1 */ For(j,tree->mod->ns) { p1_lk1 += Pij1[catg*NsNs+i*Ns+j] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*Ns+j]; } } } /* n_v1 is an internal node */ else { /* For the states at node n_v1 */ For(j,tree->mod->ns) { p1_lk1 += Pij1[catg*NsNs+i*Ns+j] * p_lk_v1[site*NsNg+catg*Ns+j]; } } } else { p1_lk1 = 1.0; } p2_lk2 = .0; /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/ if(n_v2) { /* n_v2 is a tip */ if((n_v2->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v2 == NO) { /* For the (non-ambiguous) state at node n_v2 */ p2_lk2 = Pij2[catg*NsNs+i*Ns+state_v2]; } else { /* For all the states at node n_v2 */ For(j,tree->mod->ns) { p2_lk2 += Pij2[catg*NsNs+i*Ns+j] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*Ns+j]; } } } /* n_v2 is an internal node */ else { /* For all the states at node n_v2 */ For(j,tree->mod->ns) { p2_lk2 += Pij2[catg*NsNs+i*Ns+j] * p_lk_v2[site*NsNg+catg*Ns+j]; } } } else { p2_lk2 = 1.0; } p_lk[site*NsNg+catg*Ns+i] = p1_lk1 * p2_lk2; /* PhyML_Printf("\n+ %G",p_lk[site*NsNg+catg*Ns+i]); */ if(p_lk[site*NsNg+catg*Ns+i] < smallest_p_lk) smallest_p_lk = p_lk[site*NsNg+catg*Ns+i] ; } /* Current scaling values at that site */ sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[catg*n_patterns+site]):(0); sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[catg*n_patterns+site]):(0); sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val; /* PhyML_Printf("\n@ %d",sum_scale[catg*n_patterns+site]); */ /* Scaling. For details read utilities.h */ if(smallest_p_lk < p_lk_lim_inf) { curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2; curr_scaler = (phydbl)((unsigned long long)(1) << curr_scaler_pow); /* if(fabs(curr_scaler_pow) > 63 || fabs(curr_scaler_pow) > 63) */ /* { */ /* PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); */ /* PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); */ /* PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__); */ /* Warn_And_Exit("\n"); */ /* } */ sum_scale[catg*n_patterns+site] += curr_scaler_pow; do { piecewise_scaler_pow = MIN(curr_scaler_pow,63); curr_scaler = (phydbl)((unsigned long long)(1) << piecewise_scaler_pow); For(i,tree->mod->ns) { p_lk[site*NsNg+catg*Ns+i] *= curr_scaler; if(p_lk[site*NsNg+catg*Ns+i] > BIG) { PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); PhyML_Printf("\n. Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit("\n"); } } curr_scaler_pow -= piecewise_scaler_pow; } while(curr_scaler_pow != 0); } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_P_Lk_Nucl(t_tree *tree, t_edge *b, t_node *d) { /* | |<- b | d / \ / \ / \ n_v1 n_v2 */ t_node *n_v1, *n_v2;//d's "left" and "right" neighbor nodes phydbl p1_lk1,p2_lk2;//Partial likelihood at d's "left" neighbor, d's "right" neighbor phydbl *p_lk,*p_lk_v1,*p_lk_v2;//Partial likelihood vector of node d, d's "left" neighbor, d's "right" neighbor. We fill *p_lk, and assume *p_lk_v1 and *p_lk_v2 are already filled. phydbl *Pij1,*Pij2; int *sum_scale, *sum_scale_v1, *sum_scale_v2; int sum_scale_v1_val, sum_scale_v2_val; int i;//index over the number of states int catg/*index over the number of rate categories*/,site; int n_patterns;//Number of distinct site patterns short int ambiguity_check_v1,ambiguity_check_v2; int state_v1,state_v2; int dim1, dim2, dim3; phydbl curr_scaler; int curr_scaler_pow, piecewise_scaler_pow; phydbl p_lk_lim_inf; phydbl smallest_p_lk; phydbl p0,p1,p2,p3; int *p_lk_loc;//Suppose site j, of a certain subtree, has "A" on one tip, and "C" on the other. If you come across this pattern again at site imod->ras->n_catg * tree->mod->ns;//Dimension of a matrix L that holds rate-specific character likelihoods. IOW, L[ij] is the likelihood of character j in rate class i dim2 = tree->mod->ns; dim3 = tree->mod->ns * tree->mod->ns;//Dimensions of the transition prob. matrix state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; sum_scale_v1_val = sum_scale_v2_val = 0; p1_lk1 = p2_lk2 = .0; curr_scaler = .0; curr_scaler_pow = piecewise_scaler_pow = 0; if(d->tax) { PhyML_Printf("\n== t_node %d is a leaf...",d->num); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } n_patterns = tree->n_pattern; n_v1 = n_v2 = NULL; p_lk = p_lk_v1 = p_lk_v2 = NULL; Pij1 = Pij2 = NULL; sum_scale_v1 = sum_scale_v2 = NULL; p_lk_loc = NULL; Set_All_P_Lk(&n_v1,&n_v2, &p_lk,&sum_scale,&p_lk_loc, &Pij1,&p_lk_v1,&sum_scale_v1, &Pij2,&p_lk_v2,&sum_scale_v2, d,b,tree); /* For every site in the alignment */ For(site,n_patterns) { state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; if(!tree->mod->s_opt->greedy) { /* n_v1 and n_v2 are tip nodes */ if(n_v1 && n_v1->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v1 = n_v1->c_seq->is_ambigu[site]; if(ambiguity_check_v1 == NO) state_v1 = n_v1->c_seq->d_state[site]; } if(n_v2 && n_v2->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site]; if(ambiguity_check_v2 == NO) state_v2 = n_v2->c_seq->d_state[site]; } if(tree->mod->augmented == YES && n_v1 && n_v1->tax == NO) { state_v1 = Assign_State(n_v1->c_seq_anc->state+site*tree->mod->io->state_len, tree->io->datatype, tree->mod->io->state_len); } if(tree->mod->augmented == YES && n_v2 && n_v2->tax == NO) { state_v2 = Assign_State(n_v2->c_seq_anc->state+site*tree->mod->io->state_len, tree->io->datatype, tree->mod->io->state_len); } } if(tree->mod->use_m4mod) { ambiguity_check_v1 = YES; ambiguity_check_v2 = YES; } if(p_lk_loc[site] < site) { Copy_P_Lk(p_lk,p_lk_loc[site],site,tree); Copy_Scale(sum_scale,p_lk_loc[site],site,tree); } else { /* For all the rate classes */ For(catg,tree->mod->ras->n_catg) { smallest_p_lk = BIG; /* For all states at node d */ For(i,tree->mod->ns) { if(tree->mod->augmented == YES) { For(i,tree->mod->ns) p_lk[site*dim1+catg*dim2+i] = 0.0; i = Assign_State(d->c_seq_anc->state+site*tree->mod->io->state_len, tree->io->datatype, tree->mod->io->state_len); } p1_lk1 = .0; if(n_v1) { /* n_v1 is a tip */ if((n_v1->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v1 == NO) { /* For the (non-ambiguous) state at node n_v1 */ p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1]; assert(!isnan(p1_lk1)); /* if(isnan(p1_lk1)) */ /* { */ /* PhyML_Printf("\n== Tree %d",tree->tree_num); */ /* PhyML_Printf("\n== catg=%d dim3=%d dim2=%d i=%d state_v1=%d",catg,dim3,dim2,i,state_v1); */ /* PhyML_Printf("\n== Pij1[0] = %G l = %G",Pij1[0],b->l->v); */ /* Print_Model(tree->mod); */ /* Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ /* } */ } else { /* For all the states at node n_v1 */ p0=Pij1[catg*dim3+i*dim2+0] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+0]; p1=Pij1[catg*dim3+i*dim2+1] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+1]; p2=Pij1[catg*dim3+i*dim2+2] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+2]; p3=Pij1[catg*dim3+i*dim2+3] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+3]; p1_lk1 = p0+p1+p2+p3; assert(!isnan(p1_lk1)); /* if(isnan(p1_lk1)) */ /* { */ /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */ /* PhyML_Printf("\n== Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__); */ /* Exit("\n"); */ /* } */ } } /* n_v1 is an internal node */ else { //"catg*dim3" offsets into a rate-specific flat 4*4 DNA matrix P. Then, P[i,j] is given by "i*4+l" //"site*dim1" offsets into a rate-specific flat num_rates*4 matrix L. Then, L[i,j] is given by "catg*dim2+l" if(tree->mod->augmented == YES) { p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1] * p_lk_v1[site*dim1+catg*dim2+state_v1]; } else { p0=Pij1[catg*dim3+i*dim2+0] * p_lk_v1[site*dim1+catg*dim2+0]; p1=Pij1[catg*dim3+i*dim2+1] * p_lk_v1[site*dim1+catg*dim2+1]; p2=Pij1[catg*dim3+i*dim2+2] * p_lk_v1[site*dim1+catg*dim2+2]; p3=Pij1[catg*dim3+i*dim2+3] * p_lk_v1[site*dim1+catg*dim2+3]; p1_lk1 = p0+p1+p2+p3; } if(isnan(p1_lk1)) { /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */ PhyML_Printf("\n== Err. in file %s at line %d.",__FILE__,__LINE__); Warn_And_Exit("\n"); } } } else { p1_lk1 = 1.0; } p2_lk2 = .0; /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/ if(n_v2) { /* n_v2 is a tip */ if((n_v2->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v2 == NO) { /* For the (non-ambiguous) state at node n_v2 */ p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2]; assert(!isnan(p2_lk2)); /* if(isnan(p2_lk2)) */ /* { */ /* PhyML_Printf("\n== Tree %d",tree->tree_num); */ /* PhyML_Printf("\n== catg=%d dim3=%d dim2=%d i=%d state_v2=%d",catg,dim3,dim2,i,state_v2); */ /* PhyML_Printf("\n== Pij2[0] = %G l = %G",Pij2[0],b->l->v); */ /* Print_Model(tree->mod); */ /* Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ /* } */ } else { /* For all the states at node n_v2 */ p0=Pij2[catg*dim3+i*dim2+0] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+0]; p1=Pij2[catg*dim3+i*dim2+1] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+1]; p2=Pij2[catg*dim3+i*dim2+2] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+2]; p3=Pij2[catg*dim3+i*dim2+3] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+3]; p2_lk2 = p0+p1+p2+p3; assert(!isnan(p2_lk2)); /* if(isnan(p2_lk2)) */ /* { */ /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */ /* PhyML_Printf("\n== Err. in file %s at line %d.",__FILE__,__LINE__); */ /* Warn_And_Exit("\n"); */ /* } */ } } /* n_v2 is an internal node */ else { if(tree->mod->augmented == YES) { p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2] * p_lk_v2[site*dim1+catg*dim2+state_v2]; } else { /* For all the states at node n_v2 */ p0=Pij2[catg*dim3+i*dim2+0] * p_lk_v2[site*dim1+catg*dim2+0]; p1=Pij2[catg*dim3+i*dim2+1] * p_lk_v2[site*dim1+catg*dim2+1]; p2=Pij2[catg*dim3+i*dim2+2] * p_lk_v2[site*dim1+catg*dim2+2]; p3=Pij2[catg*dim3+i*dim2+3] * p_lk_v2[site*dim1+catg*dim2+3]; p2_lk2 = p0+p1+p2+p3; } if(isnan(p2_lk2)) { PhyML_Printf("\n== %f %f",b->l->v,b->l->v*b->l->v*tree->mod->l_var_sigma); /* PhyML_Printf("\n== p0=%f p1=%f p2=%f p3=%f",p0,p1,p2,p3); */ PhyML_Printf("\n== Pij2[0]=%f Pij2[1]=%f Pij2[2]=%f Pij2[3]=%f",Pij2[catg*dim3+i*dim2+0],Pij2[catg*dim3+i*dim2+1],Pij2[catg*dim3+i*dim2+2],Pij2[catg*dim3+i*dim2+3]); PhyML_Printf("\n== Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit("\n"); } } } else { p2_lk2 = 1.0; } /* Partial likelihood of character "i" at site "site" under rate "catg" */ p_lk[site*dim1+catg*dim2+i] = p1_lk1 * p2_lk2; if(p_lk[site*dim1+catg*dim2+i] < smallest_p_lk) smallest_p_lk = p_lk[site*dim1+catg*dim2+i] ; if(tree->mod->augmented == YES) break; } /* Current scaling values at that site */ sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[catg*n_patterns+site]):(0); sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[catg*n_patterns+site]):(0); sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val; /* Scaling */ if(smallest_p_lk < p_lk_lim_inf && tree->mod->augmented == NO) { curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2; curr_scaler = (phydbl)((unsigned long long)(1) << curr_scaler_pow); sum_scale[catg*n_patterns+site] += curr_scaler_pow; // fprintf(stderr,"\n%d",sum_scale[catg*n_patterns+site]); do { piecewise_scaler_pow = MIN(curr_scaler_pow,63); curr_scaler = (phydbl)((unsigned long long)(1) << piecewise_scaler_pow); For(i,tree->mod->ns) { p_lk[site*dim1+catg*dim2+i] *= curr_scaler; if(p_lk[site*dim1+catg*dim2+i] > BIG) { PhyML_Printf("\n== p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); PhyML_Printf("\n== curr_scaler_pow = %d",curr_scaler_pow); PhyML_Printf("\n== Err. in file %s at line %d (function '%s').",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } // fprintf(stderr,"\n%e",p_lk[site*dim1+catg*dim2+i]); } curr_scaler_pow -= piecewise_scaler_pow; } while(curr_scaler_pow != 0); } } } } // fprintf(stdout, "Updated partials:");fflush(stdout); // Dump_Arr_D(p_lk, tree->mod->ras->n_catg*tree->mod->ns*tree->n_pattern); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_P_Lk_AA(t_tree *tree, t_edge *b, t_node *d) { /* | |<- b | d / \ / \ / \ n_v1 n_v2 */ t_node *n_v1, *n_v2; phydbl p1_lk1,p2_lk2; phydbl *p_lk,*p_lk_v1,*p_lk_v2; phydbl *Pij1,*Pij2; int *sum_scale, *sum_scale_v1, *sum_scale_v2; int sum_scale_v1_val, sum_scale_v2_val; int i; int catg,site; int n_patterns; short int ambiguity_check_v1,ambiguity_check_v2; int state_v1,state_v2; int dim1, dim2, dim3; phydbl curr_scaler; int curr_scaler_pow, piecewise_scaler_pow; phydbl p_lk_lim_inf; phydbl smallest_p_lk; phydbl p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19; int *p_lk_loc; p_lk_lim_inf = (phydbl)P_LK_LIM_INF; dim1 = tree->mod->ras->n_catg * tree->mod->ns; dim2 = tree->mod->ns; dim3 = tree->mod->ns * tree->mod->ns; state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; sum_scale_v1_val = sum_scale_v2_val = 0; p1_lk1 = p2_lk2 = .0; if(d->tax) { PhyML_Printf("\n== t_node %d is a leaf...",d->num); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit("\n"); } n_patterns = tree->n_pattern; n_v1 = n_v2 = NULL; p_lk = p_lk_v1 = p_lk_v2 = NULL; Pij1 = Pij2 = NULL; sum_scale_v1 = sum_scale_v2 = NULL; p_lk_loc = NULL; Set_All_P_Lk(&n_v1,&n_v2, &p_lk,&sum_scale,&p_lk_loc, &Pij1,&p_lk_v1,&sum_scale_v1, &Pij2,&p_lk_v2,&sum_scale_v2, d,b,tree); /* For every site in the alignment */ For(site,n_patterns) { state_v1 = state_v2 = -1; ambiguity_check_v1 = ambiguity_check_v2 = NO; if(!tree->mod->s_opt->greedy) { /* n_v1 and n_v2 are tip nodes */ if(n_v1 && n_v1->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v1 = n_v1->c_seq->is_ambigu[site]; /* if(ambiguity_check_v1 == NO) state_v1 = Get_State_From_P_Pars(n_v1->b[0]->p_lk_tip_r,site*dim2,tree); */ if(ambiguity_check_v1 == NO) state_v1 = n_v1->c_seq->d_state[site]; } if(n_v2 && n_v2->tax) { /* Is the state at this tip ambiguous? */ ambiguity_check_v2 = n_v2->c_seq->is_ambigu[site]; /* if(ambiguity_check_v2 == NO) state_v2 = Get_State_From_P_Pars(n_v2->b[0]->p_lk_tip_r,site*dim2,tree); */ if(ambiguity_check_v2 == NO) state_v2 = n_v2->c_seq->d_state[site]; } } if(tree->mod->use_m4mod) { ambiguity_check_v1 = YES; ambiguity_check_v2 = YES; } if(p_lk_loc[site] < site) { Copy_P_Lk(p_lk,p_lk_loc[site],site,tree); Copy_Scale(sum_scale,p_lk_loc[site],site,tree); } else { /* For all the rate classes */ For(catg,tree->mod->ras->n_catg) { smallest_p_lk = BIG; /* For all the state at node d */ For(i,tree->mod->ns) { p1_lk1 = .0; if(n_v1) { /* n_v1 is a tip */ if((n_v1->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v1 == NO) { /* For the (non-ambiguous) state at node n_v1 */ p1_lk1 = Pij1[catg*dim3+i*dim2+state_v1]; } else { /* For all the states at node n_v1 */ p0 = Pij1[catg*dim3+i*dim2+ 0] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 0]; p1 = Pij1[catg*dim3+i*dim2+ 1] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 1]; p2 = Pij1[catg*dim3+i*dim2+ 2] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 2]; p3 = Pij1[catg*dim3+i*dim2+ 3] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 3]; p4 = Pij1[catg*dim3+i*dim2+ 4] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 4]; p5 = Pij1[catg*dim3+i*dim2+ 5] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 5]; p6 = Pij1[catg*dim3+i*dim2+ 6] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 6]; p7 = Pij1[catg*dim3+i*dim2+ 7] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 7]; p8 = Pij1[catg*dim3+i*dim2+ 8] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 8]; p9 = Pij1[catg*dim3+i*dim2+ 9] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+ 9]; p10 = Pij1[catg*dim3+i*dim2+10] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+10]; p11 = Pij1[catg*dim3+i*dim2+11] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+11]; p12 = Pij1[catg*dim3+i*dim2+12] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+12]; p13 = Pij1[catg*dim3+i*dim2+13] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+13]; p14 = Pij1[catg*dim3+i*dim2+14] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+14]; p15 = Pij1[catg*dim3+i*dim2+15] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+15]; p16 = Pij1[catg*dim3+i*dim2+16] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+16]; p17 = Pij1[catg*dim3+i*dim2+17] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+17]; p18 = Pij1[catg*dim3+i*dim2+18] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+18]; p19 = Pij1[catg*dim3+i*dim2+19] * (phydbl)n_v1->b[0]->p_lk_tip_r[site*dim2+19]; p1_lk1 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19; } } /* n_v1 is an internal node */ else { /* For the states at node n_v1 */ p0 = Pij1[catg*dim3+i*dim2+ 0] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 0]; p1 = Pij1[catg*dim3+i*dim2+ 1] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 1]; p2 = Pij1[catg*dim3+i*dim2+ 2] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 2]; p3 = Pij1[catg*dim3+i*dim2+ 3] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 3]; p4 = Pij1[catg*dim3+i*dim2+ 4] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 4]; p5 = Pij1[catg*dim3+i*dim2+ 5] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 5]; p6 = Pij1[catg*dim3+i*dim2+ 6] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 6]; p7 = Pij1[catg*dim3+i*dim2+ 7] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 7]; p8 = Pij1[catg*dim3+i*dim2+ 8] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 8]; p9 = Pij1[catg*dim3+i*dim2+ 9] * (phydbl)p_lk_v1[site*dim1+catg*dim2+ 9]; p10 = Pij1[catg*dim3+i*dim2+10] * (phydbl)p_lk_v1[site*dim1+catg*dim2+10]; p11 = Pij1[catg*dim3+i*dim2+11] * (phydbl)p_lk_v1[site*dim1+catg*dim2+11]; p12 = Pij1[catg*dim3+i*dim2+12] * (phydbl)p_lk_v1[site*dim1+catg*dim2+12]; p13 = Pij1[catg*dim3+i*dim2+13] * (phydbl)p_lk_v1[site*dim1+catg*dim2+13]; p14 = Pij1[catg*dim3+i*dim2+14] * (phydbl)p_lk_v1[site*dim1+catg*dim2+14]; p15 = Pij1[catg*dim3+i*dim2+15] * (phydbl)p_lk_v1[site*dim1+catg*dim2+15]; p16 = Pij1[catg*dim3+i*dim2+16] * (phydbl)p_lk_v1[site*dim1+catg*dim2+16]; p17 = Pij1[catg*dim3+i*dim2+17] * (phydbl)p_lk_v1[site*dim1+catg*dim2+17]; p18 = Pij1[catg*dim3+i*dim2+18] * (phydbl)p_lk_v1[site*dim1+catg*dim2+18]; p19 = Pij1[catg*dim3+i*dim2+19] * (phydbl)p_lk_v1[site*dim1+catg*dim2+19]; p1_lk1 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19; } } else { p1_lk1 = 1.0; } p2_lk2 = .0; /* We do exactly the same as for node n_v1 but for node n_v2 this time.*/ if(n_v2) { /* n_v2 is a tip */ if((n_v2->tax) && (!tree->mod->s_opt->greedy)) { if(ambiguity_check_v2 == NO) { /* For the (non-ambiguous) state at node n_v2 */ p2_lk2 = Pij2[catg*dim3+i*dim2+state_v2]; } else { /* For all the states at node n_v2 */ p0 = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 0]; p1 = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 1]; p2 = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 2]; p3 = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 3]; p4 = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 4]; p5 = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 5]; p6 = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 6]; p7 = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 7]; p8 = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 8]; p9 = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+ 9]; p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+10]; p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+11]; p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+12]; p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+13]; p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+14]; p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+15]; p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+16]; p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+17]; p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+18]; p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)n_v2->b[0]->p_lk_tip_r[site*dim2+19]; p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19; } } /* n_v2 is an internal node */ else { /* For all the states at node n_v2 */ p0 = Pij2[catg*dim3+i*dim2+ 0] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 0]; p1 = Pij2[catg*dim3+i*dim2+ 1] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 1]; p2 = Pij2[catg*dim3+i*dim2+ 2] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 2]; p3 = Pij2[catg*dim3+i*dim2+ 3] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 3]; p4 = Pij2[catg*dim3+i*dim2+ 4] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 4]; p5 = Pij2[catg*dim3+i*dim2+ 5] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 5]; p6 = Pij2[catg*dim3+i*dim2+ 6] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 6]; p7 = Pij2[catg*dim3+i*dim2+ 7] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 7]; p8 = Pij2[catg*dim3+i*dim2+ 8] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 8]; p9 = Pij2[catg*dim3+i*dim2+ 9] * (phydbl)p_lk_v2[site*dim1+catg*dim2+ 9]; p10 = Pij2[catg*dim3+i*dim2+10] * (phydbl)p_lk_v2[site*dim1+catg*dim2+10]; p11 = Pij2[catg*dim3+i*dim2+11] * (phydbl)p_lk_v2[site*dim1+catg*dim2+11]; p12 = Pij2[catg*dim3+i*dim2+12] * (phydbl)p_lk_v2[site*dim1+catg*dim2+12]; p13 = Pij2[catg*dim3+i*dim2+13] * (phydbl)p_lk_v2[site*dim1+catg*dim2+13]; p14 = Pij2[catg*dim3+i*dim2+14] * (phydbl)p_lk_v2[site*dim1+catg*dim2+14]; p15 = Pij2[catg*dim3+i*dim2+15] * (phydbl)p_lk_v2[site*dim1+catg*dim2+15]; p16 = Pij2[catg*dim3+i*dim2+16] * (phydbl)p_lk_v2[site*dim1+catg*dim2+16]; p17 = Pij2[catg*dim3+i*dim2+17] * (phydbl)p_lk_v2[site*dim1+catg*dim2+17]; p18 = Pij2[catg*dim3+i*dim2+18] * (phydbl)p_lk_v2[site*dim1+catg*dim2+18]; p19 = Pij2[catg*dim3+i*dim2+19] * (phydbl)p_lk_v2[site*dim1+catg*dim2+19]; p2_lk2 = p0+p1+p2+p3+p4+p5+p6+p7+p8+p9+p10+p11+p12+p13+p14+p15+p16+p17+p18+p19; } } else { p2_lk2 = 1.0; } p_lk[site*dim1+catg*dim2+i] = p1_lk1 * p2_lk2; if(p_lk[site*dim1+catg*dim2+i] < smallest_p_lk) smallest_p_lk = p_lk[site*dim1+catg*dim2+i] ; } /* Current scaling values at that site */ sum_scale_v1_val = (sum_scale_v1)?(sum_scale_v1[catg*n_patterns+site]):(0); sum_scale_v2_val = (sum_scale_v2)?(sum_scale_v2[catg*n_patterns+site]):(0); sum_scale[catg*n_patterns+site] = sum_scale_v1_val + sum_scale_v2_val; /* Scaling */ if(smallest_p_lk < p_lk_lim_inf) { curr_scaler_pow = (int)(LOG(p_lk_lim_inf)-LOG(smallest_p_lk))/LOG2; curr_scaler = (phydbl)((unsigned long long)(1) << curr_scaler_pow); /* if(fabs(curr_scaler_pow) > 63 || fabs(curr_scaler_pow) > 63) */ /* { */ /* PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); */ /* PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); */ /* PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__); */ /* Warn_And_Exit("\n"); */ /* } */ sum_scale[catg*n_patterns+site] += curr_scaler_pow; do { piecewise_scaler_pow = MIN(curr_scaler_pow,63); curr_scaler = (phydbl)((unsigned long long)(1) << piecewise_scaler_pow); For(i,tree->mod->ns) { p_lk[site*dim1+catg*dim2+i] *= curr_scaler; if(p_lk[site*dim1+catg*dim2+i] > BIG) { PhyML_Printf("\n. p_lk_lim_inf = %G smallest_p_lk = %G",p_lk_lim_inf,smallest_p_lk); PhyML_Printf("\n. curr_scaler_pow = %d",curr_scaler_pow); PhyML_Printf("\n. Err in file %s at line %d.",__FILE__,__LINE__); Warn_And_Exit("\n"); } } curr_scaler_pow -= piecewise_scaler_pow; } while(curr_scaler_pow != 0); } } } } } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Return_Abs_Lk(t_tree *tree) { Lk(NULL,tree); return FABS(tree->c_lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// matrix *ML_Dist(calign *data, t_mod *mod) { int i,j,k,l; phydbl init; int n_catg; phydbl d_max,sum; matrix *mat; calign *twodata,*tmpdata; int state0, state1,len; phydbl *F; eigen *eigen_struct; tmpdata = (calign *)mCalloc(1,sizeof(calign)); tmpdata->c_seq = (align **)mCalloc(2,sizeof(align *)); tmpdata->b_frq = (phydbl *)mCalloc(mod->ns,sizeof(phydbl)); tmpdata->ambigu = (short int *)mCalloc(data->crunch_len,sizeof(short int)); F = (phydbl *)mCalloc(mod->ns*mod->ns,sizeof(phydbl )); eigen_struct = (eigen *)Make_Eigen_Struct(mod->ns); tmpdata->n_otu = 2; tmpdata->crunch_len = data->crunch_len; tmpdata->init_len = data->init_len; mat = NULL; if(mod->io->datatype == NT) mat = (mod->whichmodel < 10)?(K80_dist(data,1E+6)):(JC69_Dist(data,mod)); else if(mod->io->datatype == AA) mat = JC69_Dist(data,mod); else if(mod->io->datatype == GENERIC) mat = JC69_Dist(data,mod); For(i,mod->ras->n_catg) /* Don't use the discrete gamma distribution */ { mod->ras->gamma_rr->v[i] = 1.0; mod->ras->gamma_r_proba->v[i] = 1.0; } n_catg = mod->ras->n_catg; mod->ras->n_catg = 1; For(j,data->n_otu-1) { tmpdata->c_seq[0] = data->c_seq[j]; tmpdata->c_seq[0]->name = data->c_seq[j]->name; tmpdata->wght = data->wght; for(k=j+1;kn_otu;k++) { tmpdata->c_seq[1] = data->c_seq[k]; tmpdata->c_seq[1]->name = data->c_seq[k]->name; twodata = Compact_Cdata(tmpdata,mod->io); Check_Ambiguities(twodata,mod->io->datatype,mod->io->state_len); Hide_Ambiguities(twodata); init = mat->dist[j][k]; if((init > DIST_MAX-SMALL) || (init < .0)) init = 0.1; d_max = init; For(i,mod->ns*mod->ns) F[i]=.0; len = 0; For(l,twodata->c_seq[0]->len) { state0 = Assign_State(twodata->c_seq[0]->state+l*mod->io->state_len,mod->io->datatype,mod->io->state_len); state1 = Assign_State(twodata->c_seq[1]->state+l*mod->io->state_len,mod->io->datatype,mod->io->state_len); if((state0 > -1) && (state1 > -1)) { F[mod->ns*state0+state1] += twodata->wght[l]; len += (int)twodata->wght[l]; } } if(len > .0) {For(i,mod->ns*mod->ns) F[i] /= (phydbl)len;} sum = 0.; For(i,mod->ns*mod->ns) sum += F[i]; /* if(sum < .001) d_max = -1.; */ if(sum < .001) d_max = init; else if((sum > 1. - .001) && (sum < 1. + .001)) Opt_Dist_F(&(d_max),F,mod); else { PhyML_Printf("\n== sum = %f\n",sum); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } if(d_max >= DIST_MAX) d_max = DIST_MAX; /* Do not correct for dist < BL_MIN, otherwise Fill_Missing_Dist * will not be called */ mat->dist[j][k] = d_max; mat->dist[k][j] = mat->dist[j][k]; Free_Cseq(twodata); } } mod->ras->n_catg = n_catg; Free(tmpdata->ambigu); Free(tmpdata->b_frq); Free(tmpdata->c_seq); free(tmpdata); Free_Eigen(eigen_struct); Free(F); return mat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_mod *mod, phydbl *loglk) { align *seq1,*seq2; phydbl site_lk,log_site_lk; int i,j,k,l; /* phydbl **p_lk_l,**p_lk_r; */ phydbl *p_lk_l,*p_lk_r; phydbl len; int dim1,dim2; dim1 = mod->ns; dim2 = mod->ns * mod->ns; DiscreteGamma(mod->ras->gamma_r_proba->v, mod->ras->gamma_rr->v, mod->ras->alpha->v, mod->ras->alpha->v,mod->ras->n_catg,mod->ras->gamma_median); seq1 = data->c_seq[numseq1]; seq2 = data->c_seq[numseq2]; p_lk_l = (phydbl *)mCalloc(data->c_seq[0]->len * mod->ns,sizeof(phydbl)); p_lk_r = (phydbl *)mCalloc(data->c_seq[0]->len * mod->ns,sizeof(phydbl)); For(i,mod->ras->n_catg) { len = dist*mod->ras->gamma_rr->v[i]; if(len < mod->l_min) len = mod->l_min; else if(len > mod->l_max) len = mod->l_max; PMat(len,mod,dim2*i,mod->Pij_rr->v); } if(mod->io->datatype == NT) { For(i,data->c_seq[0]->len) { Init_Tips_At_One_Site_Nucleotides_Float(seq1->state[i],i*mod->ns,p_lk_l); Init_Tips_At_One_Site_Nucleotides_Float(seq2->state[i],i*mod->ns,p_lk_r); } } else if(mod->io->datatype == AA) { For(i,data->c_seq[0]->len) { Init_Tips_At_One_Site_AA_Float(seq1->state[i],i*mod->ns,p_lk_l); Init_Tips_At_One_Site_AA_Float(seq2->state[i],i*mod->ns,p_lk_r); } } else { PhyML_Printf("\n. Not implemented yet..."); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } site_lk = .0; *loglk = 0; For(i,data->c_seq[0]->len) { if(data->wght[i]) { site_lk = log_site_lk = .0; if(!data->ambigu[i]) { For(k,mod->ns) {if(p_lk_l[i*mod->ns+k] > .0001) break;} For(l,mod->ns) {if(p_lk_r[i*mod->ns+l] > .0001) break;} For(j,mod->ras->n_catg) { site_lk += mod->ras->gamma_r_proba->v[j] * mod->e_frq->pi->v[k] * p_lk_l[i*dim1+k] * mod->Pij_rr->v[j*dim2+k*dim1+l] * p_lk_r[i*dim1+l]; } } else { For(j,mod->ras->n_catg) { For(k,mod->ns) /*sort sum terms ? No global effect*/ { For(l,mod->ns) { site_lk += mod->ras->gamma_r_proba->v[j] * mod->e_frq->pi->v[k] * p_lk_l[i*dim1+k] * mod->Pij_rr->v[j*dim2+k*dim1+l] * p_lk_r[i*dim1+l]; } } } } if(site_lk <= .0) { PhyML_Printf("'%c' '%c'\n",seq1->state[i],seq2->state[i]); Exit("\n. Err: site lk <= 0\n"); } log_site_lk += (phydbl)LOG(site_lk); *loglk += data->wght[i] * log_site_lk;/* sort sum terms ? No global effect*/ } } /* For(i,data->c_seq[0]->len) */ /* { */ /* Free(p_lk_l[i]); */ /* Free(p_lk_r[i]); */ /* } */ Free(p_lk_l); Free(p_lk_r); return *loglk; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Unconstraint_Lk(t_tree *tree) { int i; tree->unconstraint_lk = .0; For(i,tree->data->crunch_len) { tree->unconstraint_lk += tree->data->wght[i]*(phydbl)LOG(tree->data->wght[i]); } tree->unconstraint_lk -= tree->data->init_len*(phydbl)LOG(tree->data->init_len); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_P_Lk_Tips_Double(t_tree *tree) { int curr_site,i,j,k,dim1,dim2; dim1 = tree->mod->ras->n_catg * tree->mod->ns; dim2 = tree->mod->ns; For(i,tree->n_otu) { if(!tree->a_nodes[i]->c_seq || strcmp(tree->a_nodes[i]->c_seq->name,tree->a_nodes[i]->name)) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } } For(curr_site,tree->data->crunch_len) { For(i,tree->n_otu) { if (tree->io->datatype == NT) /* Init_Tips_At_One_Site_Nucleotides_Float(tree->data->c_seq[i]->state[curr_site], */ /* curr_site*dim1+0*dim2, */ /* tree->a_nodes[i]->b[0]->p_lk_rght); */ Init_Tips_At_One_Site_Nucleotides_Float(tree->a_nodes[i]->c_seq->state[curr_site], curr_site*dim1+0*dim2, tree->a_nodes[i]->b[0]->p_lk_rght); else if(tree->io->datatype == AA) Init_Tips_At_One_Site_AA_Float(tree->a_nodes[i]->c_seq->state[curr_site], curr_site*dim1+0*dim2, tree->a_nodes[i]->b[0]->p_lk_rght); /* Init_Tips_At_One_Site_AA_Float(tree->data->c_seq[i]->state[curr_site], */ /* curr_site*dim1+0*dim2, */ /* tree->a_nodes[i]->b[0]->p_lk_rght); */ else if(tree->io->datatype == GENERIC) Init_Tips_At_One_Site_Generic_Float(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len, tree->mod->ns, tree->mod->io->state_len, curr_site*dim1+0*dim2, tree->a_nodes[i]->b[0]->p_lk_rght); /* Init_Tips_At_One_Site_Generic_Float(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */ /* tree->mod->ns, */ /* tree->mod->io->state_len, */ /* curr_site*dim1+0*dim2, */ /* tree->a_nodes[i]->b[0]->p_lk_rght); */ for(j=1;jmod->ras->n_catg;j++) { For(k,tree->mod->ns) { tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1+j*dim2+k] = tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1+0*dim2+k]; } } } } if(tree->mod->use_m4mod) { M4_Init_P_Lk_Tips_Double(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_P_Lk_Tips_Int(t_tree *tree) { int curr_site,i,dim1; dim1 = tree->mod->ns; For(i,tree->n_otu) { if(!tree->a_nodes[i]->c_seq || strcmp(tree->a_nodes[i]->c_seq->name,tree->a_nodes[i]->name)) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } } For(curr_site,tree->data->crunch_len) { For(i,tree->n_otu) { /* printf("\n. site: %3d %c",curr_site,tree->a_nodes[i]->c_seq->state[curr_site]); */ /* printf("\n. init at %s %p",tree->a_nodes[i]->name,tree->a_nodes[i]->b[0]->p_lk_tip_r); fflush(NULL); */ if(tree->io->datatype == NT) { Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site], curr_site*dim1, tree->a_nodes[i]->b[0]->p_lk_tip_r); /* Init_Tips_At_One_Site_Nucleotides_Int(tree->data->c_seq[i]->state[curr_site], */ /* curr_site*dim1, */ /* tree->a_nodes[i]->b[0]->p_lk_tip_r); */ } else if(tree->io->datatype == AA) Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site], curr_site*dim1, tree->a_nodes[i]->b[0]->p_lk_tip_r); /* Init_Tips_At_One_Site_AA_Int(tree->data->c_seq[i]->state[curr_site], */ /* curr_site*dim1, */ /* tree->a_nodes[i]->b[0]->p_lk_tip_r); */ else if(tree->io->datatype == GENERIC) { Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len, tree->mod->ns, tree->mod->io->state_len, curr_site*dim1, tree->a_nodes[i]->b[0]->p_lk_tip_r); /* Init_Tips_At_One_Site_Generic_Int(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */ /* tree->mod->ns, */ /* tree->mod->io->state_len, */ /* curr_site*dim1, */ /* tree->a_nodes[i]->b[0]->p_lk_tip_r); */ } #ifdef BEAGLE //Recall that tip partials are stored on the branch leading //to the tip, rather than on the tip itself (hence `p_lk_tip_idx` //is a field of the branch (i.e. b[0]) rather than the node. //Secondly, the BEAGLE's partial buffers are laid out as //BEAGLE's partials buffer = [ tax1, tax2, ..., taxN, b1Left, b2Left, b3Left,...,bMLeft, b1Rght, b2Rght, b3Rght,...,bMRght] (N taxa, M branches) tree->a_nodes[i]->b[0]->p_lk_tip_idx = i; #endif } } if(tree->mod->use_m4mod) { M4_Init_P_Lk_Tips_Int(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree) { int i; phydbl len; phydbl l_min, l_max; phydbl shape, scale, mean, var; if(tree->is_mixt_tree) { MIXT_Update_PMat_At_Given_Edge(b_fcus,tree); return; } l_min = tree->mod->l_min; l_max = tree->mod->l_max; len = -1.0; if(tree->mod->log_l == YES) {b_fcus->l->v = EXP(b_fcus->l->v);} For(i,tree->mod->ras->n_catg) { if(tree->mod->ras->skip_rate_cat[i] == YES) continue; //Update the branch length if(b_fcus->has_zero_br_len == YES) { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif len = -1.0; mean = -1.0; var = -1.0; } else { len = MAX(0.0,b_fcus->l->v)*tree->mod->ras->gamma_rr->v[i];//branch_len * rate len *= tree->mod->br_len_mult->v; if(tree->mixt_tree) len *= tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number]; if(len < l_min) len = l_min; else if(len > l_max) len = l_max; mean = len; var = MAX(0.0,b_fcus->l_var->v) * POW(tree->mod->ras->gamma_rr->v[i]*tree->mod->br_len_mult->v,2); if(tree->mixt_tree) var *= POW(tree->mixt_tree->mod->ras->gamma_rr->v[tree->mod->ras->parent_class_number],2); if(var > tree->mod->l_var_max) var = tree->mod->l_var_max; if(var < tree->mod->l_var_min) var = tree->mod->l_var_min; } //Update the transition prob. matrix if(tree->mod->gamma_mgf_bl == NO) { #ifdef BEAGLE assert(UNINITIALIZED != tree->mod->b_inst); #endif PMat(len,tree->mod,i*tree->mod->ns*tree->mod->ns,b_fcus->Pij_rr); } else { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif shape = mean*mean/var; scale = var/mean; PMat_MGF_Gamma(b_fcus->Pij_rr+tree->mod->ns*tree->mod->ns*i,shape,scale,1.0,tree->mod); } } #ifdef BEAGLE int whichmodel = tree->mod->whichmodel; //Only for some models we use Beagle to compute/update the P-matrices, for other models //we compute them in PhyML and explicitly set the P-matrices in BEAGLE if((tree->mod->io->datatype == AA || whichmodel==GTR || whichmodel==CUSTOM) && tree->mod->use_m4mod == NO) { if(b_fcus->has_zero_br_len == YES) Warn_And_Exit(TODO_BEAGLE); // update_beagle_eigen(tree->mod); update_beagle_ras(tree->mod); // len = MAX(0.0, b_fcus->l->v) * tree->mod->br_len_mult->v; int p_matrices[1] = {b_fcus->Pij_rr_idx}; double branch_lens[1] = {len}; int ret = beagleUpdateTransitionMatrices(tree->b_inst,0,p_matrices,NULL,NULL,branch_lens,1); if(ret<0){ fprintf(stderr, "beagleUpdateTransitionMatrices() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } //Retrieve a "local" copy of the P-matrix ret = beagleGetTransitionMatrix(tree->b_inst, b_fcus->Pij_rr_idx, b_fcus->Pij_rr); if(ret<0){ fprintf(stderr, "beagleGetTransitionMatrix() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } } else { int ret = beagleSetTransitionMatrix(tree->b_inst, b_fcus->Pij_rr_idx, b_fcus->Pij_rr, -1); if(ret<0){ fprintf(stderr, "beagleSetTransitionMatrix() on instance %i failed:%i\n\n",tree->b_inst,ret); Exit(""); } } #endif if(tree->mod->log_l == YES) {b_fcus->l->v = LOG(b_fcus->l->v);} // Print_Model(tree->mod); // Dump_Arr_D(tree->cur_site_lk, tree->n_pattern); // Print_Edge_PMats(tree, b_fcus); // Print_Edge_Likelihoods(tree,b_fcus,true); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* void Update_P_Lk_On_A_Path(t_node *a, t_node *d, t_edge *b, t_node *target_one_side, t_node *target_other_side, t_tree *tree) */ /* { */ /* /\* */ /* \ / */ /* target\___________b_/ */ /* / \ \ \ \ */ /* / \ \ \ \ */ /* target is the root of the subtree at which we want */ /* the likelihood to be updated */ /* *\/ */ /* /\* PhyML_Printf("Update_p_lk on (%d %d) at %d (target=%d %d)\n", *\/ */ /* /\* b->left->num, *\/ */ /* /\* b->rght->num, *\/ */ /* /\* a->num, *\/ */ /* /\* target_one_side->num, *\/ */ /* /\* target_other_side->num); *\/ */ /* Update_P_Lk(tree,b,a); */ /* if((a == target_one_side) && (d == target_other_side)) */ /* return; */ /* else */ /* { */ /* Update_P_Lk_On_A_Path(d, */ /* d->v[tree->t_dir[d->num][target_other_side->num]], */ /* d->b[tree->t_dir[d->num][target_other_side->num]], */ /* target_one_side, */ /* target_other_side, */ /* tree); */ /* } */ /* } */ void Update_P_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree) { int i,j; For(i,path_length-1) { For(j,3) if(path[i]->v[j] == path[i+1]) { if(path[i] == path[i]->b[j]->left) { Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->left); } else if(path[i] == path[i]->b[j]->rght) { Update_P_Lk(tree,path[i]->b[j],path[i]->b[j]->rght); } else { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } break; } #ifdef DEBUG if(j == 3) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } #endif } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod) { int i,j,k; phydbl lnL,len; int dim1,dim2; if(mod->log_l == YES) dist = EXP(dist); For(k,mod->ras->n_catg) { len = dist*mod->ras->gamma_rr->v[k]; if(len < mod->l_min) len = mod->l_min; else if(len > mod->l_max) len = mod->l_max; PMat(len,mod,mod->ns*mod->ns*k,mod->Pij_rr->v); } dim1 = mod->ns*mod->ns; dim2 = mod->ns; lnL = .0; /* For(i,mod->ns) */ /* { */ /* For(j,mod->ns) */ /* { */ /* For(k,mod->ras->n_catg) */ /* { */ /* lnL += */ /* F[dim1*k+dim2*i+j] * */ /* LOG(mod->pi[i] * mod->Pij_rr[dim1*k+dim2*i+j]); */ /* } */ /* } */ /* } */ For(i,mod->ns-1) { for(j=i+1;jns;j++) { For(k,mod->ras->n_catg) { lnL += (F[dim1*k+dim2*i+j] + F[dim1*k+dim2*j+i])* LOG(mod->e_frq->pi->v[i] * mod->Pij_rr->v[dim1*k+dim2*i+j]); /* printf("\n. f: %f Pij:%f F:%f", */ /* mod->e_frq->pi->v[i], */ /* mod->Pij_rr->v[dim1*k+dim2*i+j], */ /* F[dim1*k+dim2*j+i]); */ } } } For(i,mod->ns) For(k,mod->ras->n_catg) lnL += F[dim1*k+dim2*i+i]* LOG(mod->e_frq->pi->v[i] * mod->Pij_rr->v[dim1*k+dim2*i+i]); return lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Update_Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree) { Update_P_Lk(tree,b_fcus,b_fcus->left); Update_P_Lk(tree,b_fcus,b_fcus->rght); tree->c_lnL = Lk(b_fcus,tree); return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Lk_Given_Edge_Recurr(t_node *a, t_node *d, t_edge *b, t_tree *tree) { PhyML_Printf("\n___ Edge %3d (left=%3d rght=%3d) lnL=%f", b->num, b->left->num, b->rght->num, Lk(b,tree)); if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) Print_Lk_Given_Edge_Recurr(d,d->v[i],d->b[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Alias_Subpatt(t_tree *tree) { if(tree->n_root && tree->ignore_root == NO) { Alias_Subpatt_Post(tree->n_root,tree->n_root->v[2],tree); Alias_Subpatt_Post(tree->n_root,tree->n_root->v[1],tree); } else { Alias_Subpatt_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); /* if(tree->both_sides) */ Alias_Subpatt_Pre(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree) { int i,j; int *patt_id_v1, *patt_id_v2, *patt_id_d; int *p_lk_loc_d, *p_lk_loc_v1, *p_lk_loc_v2; t_node *v1, *v2; t_edge *b0, *b1, *b2; int curr_patt_id_v1, curr_patt_id_v2; int curr_p_lk_loc_v1, curr_p_lk_loc_v2; int num_subpatt; b0 = b1 = b2 = NULL; if(d->tax) { patt_id_d = (d == d->b[0]->left)?(d->b[0]->patt_id_left):(d->b[0]->patt_id_rght); p_lk_loc_d = (d == d->b[0]->left)?(d->b[0]->p_lk_loc_left):(d->b[0]->p_lk_loc_rght); For(i,tree->n_pattern) { For(j,tree->n_pattern) { if(patt_id_d[i] == patt_id_d[j]) { p_lk_loc_d[i] = j; break; } if(j > i) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } return; } else { v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(!v1) { v1=d->v[i]; b1=d->b[i];} else { v2=d->v[i]; b2=d->b[i];} } else { b0 = d->b[i]; } } patt_id_v1 = (v1 == b1->left)?(b1->patt_id_left):(b1->patt_id_rght); patt_id_v2 = (v2 == b2->left)?(b2->patt_id_left):(b2->patt_id_rght); patt_id_d = (d == b0->left)?(b0->patt_id_left):(b0->patt_id_rght); p_lk_loc_d = (d == b0->left)?(b0->p_lk_loc_left):(b0->p_lk_loc_rght); p_lk_loc_v1 = (v1 == b1->left)?(b1->p_lk_loc_left):(b1->p_lk_loc_rght); p_lk_loc_v2 = (v2 == b2->left)?(b2->p_lk_loc_left):(b2->p_lk_loc_rght); num_subpatt = 0; For(i,tree->n_pattern) { curr_patt_id_v1 = patt_id_v1[i]; curr_patt_id_v2 = patt_id_v2[i]; curr_p_lk_loc_v1 = p_lk_loc_v1[i]; curr_p_lk_loc_v2 = p_lk_loc_v2[i]; p_lk_loc_d[i] = i; if((curr_p_lk_loc_v1 == i) || (curr_p_lk_loc_v2 == i)) { p_lk_loc_d[i] = i; patt_id_d[i] = num_subpatt; num_subpatt++; } else if(curr_p_lk_loc_v1 == curr_p_lk_loc_v2) { p_lk_loc_d[i] = curr_p_lk_loc_v1; patt_id_d[i] = patt_id_d[curr_p_lk_loc_v1]; } else { for(j=MAX(curr_p_lk_loc_v1,curr_p_lk_loc_v2);jn_pattern;j++) { if((patt_id_v1[j] == curr_patt_id_v1) && (patt_id_v2[j] == curr_patt_id_v2)) { p_lk_loc_d[i] = j; if(j == i) { patt_id_d[i] = num_subpatt; num_subpatt++; } else patt_id_d[i] = patt_id_d[j]; break; } if(j > i) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Alias_Subpatt_Post(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { Alias_Subpatt_Post(d,d->v[i],tree); } } Alias_One_Subpatt(a, d, tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Alias_Subpatt_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { Alias_One_Subpatt(d->v[i],d,tree); Alias_Subpatt_Pre(d,d->v[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_P_Lk(phydbl *p_lk, int site_from, int site_to, t_tree *tree) { int i,j; int dim1,dim2; dim1 = tree->mod->ras->n_catg * tree->mod->ns; dim2 = tree->mod->ns; /* PhyML_Printf("\n# %d %d",site_to,site_from); */ For(i,tree->mod->ns) For(j,tree->mod->ras->n_catg) { p_lk[site_to*dim1+j*dim2+i] = p_lk[site_from*dim1+j*dim2+i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Scale(int *scale, int site_from, int site_to, t_tree *tree) { int i; For(i,tree->mod->ras->n_catg) { scale[i*tree->n_pattern+site_to] = scale[i*tree->n_pattern+site_from]; /* PhyML_Printf("\n. %d",scale[i*tree->n_pattern+site_to]); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Init_P_Lk_Loc(t_tree *tree) { int i,j; t_node *d; int *patt_id_d; For(i,2*tree->n_otu-1) { For(j,tree->n_pattern) { tree->a_edges[i]->p_lk_loc_left[j] = j; tree->a_edges[i]->p_lk_loc_rght[j] = j; } } For(i,tree->n_otu) { d = tree->a_nodes[i]; patt_id_d = (d == d->b[0]->left)?(d->b[0]->patt_id_left):(d->b[0]->patt_id_rght); For(j,tree->n_pattern) { patt_id_d[j] = (int)tree->a_nodes[d->num]->c_seq->state[j]; /* patt_id_d[j] = (int)tree->data->c_seq[d->num]->state[j]; */ } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Lk_Normal_Approx(t_tree *tree) { phydbl lnL; int i; int dim; phydbl first_order; dim = 2*tree->n_otu-3; lnL = Dnorm_Multi_Given_InvCov_Det(tree->rates->u_cur_l, tree->rates->mean_l, tree->rates->invcov, tree->rates->covdet, 2*tree->n_otu-3,YES); first_order = 0.0; For(i,dim) first_order += (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]) * tree->rates->grad_l[i]; lnL += first_order; /* printf("\n"); */ /* For(i,dim) printf("%f\t",tree->rates->u_cur_l[i]); */ /* printf("\n. Lk=%f %f",lnL,tree->mod->l_min); */ /* err = NO; */ /* dim = 2*tree->n_otu-3; */ /* For(i,dim) */ /* { */ /* if((tree->rates->mean_l[i] / tree->mod->l_min < 1.1) && */ /* (tree->rates->mean_l[i] / tree->mod->l_min > 0.9)) */ /* { */ /* lnL -= Log_Dnorm(tree->a_edges[i]->l->v,tree->rates->mean_l[i],SQRT(tree->rates->cov_l[i*dim+i]),&err); */ /* if(err) */ /* { */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* lambda = 1./SQRT(tree->rates->cov_l[i*dim+i]); */ /* l = (tree->mod->log_l == YES)?(EXP(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); */ /* lnL += LOG(Dexp(l,lambda)); */ /* /\* printf("\n. lambda = %f",lambda); *\/ */ /* } */ /* } */ return(lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Part_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree) { return PART_Lk_At_Given_Edge(b,stree);; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Part_Lk(t_edge *b, t_tree *tree, supert_tree *stree) { return PART_Lk(stree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree) { Lk(NULL,tree); return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Geo_Lk(t_edge *b, t_tree *tree, supert_tree *stree) { TIPO_Lk(tree); return tree->geo_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree) { Lk(b,tree); return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Lk_Rates(t_edge *b, t_tree *tree, supert_tree *stree) { RATES_Lk_Rates(tree); return tree->rates->c_lnL_rates; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Lk_Times(t_edge *b, t_tree *tree, supert_tree *stree) { TIMES_Lk_Times(tree); return tree->rates->c_lnL_times; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Lk_Linreg(t_edge *b, t_tree *tree, supert_tree *stree) { /* RATES_Lk_Linreg(tree); */ return -1.; /* return tree->rates->c_lnL_linreg; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Wrap_Diff_Lk_Norm_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree) { phydbl diff; diff = Diff_Lk_Norm_At_Given_Edge(b,tree); return(-diff); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree) { int rate_cat; int i,j,k,l; phydbl *probs; phydbl sum; phydbl u; int n_mut; FILE *fp; phydbl *muttime; int *muttype; char *s; int *ordering; probs = (phydbl *)mCalloc(tree->mod->ras->n_catg,sizeof(phydbl)); muttime = (phydbl *)mCalloc((2*tree->n_otu-3)*5, // At most 5 mutations per branch on average sizeof(phydbl)); muttype = (int *)mCalloc((2*tree->n_otu-3)*5, // At most 5 mutations per branch on average sizeof(int)); ordering = (int *)mCalloc((2*tree->n_otu-3)*5, // At most 5 mutations per branch on average sizeof(int)); s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); For(i,2*tree->n_otu-1) if(tree->a_nodes[i]->tax == NO) { tree->a_nodes[i]->c_seq_anc = (align *)mCalloc(1,sizeof(align));; tree->a_nodes[i]->c_seq_anc->state = (char *)mCalloc(tree->n_pattern,sizeof(char)); } if(fromprior == YES) { /* Update P(D_x|X=i) for each state i and node X */ Set_Both_Sides(YES,tree); Lk(NULL,tree); } For(i,tree->n_pattern) { /* Sample the rate class from its posterior density */ For(j,tree->mod->ras->n_catg) { if(fromprior == NO) probs[j] = tree->unscaled_site_lk_cat[j*tree->n_pattern+i]* tree->mod->ras->gamma_r_proba->v[j]; else probs[j] = tree->mod->ras->gamma_r_proba->v[j]; } /* Scale probas. */ sum = .0; For(j,tree->mod->ras->n_catg) sum += probs[j]; For(j,tree->mod->ras->n_catg) probs[j]/=sum; /* CDF */ for(j=1;jmod->ras->n_catg;j++) probs[j] += probs[j-1]; /* Sample rate */ u = Uni(); rate_cat = -1; For(j,tree->mod->ras->n_catg) if(probs[j] > u) { rate_cat = j; break; } n_mut = 0; Sample_Ancestral_Seq_Pre(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0], i,rate_cat, muttype,muttime,&n_mut, mutmap,fromprior,tree); For(j,n_mut) ordering[j] = 0; For(j,n_mut-1) { for(k=j+1;k muttime[j]) ordering[k]++; else ordering[j]++; } } strcpy(s,"rosetta."); sprintf(s+strlen(s),"%d",i); fp = fopen(s,"a"); PhyML_Fprintf(fp,"\n-1 -1 -1.0 -1"); For(j,n_mut) { For(k,n_mut) { if(ordering[k] == j) { For(l,tree->data->init_len) if(tree->data->sitepatt[l] == i) break; PhyML_Fprintf(fp,"\n%4d %4d %12f %4d",j,muttype[k],muttime[k],l); /* PhyML_Fprintf(fp,"\n%d",muttype[ordering[j]]); */ break; } } } For(j,n_mut) { muttype[j] = -2; muttime[j] = +1.; } fclose(fp); } Free(s); Free(muttype); Free(muttime); Free(ordering); Free(probs); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b, int site, int rate_cat, int *muttype, phydbl *muttime, int *n_mut, int mutmap, int fromprior, t_tree *tree) { int i,j; int sa,sd; phydbl *Pij; phydbl *p_lk; int dim1, dim2, dim3; phydbl sum; phydbl u; char *c; phydbl *probs; probs = (phydbl *)mCalloc(tree->mod->ns,sizeof(phydbl)); if(a->tax) c = a->c_seq->state+site*tree->mod->io->state_len; /* c = tree->data->c_seq[a->num]->state+site*tree->mod->io->state_len; */ else c = a->c_seq_anc->state+site*tree->mod->io->state_len; /* c = tree->anc_data->c_seq[a->num-tree->n_otu]->state+site*tree->mod->io->state_len; */ sa = Assign_State(c, tree->mod->io->datatype, tree->mod->io->state_len); if(sa == -1) /* c is an indel */ { For(j,tree->mod->ns) probs[j] = tree->mod->e_frq->pi->v[j]; for(j=1;jmod->ns;j++) probs[j] += probs[j-1]; u = Uni(); For(j,tree->mod->ns) if(probs[j] > u) { sa = j; break; } } if(d->tax == NO) // Need to sample state at node d { dim1 = tree->mod->ras->n_catg * tree->mod->ns; dim2 = tree->mod->ns; dim3 = tree->mod->ns * tree->mod->ns; sum = 0.0; Pij = b->Pij_rr; if(d == b->left) p_lk = b->p_lk_left; else p_lk = b->p_lk_rght; For(j,tree->mod->ns) probs[j] = 0.0; /* Formula (10) in Nielsen's Mutation Maping paper, e.g. */ For(j,tree->mod->ns) { if(fromprior == NO) probs[j] = p_lk[site*dim1+rate_cat*dim2+j] * Pij[rate_cat*dim3+sa*dim2+j]; else probs[j] = Pij[rate_cat*dim3+sa*dim2+j]; } /* Scale the probabilities */ sum = 0.0; For(j,tree->mod->ns) sum += probs[j]; For(j,tree->mod->ns) probs[j] /= sum; /* CDF */ for(j=1;jmod->ns;j++) probs[j] += probs[j-1]; /* Sample state according to their posterior probas. */ sd = -1; u = Uni(); For(j,tree->mod->ns) if(probs[j] > u) { sd = j; break; } /* Assign state */ /* tree->anc_data->c_seq[d->num-tree->n_otu]->state[site] = Reciproc_Assign_State(sd,tree->io->datatype); */ /* printf("\n<> %p",d->c_seq_anc); fflush(NULL); */ d->c_seq_anc->state[site] = Reciproc_Assign_State(sd,tree->io->datatype); } else { c = d->c_seq->state+site*tree->mod->io->state_len; /* c = tree->data->c_seq[d->num]->state+site*tree->mod->io->state_len; */ sd = Assign_State(c, tree->mod->io->datatype, tree->mod->io->state_len); if(sd == -1) // c is an indel { For(j,tree->mod->ns) probs[j] = tree->mod->e_frq->pi->v[j]; for(j=1;jmod->ns;j++) probs[j] += probs[j-1]; u = Uni(); For(j,tree->mod->ns) if(probs[j] > u) { sd = j; break; } } } /* if(site == 92) */ /* { */ /* printf("\n. sa=%d (%s,%d) sd=%d (%s,%d) b->l->v=%f", */ /* sa,a->tax?a->name:"",a->num,sd,d->tax?d->name:"",d->num,b->l->v); */ /* } */ if(mutmap == YES) Map_Mutations(a,d,sa,sd,b,site,rate_cat,muttype,muttime,n_mut,tree); Free(probs); if(d->tax) return; else { For(i,3) { if(d->v[i] != a) { Sample_Ancestral_Seq_Pre(d,d->v[i],d->b[i],site,rate_cat,muttype,muttime,n_mut,mutmap,fromprior,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, int rate_cat, int *muttype, phydbl *muttime, int *n_mut, t_tree *tree) { int i,j; phydbl *probs,*all_probs; int slast; // Last state visited phydbl tlast, td; phydbl *Q; phydbl u,sum; int *mut; // Array of mutations int thismut; int n_mut_branch; phydbl br,cr,ta,gr; int n_iter; int first_mut; all_probs = (phydbl *)mCalloc(tree->mod->ns*tree->mod->ns,sizeof(phydbl)); mut = (int *)mCalloc(tree->mod->ns*tree->mod->ns,sizeof(int)); // Edge rate br = (tree->rates->model_log_rates == YES)? EXP(tree->rates->br_r[d->num]): tree->rates->br_r[d->num]; // Clock (i.e., overall) rate cr = tree->rates->clock_r; // Age of node a ta = tree->rates->nd_t[a->num]; // Site relative rate gr = tree->mod->ras->gamma_rr->v[rate_cat]; // Rate matrix Q = tree->mod->r_mat->qmat->v; // Length of the 'time' interval considered: product of the branch length by the // current relative rate at that site (set when sampling ancestral sequences) td = b->l->v * gr; // Matrix of change probabilities For(i,tree->mod->ns) { // We only care about the non-diagonal elements here For(j,tree->mod->ns) all_probs[i*tree->mod->ns+j] = -Q[i*tree->mod->ns+j] / Q[i*tree->mod->ns+i]; // Set the diagonal to 0 all_probs[i*tree->mod->ns+i] = 0.0; // \sum_{j != i} -q_{ij}/q_{ii} sum = 0; For(j,tree->mod->ns) sum += all_probs[i*tree->mod->ns+j]; // Diagonal: 1 - \sum_{j != i} -q_{ij}/q_{ii} all_probs[i*tree->mod->ns+i] = 1.-sum; // Get the cumulative probas for(j=1;jmod->ns;j++) all_probs[i*tree->mod->ns+j] += all_probs[i*tree->mod->ns+j-1]; } For(i,tree->mod->ns*tree->mod->ns) mut[i] = 0; tlast = .0; slast = sa; probs = NULL; n_mut_branch = 0; n_iter = 0; first_mut = YES; do { if((sa != sd) && (first_mut == YES)) // ancestral and descendant states are distinct { // Sample a time for the first mutation conditional on at least one mutation // occurring (see formula A2 in Nielsen's Genetics paper (2001)) u = Uni(); tlast = -LOG(1. - u*(1.-EXP(Q[sa*tree->mod->ns+sa]*td)))/-Q[sa*tree->mod->ns+sa]; } else { // Sample a time for the next mutation tlast = tlast + Rexp(-Q[slast*tree->mod->ns+slast]); } // Select the appropriate vector of change probabilities probs = all_probs+slast*tree->mod->ns; /* printf("\n. slast=%2d sd=%2d tlast=%12G td=%12G p=%12f rcat=%12f site=%4d", */ /* slast,sd,tlast,td,-Q[slast*tree->mod->ns+slast], */ /* tree->mod->ras->gamma_rr->v[rate_cat],site); */ // The time for the next mutation does not exceed the length // of the time interval -> sample a new mutation event if(tlast < td) { first_mut = NO; n_mut_branch++; u = Uni(); For(i,tree->mod->ns) if(probs[i] > u) { // Record mutation type mut[slast*tree->mod->ns+i]++; // Record mutation type in the site mutation array thismut = MIN(i,slast) * tree->mod->ns + MAX(i,slast) - (MIN(i,slast)+1+(int)POW(MIN(i,slast)+1,2))/2; muttype[(*n_mut)+n_mut_branch-1] = thismut; if((thismut > 5) || (thismut < 0)) { PhyML_Printf("\n. thismut = %d",thismut); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } // Record time of mutation muttime[(*n_mut)+n_mut_branch-1] = ta + br*cr*gr; // Update the last state slast = i; break; } } else { if(slast == sd) break; else { // Restart from the beginning For(i,tree->mod->ns*tree->mod->ns) mut[i] = 0; For(i,n_mut_branch) muttype[(*n_mut)+n_mut_branch-1] = -2; For(i,n_mut_branch) muttime[(*n_mut)+n_mut_branch-1] = +1.; tlast = 0.0; slast = sa; n_mut_branch = 0; first_mut = YES; n_iter++; } } } while(1); (*n_mut) += n_mut_branch; For(i,tree->mod->ns) { for(j=i+1;jmod->ns;j++) { if(mut[i*tree->mod->ns+j] + mut[j*tree->mod->ns+i] > 0) { thismut = MIN(i,j) * tree->mod->ns + MAX(i,j) - (MIN(i,j)+1+(int)POW(MIN(i,j)+1,2))/2; tree->mutmap[thismut*(tree->n_pattern)*(2*tree->n_otu-3) + b->num*(tree->n_pattern) + site]++; /* if(site == 92) */ /* { */ /* printf("\nx sa=%d sd=%d mut=%d",sa,sd,thismut); */ /* } */ } } } Free(all_probs); Free(mut); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Check_Lk_At_Given_Edge(int verbose, t_tree *tree) { int res; int i; phydbl *lk; lk = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); res = 0; For(i,2*tree->n_otu-3) { lk[i] = Lk(tree->a_edges[i],tree); if(verbose == YES) PhyML_Printf("\n. Edge %3d %13G %f %13G", tree->a_edges[i]->num,tree->a_edges[i]->l->v,lk[i], tree->a_edges[i]->l_var->v); } if(tree->n_root && tree->ignore_root == NO) { Lk(tree->n_root->b[1],tree); if(verbose == YES) PhyML_Printf("\nx Edge %3d %13G %f %13G", tree->n_root->b[1]->num,tree->n_root->b[1]->l->v,tree->c_lnL, tree->n_root->b[1]->l_var->v ); Lk(tree->n_root->b[2],tree); if(verbose == YES) PhyML_Printf("\nx Edge %3d %13G %f %13G", tree->n_root->b[2]->num,tree->n_root->b[2]->l->v,tree->c_lnL, tree->n_root->b[2]->l_var->v ); } res=1; for(i=1;i<2*tree->n_otu-3;i++) { if(FABS(lk[i]-lk[i-1]) > 1.E-2) res=0; } Free(lk); return res; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void ML_Ancestral_Sequences(t_tree *tree) { int i; /* PhyML_Printf("\n. %s \n",Write_Tree(tree,NO)); */ PhyML_Printf("\n\n. Estimating ancestral sequences..."); strcpy(tree->io->out_ancestral_file,tree->io->out_file); if(tree->io->append_run_ID) { strcat(tree->io->out_ancestral_file,"_"); strcat(tree->io->out_ancestral_file,tree->io->run_id_string); } strcat(tree->io->out_ancestral_file,"_phyml_ancestral_seq"); tree->io->fp_out_ancestral = Openfile(tree->io->out_ancestral_file,1); if(tree->n_root) { PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from the root node"); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers"); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n"); Print_Node_Brief(tree->n_root,tree->n_root->v[0],tree,tree->io->fp_out_ancestral); Print_Node_Brief(tree->n_root,tree->n_root->v[1],tree,tree->io->fp_out_ancestral); } else { PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing the tree structure. Starting from node 0 (taxon %s)",tree->a_nodes[0]->name); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and displaying the nodes underneath recursively. Edge numbers"); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== and their lengths are also provided.\n\n"); Print_Node_Brief(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree,tree->io->fp_out_ancestral); } PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n\n"); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== Printing marginal probabilities of ancestral sequences at each site"); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n== of the alignment and each node of the tree."); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n\n"); PhyML_Fprintf(tree->io->fp_out_ancestral,"Site\tNode\t"); For(i,tree->mod->ns) PhyML_Fprintf(tree->io->fp_out_ancestral,"%c\t",Reciproc_Assign_State(i,tree->io->datatype)); PhyML_Fprintf(tree->io->fp_out_ancestral,"\n"); For(i,2*tree->n_otu-2) if(tree->a_nodes[i]->tax == NO) ML_Ancestral_Sequences_One_Node(tree->a_nodes[i],tree); if(tree->n_root) ML_Ancestral_Sequences_One_Node(tree->n_root,tree); fclose(tree->io->fp_out_ancestral); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree) { if(mixt_d->tax) return; else { t_node *v0,*v1,*v2; // three neighbours of d t_edge *b0,*b1,*b2; int i,j; int catg; phydbl p0, p1, p2; phydbl *p; t_node *d,*curr_mixt_d; t_tree *tree, *curr_mixt_tree; int site,csite; phydbl *p_lk0, *p_lk1, *p_lk2; int *sum_scale0, *sum_scale1, *sum_scale2; phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas; phydbl *Pij0, *Pij1, *Pij2; int NsNs, Ns, NsNg; FILE *fp; if(!mixt_d) return; curr_mixt_tree = mixt_tree; curr_mixt_d = mixt_d; fp = mixt_tree->io->fp_out_ancestral; do /* For each partition element */ { if(curr_mixt_tree->next) { r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->r_mat_weight); e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(curr_mixt_tree->next->mod->e_frq_weight); sum_probas = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, curr_mixt_tree); } else { r_mat_weight_sum = 1.; e_frq_weight_sum = 1.; sum_probas = 1.; } Ns = curr_mixt_tree->next ? curr_mixt_tree->next->mod->ns : curr_mixt_tree->mod->ns; NsNs = Ns*Ns; NsNg = Ns*curr_mixt_tree->mod->ras->n_catg; p = (phydbl *)mCalloc(Ns,sizeof(phydbl)); /* For(site,curr_mixt_tree->n_pattern) // For each site in the current partition element */ For(site,curr_mixt_tree->data->init_len) // For each site in the current partition element { csite = curr_mixt_tree->data->sitepatt[site]; d = curr_mixt_d->next ? curr_mixt_d->next : curr_mixt_d; tree = curr_mixt_tree->next ? curr_mixt_tree->next : curr_mixt_tree; For(i,tree->mod->ns) p[i] = .0; do // For each class of the mixture model that applies to the current partition element { if(tree->is_mixt_tree == YES) { tree = tree->next; d = d->next; } v0 = d->v[0]; v1 = d->v[1]; v2 = d->v[2]; b0 = d->b[0]; b1 = d->b[1]; b2 = d->b[2]; Pij0 = b0->Pij_rr; Pij1 = b1->Pij_rr; Pij2 = b2->Pij_rr; if(v0 == b0->left) { p_lk0 = b0->p_lk_left; sum_scale0 = b0->sum_scale_left; } else { p_lk0 = b0->p_lk_rght; sum_scale0 = b0->sum_scale_rght; } if(v1 == b1->left) { p_lk1 = b1->p_lk_left; sum_scale1 = b1->sum_scale_left; } else { p_lk1 = b1->p_lk_rght; sum_scale1 = b1->sum_scale_rght; } if(v2 == b2->left) { p_lk2 = b2->p_lk_left; sum_scale2 = b2->sum_scale_left; } else { p_lk2 = b2->p_lk_rght; sum_scale2 = b2->sum_scale_rght; } For(catg,tree->mod->ras->n_catg) { For(i,Ns) { p0 = .0; if(v0->tax) For(j,tree->mod->ns) { p0 += v0->b[0]->p_lk_tip_r[csite*Ns+j] * Pij0[catg*NsNs+i*Ns+j]; /* printf("\n. p0 %d %f", */ /* v0->b[0]->p_lk_tip_r[site*Ns+j], */ /* Pij0[catg*NsNs+i*Ns+j]); */ } else For(j,tree->mod->ns) { p0 += p_lk0[csite*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale0[catg*curr_mixt_tree->n_pattern+csite]); /* p0 += p_lk0[site*NsNg+catg*Ns+j] * Pij0[catg*NsNs+i*Ns+j]; */ /* printf("\n. p0 %f %f", */ /* p_lk0[site*NsNg+catg*Ns+j], */ /* Pij0[catg*NsNs+i*Ns+j]); */ } p1 = .0; if(v1->tax) For(j,tree->mod->ns) { p1 += v1->b[0]->p_lk_tip_r[csite*Ns+j] * Pij1[catg*NsNs+i*Ns+j]; /* printf("\n. p1 %d %f", */ /* v1->b[0]->p_lk_tip_r[site*Ns+j], */ /* Pij1[catg*NsNs+i*Ns+j]); */ } else For(j,tree->mod->ns) { p1 += p_lk1[csite*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale1[catg*curr_mixt_tree->n_pattern+csite]); /* p1 += p_lk1[site*NsNg+catg*Ns+j] * Pij1[catg*NsNs+i*Ns+j]; */ /* printf("\n. p1 %f %f", */ /* p_lk1[site*NsNg+catg*Ns+j], */ /* Pij1[catg*NsNs+i*Ns+j]); */ } p2 = .0; if(v2->tax) For(j,tree->mod->ns) { p2 += v2->b[0]->p_lk_tip_r[csite*Ns+j] * Pij2[catg*NsNs+i*Ns+j]; /* printf("\n. p2 %d %f", */ /* v2->b[0]->p_lk_tip_r[site*Ns+j], */ /* Pij2[catg*NsNs+i*Ns+j]); */ } else For(j,tree->mod->ns) { p2 += p_lk2[csite*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j] / (phydbl)POW(2,sum_scale2[catg*curr_mixt_tree->n_pattern+csite]); /* p2 += p_lk2[site*NsNg+catg*Ns+j] * Pij2[catg*NsNs+i*Ns+j]; */ /* printf("\n. p2 %f %f", */ /* p_lk2[site*NsNg+catg*Ns+j], */ /* Pij2[catg*NsNs+i*Ns+j]); */ } p[i] += p0*p1*p2* tree->mod->e_frq->pi->v[i] / tree->cur_site_lk[csite] * curr_mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] * tree->mod->r_mat_weight->v / r_mat_weight_sum * tree->mod->e_frq_weight->v / e_frq_weight_sum / sum_probas; } } PhyML_Fprintf(fp,"%4d\t%4d\t",site+1,d->num); For(i,Ns) { PhyML_Fprintf(fp,"%.4f\t",p[i]); } PhyML_Fprintf(fp,"\n"); fflush(NULL); /* Exit("\n"); */ tree = tree->next; d = d->next; } while(tree && d && tree->is_mixt_tree == NO); } Free(p); curr_mixt_tree = curr_mixt_tree->next_mixt; curr_mixt_d = curr_mixt_d->next_mixt; } while(curr_mixt_tree != NULL); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the value of fact_sum_scale, the part of the scaling factors // that is common to all classes of the mixture and scale the // likelihood for each mixture (using the part of the scaling // factors that is class-specific) void Pull_Scaling_Factors(int site, t_edge *b, t_tree *tree) { int catg; int *sum_scale_left_cat,*sum_scale_rght_cat; int exponent; phydbl max_sum_scale,min_sum_scale; phydbl sum,tmp; phydbl site_lk_cat; sum_scale_left_cat = b->sum_scale_left_cat; sum_scale_rght_cat = b->sum_scale_rght_cat; if(tree->apply_lk_scaling == YES) { max_sum_scale = (phydbl)BIG; min_sum_scale = -(phydbl)BIG; For(catg,tree->mod->ras->n_catg) { sum_scale_left_cat[catg] = (b->sum_scale_left)? (b->sum_scale_left[catg*tree->n_pattern+site]): (0.0); sum_scale_rght_cat[catg] = (b->sum_scale_rght)? (b->sum_scale_rght[catg*tree->n_pattern+site]): (0.0); sum = sum_scale_left_cat[catg] + sum_scale_rght_cat[catg]; if(sum < .0) { printf("\n== tree: %s\n",Write_Tree(tree,NO)); PhyML_Printf("\n== b->num = %d sum = %G root ? %d",sum,b->num,b == tree->e_root); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } tmp = sum + ((phydbl)LOGBIG - LOG(tree->site_lk_cat[catg]))/(phydbl)LOG2; if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */ tmp = sum + ((phydbl)LOGSMALL - LOG(tree->site_lk_cat[catg]))/(phydbl)LOG2; if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */ } if(min_sum_scale > max_sum_scale) { /* PhyML_Printf("\n== Numerical precision issue alert."); */ /* PhyML_Printf("\n== min_sum_scale = %G max_sum_scale = %G",min_sum_scale,max_sum_scale); */ /* PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit("\n"); */ min_sum_scale = max_sum_scale; } tree->fact_sum_scale[site] = (int)((max_sum_scale + min_sum_scale) / 2); /* fact_sum_scale = (int)(max_sum_scale / 2); */ /* Apply scaling factors */ For(catg,tree->mod->ras->n_catg) { exponent = -(sum_scale_left_cat[catg]+sum_scale_rght_cat[catg])+tree->fact_sum_scale[site]; site_lk_cat = tree->site_lk_cat[catg]; Rate_Correction(exponent,&site_lk_cat,tree); tree->site_lk_cat[catg] = site_lk_cat; } } else // No scaling of lk { tree->fact_sum_scale[site] = 0; } For(catg,tree->mod->ras->n_catg) { tree->unscaled_site_lk_cat[catg*tree->n_pattern + site] = tree->site_lk_cat[catg]; if(isinf(tree->unscaled_site_lk_cat[catg*tree->n_pattern + site]) || isnan(tree->unscaled_site_lk_cat[catg*tree->n_pattern + site])) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s')",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/lk.h000066400000000000000000000114041263450375500142250ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef LK_H #define LK_H #include "utilities.h" #include "optimiz.h" #include "models.h" #include "free.h" #include "times.h" #include "mixt.h" void Init_Tips_At_One_Site_Nucleotides_Float(char state, int pos, phydbl *p_lk); void Init_Tips_At_One_Site_AA_Float(char aa, int pos, phydbl *p_lk); void Get_All_Partial_Lk(t_tree *tree,t_edge *b_fcus,t_node *a,t_node *d); void Get_All_Partial_Lk_Scale(t_tree *tree,t_edge *b_fcus,t_node *a,t_node *d); void Post_Order_Lk(t_node *pere, t_node *fils, t_tree *tree); void Pre_Order_Lk(t_node *pere, t_node *fils, t_tree *tree); phydbl Lk(t_edge *b, t_tree *tree); void Site_Lk(t_tree *tree); /* phydbl Lk_At_Given_Edge(t_edge *b_fcus,t_tree *tree); */ phydbl Return_Abs_Lk(t_tree *tree); matrix *ML_Dist(calign *data, t_mod *mod); phydbl Lk_Given_Two_Seq(calign *data, int numseq1, int numseq2, phydbl dist, t_mod *mod, phydbl *loglk); void Unconstraint_Lk(t_tree *tree); void Update_P_Lk(t_tree *tree,t_edge *b_fcus,t_node *n); void Update_P_Lk_Generic(t_tree *tree,t_edge *b_fcus,t_node *n); void Update_P_Lk_AA(t_tree *tree,t_edge *b_fcus,t_node *n); void Update_P_Lk_Nucl(t_tree *tree,t_edge *b_fcus,t_node *n); void Init_P_Lk_Tips_Double(t_tree *tree); void Init_P_Lk_Tips_Int(t_tree *tree); void Init_P_Lk_At_One_Node(t_node *a, t_tree *tree); void Update_PMat_At_Given_Edge(t_edge *b_fcus, t_tree *tree); void Sort_Sites_Based_On_Lk(t_tree *tree); void Get_Partial_Lk_Scale(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d); void Get_Partial_Lk(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d); void Init_Tips_At_One_Site_Nucleotides_Int(char state, int pos, short int *p_pars); void Init_Tips_At_One_Site_AA_Int(char aa, int pos, short int *p_pars); void Update_P_Lk_Along_A_Path(t_node **path, int path_length, t_tree *tree); phydbl Lk_Dist(phydbl *F, phydbl dist, t_mod *mod); phydbl Update_Lk_At_Given_Edge(t_edge *b_fcus, t_tree *tree); void Update_P_Lk_Greedy(t_tree *tree, t_edge *b_fcus, t_node *n); void Get_All_Partial_Lk_Scale_Greedy(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d); phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree); phydbl Lk_Triplet(t_node *a, t_node *d, t_tree *tree); void Print_Lk_Given_Edge_Recurr(t_node *a, t_node *d, t_edge *b, t_tree *tree); phydbl *Post_Prob_Rates_At_Given_Edge(t_edge *b, phydbl *post_prob, t_tree *tree); phydbl Lk_With_MAP_Branch_Rates(t_tree *tree); void Init_Tips_At_One_Site_Generic_Int(char *state, int ns, int state_len, int pos, short int *p_pars); void Init_Tips_At_One_Site_Generic_Float(char *state, int ns, int state_len, int pos, phydbl *p_lk); void Alias_Subpatt(t_tree *tree); void Alias_One_Subpatt(t_node *a, t_node *d, t_tree *tree); void Alias_Subpatt_Post(t_node *a, t_node *d, t_tree *tree); void Alias_Subpatt_Pre(t_node *a, t_node *d, t_tree *tree); void Copy_P_Lk(phydbl *p_lk, int site_from, int site_to, t_tree *tree); void Copy_Scale(int *scale, int site_from, int site_to, t_tree *tree); void Init_P_Lk_Loc(t_tree *tree); phydbl Lk_Normal_Approx(t_tree *tree); phydbl Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Part_Lk_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Part_Lk(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Geo_Lk(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Diff_Lk_Norm_At_Given_Edge(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Lk_Rates(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Wrap_Lk_Linreg(t_edge *b, t_tree *tree, supert_tree *stree); void Sample_Ancestral_Seq(int mutmap, int fromprior, t_tree *tree); void Map_Mutations(t_node *a, t_node *d, int sa, int sd, t_edge *b, int site, int rate_cat, int *muttype, phydbl *muttime, int *n_mut, t_tree *tree); void Sample_Ancestral_Seq_Pre(t_node *a, t_node *d, t_edge *b, int site, int rate_cat, int *muttype, phydbl *muttime, int *n_mut, int mutmap, int fromprior, t_tree *tree); phydbl Wrap_Lk_Times(t_edge *b, t_tree *tree, supert_tree *stree); phydbl Lk_LastFirst(t_tree *tree); phydbl Invariant_Lk(int fact_sum_scale, int site, int *num_prec_issue, t_tree *tree); void Rate_Correction(int exponent, phydbl *site_lk_cat, t_tree *tree); int Check_Lk_At_Given_Edge(int verbose, t_tree *tree); void ML_Ancestral_Sequences_One_Node(t_node *mixt_d, t_tree *mixt_tree); void ML_Ancestral_Sequences(t_tree *tree); void Pull_Scaling_Factors(int site, t_edge *b, t_tree *tree); #endif phyml-3.2.0/src/m4.c000066400000000000000000001364611263450375500141450ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Routines for Markov-Modulated Markov Models (M4) */ #include "m4.h" int M4_main(int argc, char **argv) { calign *cdata; option *io; t_tree *tree; int num_data_set; int num_tree,num_rand_tree; t_mod *mod; time_t t_beg,t_end; phydbl best_lnL; int r_seed; char *most_likely_tree=NULL; #ifdef MPI int rc; rc = MPI_Init(&argc,&argv); if (rc != MPI_SUCCESS) { PhyML_Printf("\n== Err. starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD,&Global_numTask); MPI_Comm_rank(MPI_COMM_WORLD,&Global_myRank); #endif #ifdef QUIET setvbuf(stdout,NULL,_IOFBF,2048); #endif tree = NULL; mod = NULL; best_lnL = UNLIKELY; io = (option *)Get_Input(argc,argv); r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed); srand(r_seed); io->r_seed = r_seed; if(io->in_tree == 2) Test_Multiple_Data_Set_Format(io); else io->n_trees = 1; if((io->n_data_sets > 1) && (io->n_trees > 1)) { io->n_data_sets = MIN(io->n_trees,io->n_data_sets); io->n_trees = MIN(io->n_trees,io->n_data_sets); } For(num_data_set,io->n_data_sets) { best_lnL = UNLIKELY; Get_Seq(io); Make_Model_Complete(io->mod); Set_Model_Name(io->mod); Print_Settings(io); mod = io->mod; if(io->data) { if(io->n_data_sets > 1) PhyML_Printf("\n. Data set [#%d]\n",num_data_set+1); cdata = Compact_Data(io->data,io); Free_Seq(io->data,cdata->n_otu); if(cdata) Check_Ambiguities(cdata,io->datatype,io->state_len); else { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } for(num_tree=(io->n_trees == 1)?(0):(num_data_set);num_tree < io->n_trees;num_tree++) { if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1; For(num_rand_tree,io->mod->s_opt->n_rand_starts) { if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE)) if(!io->quiet) PhyML_Printf("\n. [Random start %3d/%3d]\n",num_rand_tree+1,io->mod->s_opt->n_rand_starts); Init_Model(cdata,mod,io); if(io->mod->use_m4mod) M4_Init_Model(mod->m4mod,cdata,mod); switch(io->in_tree) { case 0 : case 1 : { tree = Dist_And_BioNJ(cdata,mod,io); break; } case 2 : { tree = Read_User_Tree(cdata,mod,io); break; } } if(!tree) continue; time(&t_beg); time(&(tree->t_beg)); tree->mod = mod; tree->io = io; tree->data = cdata; tree->n_pattern = tree->data->crunch_len; Set_Both_Sides(YES,tree); if(mod->s_opt->random_input_tree) Random_Tree(tree); if((!num_data_set) && (!num_tree) && (!num_rand_tree)) Check_Memory_Amount(tree); Prepare_Tree_For_Lk(tree); if(io->in_tree == 1) Spr_Pars(tree); if(io->do_alias_subpatt) { MIXT_Set_Alias_Subpatt(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); } if(tree->mod->s_opt->opt_topo) { if(tree->mod->s_opt->topo_search == NNI_MOVE) Simu_Loop(tree); else if(tree->mod->s_opt->topo_search == SPR_MOVE) Speed_Spr_Loop(tree); else Best_Of_NNI_And_SPR(tree); } else { if(tree->mod->s_opt->opt_subst_param || tree->mod->s_opt->opt_bl) Round_Optimize(tree,tree->data,ROUND_MAX); else Lk(NULL,tree); } Set_Both_Sides(YES,tree); Lk(NULL,tree); Pars(NULL,tree); Get_Tree_Size(tree); PhyML_Printf("\n. Log likelihood of the current tree: %f.\n",tree->c_lnL); Exit("\n"); /* */ M4_Compute_Proba_Hidden_States_On_Edges(tree); /* */ Get_Best_Root_Position(tree); /* Print the tree estimated using the current random (or BioNJ) starting tree */ if(io->mod->s_opt->n_rand_starts > 1) { Br_Len_Involving_Invar(tree); Print_Tree(io->fp_out_trees,tree); fflush(NULL); } /* Record the most likely tree in a string of characters */ if(tree->c_lnL > best_lnL) { best_lnL = tree->c_lnL; Br_Len_Involving_Invar(tree); if(most_likely_tree) Free(most_likely_tree); most_likely_tree = Write_Tree(tree,NO); Get_Tree_Size(tree); } /* JF(tree); */ time(&t_end); Print_Fp_Out(io->fp_out_stats,t_beg,t_end,tree, io,num_data_set+1, (tree->mod->s_opt->n_rand_starts > 1)? (num_rand_tree):(num_tree),YES); if(tree->io->print_site_lnl) Print_Site_Lk(tree,io->fp_out_lk); /* Start from BioNJ tree */ if((num_rand_tree == io->mod->s_opt->n_rand_starts-1) && (tree->mod->s_opt->random_input_tree)) { /* Do one more iteration in the loop, but don't randomize the tree */ num_rand_tree--; tree->mod->s_opt->random_input_tree = 0; } Free_Spr_List(tree); Free_One_Spr(tree->best_spr); if(tree->mat) Free_Mat(tree->mat); Free_Triplet(tree->triplet_struct); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); } /* Launch bootstrap analysis */ if(mod->bootstrap) { if(!io->quiet) PhyML_Printf("\n. Launch bootstrap analysis on the most likely tree...\n"); #ifdef MPI MPI_Bcast (most_likely_tree, strlen(most_likely_tree)+1, MPI_CHAR, 0, MPI_COMM_WORLD); if(!io->quiet) PhyML_Printf("\n. The bootstrap analysis will use %d CPUs.\n",Global_numTask); #endif most_likely_tree = Bootstrap_From_String(most_likely_tree,cdata,mod,io); } else if(io->ratio_test) { /* Launch aLRT */ if(!io->quiet) PhyML_Printf("\n. Compute aLRT branch supports on the most likely tree...\n"); most_likely_tree = aLRT_From_String(most_likely_tree,cdata,mod,io); } /* Print the most likely tree in the output file */ if(!io->quiet) PhyML_Printf("\n. Printing the most likely tree in file '%s'...\n", Basename(io->out_tree_file)); if(io->n_data_sets == 1) rewind(io->fp_out_tree); PhyML_Fprintf(io->fp_out_tree,"%s\n",most_likely_tree); if(io->n_trees > 1 && io->n_data_sets > 1) break; } Free_Cseq(cdata); } else { PhyML_Printf("\n. No data was found.\n"); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } Free_Model_Complete(mod); } if(most_likely_tree) Free(most_likely_tree); if(mod->s_opt->n_rand_starts > 1) PhyML_Printf("\n. Best log likelihood: %f\n",best_lnL); Free_Optimiz(mod->s_opt); Free_Model_Basic(mod); if(io->fp_in_align) fclose(io->fp_in_align); if(io->fp_in_tree) fclose(io->fp_in_tree); if(io->fp_out_lk) fclose(io->fp_out_lk); if(io->fp_out_tree) fclose(io->fp_out_tree); if(io->fp_out_trees) fclose(io->fp_out_trees); if(io->fp_out_stats) fclose(io->fp_out_stats); Free_Input(io); time(&t_end); Print_Time_Info(t_beg,t_end); #ifdef MPI MPI_Finalize(); #endif return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Allocate memory */ m4 *M4_Make_Light() { m4 *m4mod; m4mod = (m4 *)mCalloc(1,sizeof(m4)); M4_Set_M4mod_Default(m4mod); return m4mod; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Set_M4mod_Default(m4 *m4mod) { m4mod->use_cov_alpha = 1; m4mod->use_cov_alpha = 0; m4mod->n_h = 3; m4mod->n_o = 4; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Allocate memory */ void M4_Make_Complete(int n_h, int n_o, m4 *m4mod) { int i; m4mod->n_h = n_h; m4mod->n_o = n_o; m4mod->n_o = n_o; m4mod->o_rr = (phydbl *)mCalloc(n_o*n_o,sizeof(phydbl)); m4mod->o_fq = (phydbl *)mCalloc(n_o,sizeof(phydbl)); m4mod->o_mats = (phydbl **)mCalloc(n_h,sizeof(phydbl *)); For(i,n_h) m4mod->o_mats[i] = (phydbl *)mCalloc(n_o*n_o,sizeof(phydbl)); m4mod->h_mat = (phydbl *)mCalloc(n_h*n_h,sizeof(phydbl)); m4mod->h_rr = (phydbl *)mCalloc(n_h*n_h,sizeof(phydbl)); m4mod->h_fq = (phydbl *)mCalloc(n_h,sizeof(phydbl)); m4mod->multipl = (phydbl *)mCalloc(n_h,sizeof(phydbl)); m4mod->multipl_unscaled = (phydbl *)mCalloc(n_h,sizeof(phydbl)); m4mod->h_fq_unscaled = (phydbl *)mCalloc(n_h,sizeof(phydbl)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Fill in the (big) rate matrix of the M4 t_mod */ void M4_Update_Qmat(m4 *m4mod, t_mod *mod) { int i,j; int n_s, n_o, n_h; phydbl mr, sum; /* The number of states in M4 models is the product of the number of hidden states (or classes) by the number of observable states */ n_s = mod->ns; n_o = m4mod->n_o; n_h = m4mod->n_h; /* Set the relative substitution rates */ if(mod->m4mod->use_cov_alpha) { DiscreteGamma(m4mod->h_fq,m4mod->multipl,m4mod->alpha,m4mod->alpha,m4mod->n_h,mod->ras->gamma_median); } else if(mod->m4mod->use_cov_free) { sum = .0; For(i,mod->m4mod->n_h) sum += FABS(mod->m4mod->h_fq_unscaled[i]); For(i,mod->m4mod->n_h) mod->m4mod->h_fq[i] = FABS(mod->m4mod->h_fq_unscaled[i])/sum; do { sum = .0; For(i,mod->m4mod->n_h) { if(mod->m4mod->h_fq[i] < 0.01) mod->m4mod->h_fq[i]=0.01; if(mod->m4mod->h_fq[i] > 0.99) mod->m4mod->h_fq[i]=0.99; sum += mod->m4mod->h_fq[i]; } For(i,mod->m4mod->n_h) mod->m4mod->h_fq[i]/=sum; } while((sum > 1.01) || (sum < 0.99)); /* Make sure the multipliers are centered on 1.0 */ sum = .0; For(i,mod->m4mod->n_h) sum += FABS(mod->m4mod->multipl_unscaled[i]) * mod->m4mod->h_fq[i]; For(i,mod->m4mod->n_h) mod->m4mod->multipl[i] = mod->m4mod->multipl_unscaled[i] / sum; /* printf("\n. WARNING\n"); */ /* mod->m4mod->h_fq[0] = 1./3; */ /* mod->m4mod->h_fq[1] = 1./3; */ /* mod->m4mod->h_fq[2] = 1./3; */ /* mod->m4mod->multipl[0] = 1.0; */ /* mod->m4mod->multipl[1] = 1.0; */ /* mod->m4mod->multipl[2] = 1.0; */ sum = 0; For(i,mod->m4mod->n_h) sum += mod->m4mod->multipl[i] * mod->m4mod->h_fq[i]; if(sum < 0.99 || sum > 1.01) { PhyML_Printf("\n. sum = %f",sum); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } /* PhyML_Printf("\n__ "); */ /* For(i,mod->m4mod->n_h) PhyML_Printf("\n.%f %f %f", */ /* mod->m4mod->h_fq[i], */ /* mod->m4mod->h_fq_unscaled[i], */ /* mod->m4mod->multipl[i]); */ } /* PhyML_Printf("\n."); */ /* PhyML_Printf("\n. M4 model parameters"); */ /* m4mod->delta=.0; */ /* PhyML_Printf("\n. Delta = %f",m4mod->delta); */ /* For(i,mod->m4mod->n_h) PhyML_Printf("\n. multipl %d = %f",i,m4mod->multipl[i]); */ /* For(i,mod->m4mod->n_h) PhyML_Printf("\n. fq %d = %f",i,m4mod->h_fq[i]); */ /* Set up the stationary frequency vector */ For(i,n_s) mod->e_frq->pi->v[i] = m4mod->o_fq[i%n_o] * m4mod->h_fq[i/n_o]; if(mod->whichmodel != CUSTOM && mod->whichmodel != GTR && mod->io->datatype == NT) { phydbl kappa1,kappa2; if((mod->whichmodel != F84) && (mod->whichmodel != TN93)) mod->lambda->v = 1.; else if(mod->whichmodel == F84) { mod->lambda->v = Get_Lambda_F84(mod->e_frq->pi->v,&(mod->kappa->v)); } kappa2 = mod->kappa->v*2./(1.+mod->lambda->v); kappa1 = kappa2 * mod->lambda->v; /* A <-> C */ m4mod->o_rr[0] = 1.0; /* A <-> G */ m4mod->o_rr[1] = kappa2; /* A <-> T */ m4mod->o_rr[2] = 1.0; /* C <-> G */ m4mod->o_rr[3] = 1.0; /* C <-> T */ m4mod->o_rr[4] = kappa1; } /* Fill in the matrices of nucleotide or amino-acid substitution rates here */ Update_Qmat_Generic(m4mod->o_rr, m4mod->o_fq, m4mod->n_o, m4mod->o_mats[0]); /* Print_Square_Matrix_Generic(n_o,m4mod->o_mats[0]); */ /* Multiply each of these matrices by a relative substitution rate */ for(i=1;in_h;i++) For(j,n_o*n_o) m4mod->o_mats[i][j] = m4mod->o_mats[0][j]*m4mod->multipl[i]; For(j,n_o*n_o) m4mod->o_mats[0][j] *= m4mod->multipl[0]; For(i,n_s*n_s) mod->r_mat->qmat->v[i] = .0; /* Diagonal blocks (i.e, nucleotide substitutions), symmetric */ For(i,n_s) { for(j=i+1;jr_mat->qmat->v[i*n_s+j] = m4mod->o_mats[(int)(i/n_o)][(i%n_o)*n_o+j%n_o]; mod->r_mat->qmat->v[j*n_s+i] = mod->r_mat->qmat->v[i*n_s+j] * m4mod->o_fq[i%n_o] / m4mod->o_fq[j%n_o]; } } } /* Work out scaling factor such that the expected number of observed state substitution along a branch of length 1 is 1.*/ mr = .0; For(i,n_s) { sum = .0; For(j,n_s) sum += mod->r_mat->qmat->v[i*n_s+j]; mr += sum * m4mod->o_fq[i%n_o] * m4mod->h_fq[(int)(i/n_o)]; } /* Scale the diagonal blocks */ For(i,n_s*n_s) mod->r_mat->qmat->v[i] /= mr; /* We are done with the diagonal blocks. Let's fill the non-diagonal ones now. */ /* Fill the matrix of substitution rate across classes (switches) here */ Update_Qmat_Generic(m4mod->h_rr, m4mod->h_fq, m4mod->n_h, m4mod->h_mat); /* Print_Square_Matrix_Generic(m4mod->n_h,m4mod->h_mat); */ /* Multiply this matrix by the switching rate */ For(i,n_h*n_h) m4mod->h_mat[i] *= m4mod->delta; /* Fill the non diagonal blocks */ For(i,n_s) { for(j=i+1;jr_mat->qmat->v[i*n_s+j] = m4mod->h_mat[(int)(i/n_o)*n_h+(int)(j/n_o)]; mod->r_mat->qmat->v[j*n_s+i] = mod->r_mat->qmat->v[i*n_s+j] * m4mod->h_fq[(int)(i/n_o)] / m4mod->h_fq[(int)(j/n_o)]; } } } } /* Note: class equilibrium frequencies are already built in the h_mat matrix. No need to 'add' these frequencies later on. */ /* We are done with the non diagonal blocks */ /* Diagonal cells */ For(i,n_s) { sum = .0; For(j,n_s) { if(j != i) sum += mod->r_mat->qmat->v[i*n_s+j]; } mod->r_mat->qmat->v[i*n_s+i] = -sum; } For(i,n_s*n_s) mod->eigen->q[i] = mod->r_mat->qmat->v[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Init_P_Lk_Tips_Double(t_tree *tree) { int curr_site,i,j,k,l,dim1,dim2,dim3; dim1 = tree->mod->ras->n_catg * tree->mod->m4mod->n_h * tree->mod->m4mod->n_o; dim2 = tree->mod->m4mod->n_h * tree->mod->m4mod->n_o; dim3 = tree->mod->m4mod->n_o; Fors(curr_site,tree->data->crunch_len,tree->mod->io->state_len) { For(i,tree->n_otu) { for(j=1;jmod->m4mod->n_h;j++) { For(k,tree->mod->m4mod->n_o) { tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + j*dim3+k] = tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + 0*dim3+k]; printf("\n() i=%d plk=%f", curr_site*dim1 + 0*dim2 + j*dim3+k, tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + j*dim3+k]); /* tree->a_nodes[i]->b[0]->p_lk_rght[curr_site][0][j*tree->mod->m4mod->n_o+k] = */ /* tree->a_nodes[i]->b[0]->p_lk_rght[curr_site][0][k]; */ } For(k,tree->mod->m4mod->n_o) for(l=1;lmod->ras->n_catg;l++) tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + l*dim2 + j*dim3+k] = tree->a_nodes[i]->b[0]->p_lk_rght[curr_site*dim1 + 0*dim2 + j*dim3+k]; /* tree->a_nodes[i]->b[0]->p_lk_rght[curr_site][l][j*tree->mod->m4mod->n_o+k] = */ /* tree->a_nodes[i]->b[0]->p_lk_rght[curr_site][0][j*tree->mod->m4mod->n_o+k]; */ } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Init_P_Lk_Tips_Int(t_tree *tree) { int curr_site,i,j,k,dim2,dim3; dim2 = tree->mod->m4mod->n_h * tree->mod->m4mod->n_o; dim3 = tree->mod->m4mod->n_o; Fors(curr_site,tree->data->crunch_len,tree->mod->io->state_len) { For(i,tree->n_otu) { for(j=1;jmod->m4mod->n_h;j++) { For(k,tree->mod->m4mod->n_o) { tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site*dim2 + j*dim3+k] = tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site*dim2 + 0*dim3+k]; /* tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site][j*tree->mod->m4mod->n_o+k] = */ /* tree->a_nodes[i]->b[0]->p_lk_tip_r[curr_site][k]; */ } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl ****M4_Integral_Term_On_One_Edge(t_edge *b, t_tree *tree) { phydbl ****integral,*P1,*P2; int ns; int g,i,j,k,l; int step; ns = tree->mod->ns; P1 = (phydbl *)mCalloc(tree->mod->ras->n_catg*ns*ns,sizeof(phydbl)); P2 = (phydbl *)mCalloc(tree->mod->ras->n_catg*ns*ns,sizeof(phydbl)); integral = (phydbl ****)mCalloc(tree->mod->ras->n_catg,sizeof(phydbl ***)); For(g,tree->mod->ras->n_catg) { integral[g] = (phydbl ***)mCalloc(ns,sizeof(phydbl **)); For(j,ns) { integral[g][j] = (phydbl **)mCalloc(ns,sizeof(phydbl *)); For(k,ns) integral[g][j][k] = (phydbl *)mCalloc(ns,sizeof(phydbl)); } } /* Integral calculation */ step = 100; PhyML_Printf("\n. ["); For(i,step) { For(g,tree->mod->ras->n_catg) { PMat(((phydbl)(i+0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P1); PMat(((phydbl)(step-i-0.5)/step)*b->l->v*tree->mod->ras->gamma_rr->v[g],tree->mod,g*ns*ns,P2); For(j,ns) { For(k,ns) { For(l,ns) { /* integral[g][j][k][l] += P1[g][j][k] * P2[g][j][l] / ((phydbl)(step)); */ integral[g][j][k][l] += P1[g*ns*ns + j*ns+k] * P2[g*ns*ns + j*ns+l] / ((phydbl)(step)); } } } } PhyML_Printf("."); fflush(NULL); } PhyML_Printf("]\n"); Free(P1); Free(P2); return integral; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *postprob, t_tree *tree) { /* Calculation of the expected frequencies of each hidden class at a given site. */ phydbl site_lk; int g,i,j,k,l; int n_h; phydbl sum; int dim1,dim2; dim1 = tree->mod->ras->n_catg * tree->mod->ns; dim2 = tree->mod->ns; n_h = tree->mod->m4mod->n_h; /* number of classes, i.e., number of hidden states */ site_lk = (phydbl)EXP(tree->cur_site_lk[tree->curr_site]); if(b->rght->tax) { sum = .0; For(i,n_h) { postprob[i] = .0; For(j,tree->mod->m4mod->n_o) { For(g,tree->mod->ras->n_catg) { For(k,tree->mod->ns) { For(l,tree->mod->ns) { postprob[i] += (1./site_lk) * tree->mod->ras->gamma_r_proba->v[g] * tree->mod->m4mod->h_fq[i] * tree->mod->m4mod->o_fq[j] * b->p_lk_left[tree->curr_site*dim1 + g*dim2 + k] * b->p_lk_tip_r[tree->curr_site*dim2 + l] * integral[g][i*tree->mod->m4mod->n_o+j][k][l]; /* (1./site_lk) * */ /* tree->mod->ras->gamma_r_proba[g] * */ /* tree->mod->m4mod->h_fq[i] * */ /* tree->mod->m4mod->o_fq[j] * */ /* b->p_lk_left[tree->curr_site][g][k] * */ /* b->p_lk_tip_r[tree->curr_site][l] * */ /* /\* b->p_lk_rght[tree->curr_site][0][l] * *\/ */ /* integral[g][i*tree->mod->m4mod->n_o+j][k][l]; */ } } } } sum += postprob[i]; } /* TO DO */ For(i,n_h) postprob[i] *= EXP(b->sum_scale_left[tree->curr_site]); } else { sum = .0; For(i,n_h) { postprob[i] = .0; For(j,tree->mod->m4mod->n_o) { For(g,tree->mod->ras->n_catg) { For(k,tree->mod->ns) { For(l,tree->mod->ns) { postprob[i] += (1./site_lk) * tree->mod->ras->gamma_r_proba->v[g] * tree->mod->m4mod->h_fq[i] * tree->mod->m4mod->o_fq[j] * b->p_lk_left[tree->curr_site*dim1 + g*dim2 + k] * b->p_lk_rght[tree->curr_site*dim1 + g*dim2 + l] * integral[g][i*tree->mod->m4mod->n_o+j][k][l]; /* (1./site_lk) * */ /* tree->mod->ras->gamma_r_proba[g] * */ /* tree->mod->m4mod->h_fq[i] * */ /* tree->mod->m4mod->o_fq[j] * */ /* b->p_lk_left[tree->curr_site][g][k] * */ /* b->p_lk_rght[tree->curr_site][g][l] * */ /* integral[g][i*tree->mod->m4mod->n_o+j][k][l]; */ } } } } sum += postprob[i]; } /* TO DO */ For(i,n_h) postprob[i] *= EXP(b->sum_scale_left[tree->curr_site] + b->sum_scale_rght[tree->curr_site]); } For(i,n_h) if((postprob[i] < -1.E-5) || (postprob[i] > 1.0+1.E-5)) { PhyML_Printf("\n. Cat : %d Prob : %f\n",i,postprob[i]); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } sum = 0.0; For(i,n_h) sum += postprob[i]; if((sum > 1.0+1.E-2) || (sum < 1.0-1.E-2)) { PhyML_Printf("\n. Sum = %f\n",sum); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Exit("\n"); } return; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl ***M4_Compute_Proba_Hidden_States_On_Edges(t_tree *tree) { int i; phydbl ***post_probs; phydbl ****integral; post_probs = (phydbl ***)mCalloc(2*tree->n_otu-3,sizeof(phydbl **)); For(i,2*tree->n_otu-3) { post_probs[i] = (phydbl **)mCalloc(tree->n_pattern,sizeof(phydbl *)); For(tree->curr_site,tree->n_pattern) post_probs[i][tree->curr_site] = (phydbl *)mCalloc(tree->mod->m4mod->n_h,sizeof(phydbl)); } /* Compute posterior probabilities of each hidden class (usually a rate class) on each edge, at each site. */ For(i,2*tree->n_otu-3) { PhyML_Printf("\n. Edge %4d/%4d",i+1,2*tree->n_otu-3); integral = M4_Integral_Term_On_One_Edge(tree->a_edges[i],tree); For(tree->curr_site,tree->n_pattern) M4_Post_Prob_H_Class_Edge_Site(tree->a_edges[i], integral, post_probs[i][tree->curr_site], tree); M4_Free_Integral_Term_On_One_Edge(integral,tree); } return post_probs; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Estimate the (posterior) mean relative rate of substitution on each branch at each site. The posterior mean rates averaged over sites is also estimated for each edge. The corresponding trees are printed in a postscript file. Tree 0 is the tree with posterior mean rates averaged over the sites. The following trees have posterior mean rates computed for each site. */ void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree) { char *s; int i; phydbl **mean_post_probs; phydbl *mrr; phydbl sum; int patt,br,rcat; phydbl *mean_br_len; int best_r,len_var; phydbl max_prob; mean_br_len = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); mean_post_probs = (phydbl **)mCalloc(2*tree->n_otu-3,sizeof(phydbl *)); For(i,2*tree->n_otu-3) mean_post_probs[i] = (phydbl *)mCalloc(tree->mod->m4mod->n_h,sizeof(phydbl )); mrr = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); Record_Br_Len(tree); M4_Scale_Br_Len(tree); /* Compute the posterior mean relative rate on each branch averaged over the whole set of patterns (sites) */ len_var = 0; For(patt,tree->n_pattern) { if(!Is_Invar(patt,1,NT,tree->data)) { For(br,2*tree->n_otu-3) { max_prob = -1.; best_r = -1; For(rcat,tree->mod->m4mod->n_h) { if(post_probs[br][patt][rcat] > max_prob) { max_prob = post_probs[br][patt][rcat]; best_r = rcat; } } /* /\* Add weight on each category, weight is proportional to the corresponding posterior probability *\/ */ /* For(rcat,tree->mod->m4mod->n_h) */ /* { */ /* mean_post_probs[br][rcat] += post_probs[br][patt][rcat] * tree->data->wght[patt]; */ /* } */ /* Add weight on the most probable rate category only */ mean_post_probs[br][best_r] += tree->data->wght[patt]; } len_var += tree->data->wght[patt]; } } For(br,2*tree->n_otu-3) { For(rcat,tree->mod->m4mod->n_h) { mean_post_probs[br][rcat] /= (phydbl)len_var; } } /* Compute the posterior mean relative rate and scale each branch length using this factor */ For(br,2*tree->n_otu-3) { For(rcat,tree->mod->m4mod->n_h) { mrr[br] += mean_post_probs[br][rcat] * tree->mod->m4mod->multipl[rcat]; } tree->a_edges[br]->l->v *= mrr[br]; } PhyML_Fprintf(tree->io->fp_out_stats,"\n. Mean posterior probabilities & rates\n"); For(rcat,tree->mod->m4mod->n_h) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]); PhyML_Fprintf(tree->io->fp_out_stats,"\n"); For(br,2*tree->n_otu-3) { For(rcat,tree->mod->m4mod->n_h) { PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",mean_post_probs[br][rcat]); } /* PhyML_Fprintf(tree->io->fp_out_stats," -- %f -> %f x %f = %f",mrr[br],tree->a_edges[br]->l->v,mrr[br],tree->a_edges[br]->l->v*mrr[br]); */ PhyML_Fprintf(tree->io->fp_out_stats," mrr=%f ",mrr[br]); if(mrr[br] > 1.) PhyML_Fprintf(tree->io->fp_out_stats,"FAST "); else PhyML_Fprintf(tree->io->fp_out_stats,"SLOW "); PhyML_Fprintf(tree->io->fp_out_stats,"%s",tree->a_edges[br]->labels[0]); PhyML_Fprintf(tree->io->fp_out_stats,"\n"); } /* Print the tree */ PhyML_Fprintf(tree->io->fp_out_tree,"Constrained tree with corrected branch lengths = "); s = Write_Tree(tree,NO); PhyML_Fprintf(tree->io->fp_out_tree,"%s\n",s); Free(s); tree->ps_tree = DR_Make_Tdraw_Struct(tree); DR_Print_Postscript_Header(tree->n_pattern,tree->io->fp_out_ps); tree->ps_page_number = 0; DR_Print_Tree_Postscript(tree->ps_page_number++,YES,tree->io->fp_out_ps,tree); /* Go back to the initial scaled branch lengths */ For(br,2*tree->n_otu-3) tree->a_edges[br]->l->v /= mrr[br]; /* Compute the posterior mean relative rate at each site, for each branch and each rate category. Scale branch lengths using these factors and print each tree (i.e., on tree per site pattern) */ For(patt,tree->n_pattern) { For(br,2*tree->n_otu-3) { mrr[br] = .0; max_prob = -1.; best_r = -1; For(rcat,tree->mod->m4mod->n_h) /* For each rate class */ { mrr[br] += post_probs[br][patt][rcat] * tree->mod->m4mod->multipl[rcat]; if(post_probs[br][patt][rcat] > max_prob) { max_prob = post_probs[br][patt][rcat]; best_r = rcat; } } /* mrr[br] = tree->mod->m4mod->multipl[best_r]; /\* Use the most probable relative rate instead of mean *\/ */ tree->a_edges[br]->l->v *= mrr[br]; } For(br,2*tree->n_otu-3) mean_br_len[br] += tree->a_edges[br]->l->v * tree->data->wght[patt]; PhyML_Fprintf(tree->io->fp_out_stats,"\n. Posterior probabilities site %4d (weight=%d, is_inv=%d)\n", patt, tree->data->wght[patt], Is_Invar(patt,1,NT,tree->data)); For(rcat,tree->mod->m4mod->n_h) PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f ",tree->mod->m4mod->multipl[rcat]); PhyML_Fprintf(tree->io->fp_out_stats,"\n"); For(br,2*tree->n_otu-3) { PhyML_Fprintf(tree->io->fp_out_stats,"Edge %3d ",br); max_prob = -1.0; best_r = -1; For(rcat,tree->mod->m4mod->n_h) { if(post_probs[br][patt][rcat] > max_prob) { max_prob = post_probs[br][patt][rcat]; best_r = rcat; } } For(rcat,tree->mod->m4mod->n_h) { PhyML_Fprintf(tree->io->fp_out_stats,"%2.4f",post_probs[br][patt][rcat]); if(rcat == best_r) PhyML_Fprintf(tree->io->fp_out_stats,"* "); else PhyML_Fprintf(tree->io->fp_out_stats," "); } /* PhyML_Fprintf(tree->io->fp_out_stats," -- %f -> %f x %f = %f",mrr[br],tree->a_edges[br]->l->v,mrr[br],tree->a_edges[br]->l->v*mrr[br]); */ if(mrr[br] > 1.01) PhyML_Fprintf(tree->io->fp_out_stats," %s ","FAST"); else if(mrr[br] < 0.99) PhyML_Fprintf(tree->io->fp_out_stats," %s ","SLOW"); else PhyML_Fprintf(tree->io->fp_out_stats," %s ","MEDIUM"); PhyML_Fprintf(tree->io->fp_out_stats,"%s ",tree->a_edges[br]->labels[0]); PhyML_Fprintf(tree->io->fp_out_stats,"\n"); } PhyML_Fprintf(tree->io->fp_out_tree,"tree %d = ",patt+1); s = Write_Tree(tree,NO); PhyML_Fprintf(tree->io->fp_out_tree,"%s\n",s); Free(s); DR_Print_Tree_Postscript(tree->ps_page_number++,YES,tree->io->fp_out_ps,tree); /* Go back to the initial scaled branch lengths */ For(br,2*tree->n_otu-3) tree->a_edges[br]->l->v /= mrr[br]; For(br,2*tree->n_otu-3) { sum = .0; For(rcat,tree->mod->m4mod->n_h) { sum += post_probs[br][patt][rcat]; } if((sum < 0.99) || (sum > 1.01)) { PhyML_Fprintf(tree->io->fp_out_stats,"\n. sum = %f\n",sum); PhyML_Fprintf(tree->io->fp_out_stats,"\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } } /* Mean branch lengths */ For(br,2*tree->n_otu-3) { mean_br_len[br] /= (phydbl)tree->data->init_len; tree->a_edges[br]->l->v = mean_br_len[br]; } PhyML_Fprintf(tree->io->fp_out_tree,"Mean branch lengths="); s = Write_Tree(tree,NO); PhyML_Fprintf(tree->io->fp_out_tree,"%s\n",s); Free(s); /* DR_Print_Tree_Postscript(tree->ps_page_number++,tree->io->fp_out_ps,tree); */ Restore_Br_Len(tree); DR_Print_Postscript_EOF(tree->io->fp_out_ps); For(br,2*tree->n_otu-3) { For(tree->curr_site,tree->n_pattern) Free(post_probs[br][tree->curr_site]); Free(post_probs[br]); } Free(post_probs); For(i,2*tree->n_otu-3) Free(mean_post_probs[i]); Free(mean_post_probs); Free(mrr); Free(mean_br_len); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Classifiy each branch, at each site, among one of the rate classes */ phydbl **M4_Site_Branch_Classification(phydbl ***post_probs, t_tree *tree) { int patt, br, rcat, i; phydbl **best_probs; phydbl post_prob_fast, post_prob_slow; best_probs = (phydbl **)mCalloc(tree->n_pattern,sizeof(phydbl *)); For(i,tree->n_pattern) best_probs[i] = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); tree->write_labels = YES; For(patt,tree->n_pattern) { For(br,2*tree->n_otu-3) { post_prob_fast = .0; post_prob_slow = .0; For(rcat,tree->mod->m4mod->n_h) /* For each rate class */ { if(tree->mod->m4mod->multipl[rcat] > 1.0) post_prob_fast += post_probs[br][patt][rcat]; else post_prob_slow += post_probs[br][patt][rcat]; } best_probs[patt][br] = (post_prob_fast > post_prob_slow)?(post_prob_fast):(post_prob_slow); if(!(tree->a_edges[br]->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(tree->a_edges[br]); /* if((post_prob_fast > post_prob_slow) && (best_probs[patt][br] > 0.95)) */ /* strcpy(tree->a_edges[br]->labels[tree->a_edges[br]->n_labels],"FASTER"); */ /* else if((post_prob_fast < post_prob_slow) && (best_probs[patt][br] > 0.95)) */ /* strcpy(tree->a_edges[br]->labels[tree->a_edges[br]->n_labels],"SLOWER"); */ /* else */ /* strcpy(tree->a_edges[br]->labels[tree->a_edges[br]->n_labels],"UNKNOWN"); */ if(post_prob_fast > post_prob_slow) strcpy(tree->a_edges[br]->labels[tree->a_edges[br]->n_labels],"FASTER"); else strcpy(tree->a_edges[br]->labels[tree->a_edges[br]->n_labels],"SLOWER"); tree->a_edges[br]->n_labels++; } } return best_probs; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Site_Branch_Classification_Experiment(t_tree *tree) { calign *cpy_data; short int **true_rclass, **est_rclass; phydbl **best_probs; int i,j; phydbl correct_class, mis_class, unknown; true_rclass = (short int **)mCalloc(tree->data->init_len, sizeof(short int *)); est_rclass = (short int **)mCalloc(tree->data->init_len, sizeof(short int *)); For(i,tree->data->init_len) { true_rclass[i] = (short int *)mCalloc(2*tree->n_otu-3,sizeof(short int)); est_rclass[i] = (short int *)mCalloc(2*tree->n_otu-3,sizeof(short int)); } if(tree->io->datatype != NT && tree->io->datatype != AA) { PhyML_Printf("\n. Not implemented yet."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } cpy_data = Copy_Cseq(tree->data,tree->io); /* Generate a simulated data set under H0, with the right sequence length. */ PhyML_Printf("\n. Evolving sequences (delta=%f, alpha=%f) ...\n",tree->mod->m4mod->delta,tree->mod->m4mod->alpha); Evolve(cpy_data,tree->mod,tree); For(i,cpy_data->init_len) { For(j,2*tree->n_otu-3) { if(!strcmp(tree->a_edges[j]->labels[i],"FASTER")) { true_rclass[i][j] = 1; } else if(!strcmp(tree->a_edges[j]->labels[i],"SLOWER")) { true_rclass[i][j] = 0; } else { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } } For(j,2*tree->n_otu-3) { Free_Edge_Labels(tree->a_edges[j]); tree->a_edges[j]->n_labels = 0; } /* Generate the memory needed for likelihood calculation because we will need bigger arrays */ Free_Tree_Lk(tree); Free_Tree_Pars(tree); tree->data = cpy_data; tree->n_pattern = tree->data->crunch_len; /* Allocate memory and initialize likelihood structure with simulated sequences (i.e., columns are not compressed) */ Make_Tree_4_Pars(tree,cpy_data,cpy_data->init_len); Make_Tree_4_Lk(tree,cpy_data,cpy_data->init_len); /* Estimate model parameters */ PhyML_Printf("\n. Estimating model parameters...\n"); tree->mod->s_opt->opt_cov_alpha = 1; tree->mod->s_opt->opt_cov_delta = 1; Round_Optimize(tree,tree->data,ROUND_MAX); tree->both_sides = 1; Lk(NULL,tree); /* Classify branches */ best_probs = M4_Site_Branch_Classification(M4_Compute_Proba_Hidden_States_On_Edges(tree),tree); For(i,tree->data->init_len) { For(j,2*tree->n_otu-3) { if(!strcmp(tree->a_edges[j]->labels[i],"FASTER")) { est_rclass[i][j] = 1; } else if(!strcmp(tree->a_edges[j]->labels[i],"SLOWER")) { est_rclass[i][j] = 0; } else if(!strcmp(tree->a_edges[j]->labels[i],"UNKNOWN")) { est_rclass[i][j] = -1; } else { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } } unknown = .0; correct_class = .0; mis_class = .0; For(i,tree->data->init_len) { For(j,2*tree->n_otu-3) { /* PhyML_Printf("\n. Edge %3d %4d %4d - %f",j,true_rclass[i][j],est_rclass[i][j],best_probs[i][j]); */ if(est_rclass[i][j] == -1) { unknown += 1.; } else if(est_rclass[i][j] == true_rclass[i][j]) { correct_class += 1.; } else if(est_rclass[i][j] != true_rclass[i][j]) { mis_class += 1.; } else { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } /* PhyML_Printf("\n"); */ } correct_class /= ((tree->data->init_len * (2*tree->n_otu-3)) - unknown); mis_class /= ((tree->data->init_len * (2*tree->n_otu-3)) - unknown); unknown /= (tree->data->init_len * (2*tree->n_otu-3)); PhyML_Printf("\n. correct_class = %f mis_class = %f unknown = %f", correct_class, mis_class, unknown); For(i,tree->data->init_len) { Free(true_rclass[i]); Free(est_rclass[i]); Free(best_probs[i]); } Free(true_rclass); Free(est_rclass); Free(best_probs); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Scale branch lengths such that they express expected number of nucleotide or amino-acid substitutions */ void M4_Scale_Br_Len(t_tree *tree) { phydbl scale_fact,mrs; int i,j; /* (1) Work out the relative mean rate of switches */ mrs = .0; For(i,tree->mod->m4mod->n_h) { For(j,tree->mod->m4mod->n_h) { if(j != i) mrs += tree->mod->m4mod->h_fq[i] * tree->mod->m4mod->h_mat[i*tree->mod->m4mod->n_h+j]; } } /* (2) scale_fact = (1 + delta x mrs) */ scale_fact = 1.0 + tree->mod->m4mod->delta * mrs; /* (3) Scale branch lengths */ For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v /= scale_fact; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Free_Integral_Term_On_One_Edge(phydbl ****integral, t_tree *tree) { int g,i,j; For(g,tree->mod->ras->n_catg) { For(i,tree->mod->m4mod->n_h) { For(j,tree->mod->m4mod->n_h) { Free(integral[g][i][j]); } Free(integral[g][i]); } Free(integral[g]); } Free(integral); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Detect_Site_Switches_Experiment(t_tree *tree) { t_mod *nocov_mod,*cov_mod,*ori_mod; calign *ori_data,*cpy_data; int i,n_iter; phydbl *nocov_bl,*cov_bl; phydbl *site_lnl_nocov, *site_lnl_cov; nocov_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); cov_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); site_lnl_nocov = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl)); site_lnl_cov = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl)); ori_data = tree->data; ori_mod = tree->mod; if(tree->io->datatype != NT && tree->io->datatype != AA) { PhyML_Printf("\n== Not implemented yet."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } cpy_data = Copy_Cseq(tree->data,tree->io); PhyML_Printf("\n. Estimate model parameters under non-switching substitution model.\n"); Switch_From_M4mod_To_Mod(tree->mod); Simu_Loop(tree); nocov_mod = (t_mod *)Copy_Model(tree->mod); /* Record model parameters */ For(i,2*tree->n_otu-3) nocov_bl[i] = tree->a_edges[i]->l->v; /* Record branch lengths */ For(i,tree->data->crunch_len) site_lnl_nocov[i] = tree->cur_site_lk[i]; Print_Lk(tree,"[LnL under non-switching substitution model]"); PhyML_Printf("\n. Estimate model parameters under switching substitution model.\n"); Switch_From_Mod_To_M4mod(tree->mod); Simu_Loop(tree); cov_mod = (t_mod *)Copy_Model(tree->mod); /* Record model parameters */ For(i,2*tree->n_otu-3) cov_bl[i] = tree->a_edges[i]->l->v; /* Record branch lengths */ For(i,tree->data->crunch_len) site_lnl_cov[i] = tree->cur_site_lk[i]; Print_Lk(tree,"[LnL under switching substitution model]"); PhyML_Printf("\n"); For(i,tree->data->crunch_len) PhyML_Printf("TRUTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]); /* Generate a simulated data set under H0, with the right sequence length. */ tree->mod = nocov_mod; Evolve(cpy_data, nocov_mod, tree); /* Generate the memory needed for likelihood calculation because we will need bigger arrays */ tree->mod = cov_mod; Free_Tree_Lk(tree); Free_Tree_Pars(tree); tree->data = cpy_data; tree->n_pattern = tree->data->crunch_len; tree->mod = cov_mod; /* Allocate memory and initialize likelihood structure with simulated sequences (i.e., columns are not compressed) */ Make_Tree_4_Pars(tree,cpy_data,cpy_data->init_len); Make_Tree_4_Lk(tree,cpy_data,cpy_data->init_len); n_iter = 0; do { /* Get the transition proba right to generate sequences */ tree->mod = nocov_mod; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = nocov_bl[i]; For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree); /* Generate sequences */ Evolve(cpy_data, nocov_mod, tree); tree->data = cpy_data; if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); tree->mod = nocov_mod; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = nocov_bl[i]; Lk(NULL,tree); For(i,tree->data->crunch_len) site_lnl_nocov[i] = tree->cur_site_lk[i]; Print_Lk(tree,"[CPY LnL under non-switching substitution model]"); tree->mod = cov_mod; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = cov_bl[i]; Lk(NULL,tree); For(i,tree->data->crunch_len) site_lnl_cov[i] = tree->cur_site_lk[i]; Print_Lk(tree,"[CPY LnL under switching substitution model]"); PhyML_Printf("\n"); For(i,tree->data->crunch_len) PhyML_Printf("SYNTH %f %f\n",site_lnl_nocov[i],site_lnl_cov[i]); } while(++n_iter < 200); Free_Tree_Lk(tree); Free_Tree_Pars(tree); /* Back to the original data set to check that everything is ok */ tree->data = ori_data; tree->n_pattern = tree->data->crunch_len; Make_Tree_4_Pars(tree,ori_data,ori_data->init_len); Make_Tree_4_Lk(tree,ori_data,ori_data->init_len); tree->mod = nocov_mod; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = nocov_bl[i]; Lk(NULL,tree); Print_Lk(tree,"[FINAL LnL under non-switching substitution model]"); tree->mod = cov_mod; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = cov_bl[i]; Lk(NULL,tree); Print_Lk(tree,"[FINAL LnL under switching substitution model]"); tree->mod = ori_mod; Free_Model(cov_mod); Free_Model(nocov_mod); Free(site_lnl_cov); Free(site_lnl_nocov); Free_Cseq(cpy_data); Free(nocov_bl); Free(cov_bl); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void M4_Posterior_Prediction_Experiment(t_tree *tree) { calign *ori_data,*cpy_data; int i,n_iter,n_simul; FILE *fp_nocov,*fp_cov,*fp_obs; char *s; t_edge *best_edge; s = (char *)mCalloc(100,sizeof(char)); best_edge = NULL; strcpy(s,tree->io->in_align_file); fp_nocov = Openfile(strcat(s,"_nocov"),1); strcpy(s,tree->io->in_align_file); fp_cov = Openfile(strcat(s,"_cov"),1); strcpy(s,tree->io->in_align_file); fp_obs = Openfile(strcat(s,"_obs"),1); Free(s); Print_Diversity_Header(fp_nocov, tree); Print_Diversity_Header(fp_cov, tree); Print_Diversity_Header(fp_obs, tree); ori_data = tree->data; if(tree->io->datatype != NT && tree->io->datatype != AA) { PhyML_Printf("\n. Not implemented yet."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } cpy_data = Copy_Cseq(tree->data,tree->io); /* Generate a simulated data set under H0, with the right sequence length. */ Set_Model_Parameters(tree->mod); For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree); Evolve(cpy_data,tree->mod,tree); /* Generate the memory needed for likelihood calculation because we will need bigger arrays */ Free_Tree_Lk(tree); Free_Tree_Pars(tree); tree->data = cpy_data; tree->n_pattern = tree->data->crunch_len; /* Allocate memory and initialize likelihood structure with simulated sequences (i.e., columns are not compressed) */ Make_Tree_4_Pars(tree,cpy_data,cpy_data->init_len); Make_Tree_4_Lk(tree,cpy_data,cpy_data->init_len); /* Go back to the original data set */ tree->data = ori_data; tree->n_pattern = ori_data->crunch_len; if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); PhyML_Printf("\n. Estimate model parameters under non-switching substitution model.\n"); Switch_From_M4mod_To_Mod(tree->mod); tree->bl_from_node_stamps = 1; /* best_edge = TIMES_Find_Best_Root_Position(tree); */ PhyML_Printf("\n. Put root on t_edge %3d",i); TIMES_Least_Square_Node_Times(best_edge,tree); TIMES_Adjust_Node_Times(tree); /* TIMES_Round_Optimize(tree); */ /* Round_Optimize(tree,tree->data); */ /* Simu_Loop(tree); */ Print_Lk(tree,"[LnL under non-switching substitution model]"); Print_Tree(tree->io->fp_out_tree,tree); /* Print observed diversities */ Init_Ui_Tips(tree); Site_Diversity(tree); Print_Diversity(fp_obs,tree); n_simul = 100; n_iter = 0; do { Evolve(cpy_data,tree->mod,tree); tree->data = cpy_data; tree->n_pattern = cpy_data->init_len; if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); Lk(NULL,tree); Init_Ui_Tips(tree); Site_Diversity(tree); Print_Diversity(fp_nocov,tree); Print_Lk(tree,"[CPY under non-switching substitution model]"); }while(++n_iter < n_simul); /* Go back to the original data set */ tree->data = ori_data; tree->n_pattern = ori_data->crunch_len; if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); PhyML_Printf("\n. Estimate model parameters under switching substitution model.\n"); Switch_From_Mod_To_M4mod(tree->mod); /* TIME_Round_Optimize(tree); */ /* Round_Optimize(tree,tree->data); */ /* Simu_Loop(tree); */ Print_Lk(tree,"[LnL under switching substitution model]"); Print_Tree(tree->io->fp_out_tree,tree); n_iter = 0; do { Evolve(cpy_data,tree->mod,tree); tree->data = cpy_data; tree->n_pattern = cpy_data->init_len; if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); Lk(NULL,tree); Init_Ui_Tips(tree); Site_Diversity(tree); Print_Diversity(fp_cov,tree); Print_Lk(tree,"[LnL under switching substitution model]"); }while(++n_iter < n_simul); fclose(fp_obs); fclose(fp_nocov); fclose(fp_cov); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// m4 *M4_Copy_M4_Model(t_mod *ori_mod, m4 *ori_m4mod) { int i,j,n_h, n_o; m4 *cpy_m4mod; if(ori_mod->io->datatype != NT && ori_mod->io->datatype != AA) { PhyML_Printf("\n== Not implemented yet."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } cpy_m4mod = (m4 *)M4_Make_Light(); cpy_m4mod->n_o = ori_m4mod->n_o; cpy_m4mod->n_h = ori_m4mod->n_h; if(ori_mod->use_m4mod) { M4_Make_Complete(cpy_m4mod->n_h, cpy_m4mod->n_o, cpy_m4mod); n_h = cpy_m4mod->n_h; n_o = cpy_m4mod->n_o; cpy_m4mod->n_h = ori_m4mod->n_h; cpy_m4mod->n_o = ori_m4mod->n_o; For(i,n_h) For(j,n_o*n_o) cpy_m4mod->o_mats[i][j] = ori_m4mod->o_mats[i][j]; For(i,n_h) cpy_m4mod->multipl[i] = ori_m4mod->multipl[i]; For(i,n_h) cpy_m4mod->multipl_unscaled[i] = ori_m4mod->multipl_unscaled[i]; For(i,n_o*n_o) cpy_m4mod->o_rr[i] = ori_m4mod->o_rr[i]; For(i,n_h*n_h) cpy_m4mod->h_rr[i] = ori_m4mod->h_rr[i]; For(i,n_h*n_h) cpy_m4mod->h_mat[i] = ori_m4mod->h_mat[i]; For(i,n_o) cpy_m4mod->o_fq[i] = ori_m4mod->o_fq[i]; For(i,n_h) cpy_m4mod->h_fq[i] = ori_m4mod->h_fq[i]; For(i,n_h) cpy_m4mod->h_fq_unscaled[i] = ori_m4mod->h_fq_unscaled[i]; cpy_m4mod->delta = ori_m4mod->delta; cpy_m4mod->alpha = ori_m4mod->alpha; } return cpy_m4mod; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/m4.h000066400000000000000000000034001263450375500141340ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef M4_H #define M4_H #include "spr.h" #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "time.h" #include "draw.h" #ifdef PART #include "mg.h" #endif int M4_main(int argc, char **argv); void M4_Make_Complete(int n_h, int n_o, m4 *m4mod); m4 *M4_Make_Light(); void M4_Free_M4_Model(m4 *m4mod); void M4_Init_Qmat(m4 *m4mod, calign *data, t_mod *mod); void M4_Update_Qmat(m4 *m4mod, t_mod *mod); void M4_Init_Model(m4 *m4mod, calign *data, t_mod *mod); void M4_Init_P_Lk_Tips_Double(t_tree *tree); void M4_Init_P_Lk_Tips_Int(t_tree *tree); void M4_Post_Prob_H_Class_Edge_Site(t_edge *b, phydbl ****integral, phydbl *postprob, t_tree *tree); phydbl ****M4_Integral_Term_On_One_Edge(t_edge *b, t_tree *tree); phydbl ***M4_Compute_Proba_Hidden_States_On_Edges(t_tree *tree); void M4_Free_Integral_Term_On_One_Edge(phydbl ****integral, t_tree *tree); void M4_Compute_Posterior_Mean_Rates(phydbl ***post_probs, t_tree *tree); void M4_Scale_Br_Len(t_tree *tree); void M4_Detect_Site_Switches_Experiment(t_tree *tree); m4 *M4_Copy_M4_Model(t_mod *ori_mod, m4 *ori_m4mod); void M4_Posterior_Prediction_Experiment(t_tree *tree); void M4_Set_M4mod_Default(m4 *m4mod); phydbl **M4_Site_Branch_Classification(phydbl ***post_probs, t_tree *tree); void M4_Site_Branch_Classification_Experiment(t_tree *tree); #endif phyml-3.2.0/src/main.c000066400000000000000000000415031263450375500145410ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "spr.h" #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "mixt.h" #include "invitee.h" //#include "geo.h" #ifdef MPI #include "mpi_boot.h" #endif #ifdef BEAGLE #include "beagle_utils.h" #endif #if (defined PHYML || EVOLVE) int main(int argc, char **argv) { calign *cdata; option *io; t_tree *tree; int num_data_set; int num_tree,num_rand_tree; t_mod *mod; time_t t_beg,t_end; phydbl best_lnL; int r_seed; char *most_likely_tree=NULL; int orig_random_input_tree; #ifdef MPI int rc; rc = MPI_Init(&argc,&argv); if (rc != MPI_SUCCESS) { PhyML_Printf("\n== Err. starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD,&Global_numTask); MPI_Comm_rank(MPI_COMM_WORLD,&Global_myRank); #endif #ifdef QUIET setvbuf(stdout,NULL,_IOFBF,2048); #endif tree = NULL; mod = NULL; best_lnL = UNLIKELY; io = (option *)Get_Input(argc,argv); if(!io) return(0); else if(io->use_xml == YES) { Free(io); return(0); } #ifdef EVOLVE io->colalias = NO; #endif r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed); srand(r_seed); io->r_seed = r_seed; if(io->in_tree == 2) Test_Multiple_Data_Set_Format(io); else io->n_trees = 1; if(io->n_trees == 0 && io->in_tree == 2) { PhyML_Printf("\n== Err.: the input tree file does not provide a tree in valid format."); Exit("\n"); } if((io->n_data_sets > 1) && (io->n_trees > 1)) { io->n_data_sets = MIN(io->n_trees,io->n_data_sets); io->n_trees = MIN(io->n_trees,io->n_data_sets); } For(num_data_set,io->n_data_sets) { best_lnL = UNLIKELY; Get_Seq(io); Make_Model_Complete(io->mod); Set_Model_Name(io->mod); Print_Settings(io); mod = io->mod; orig_random_input_tree = io->mod->s_opt->random_input_tree; if(io->data) { if(io->n_data_sets > 1) PhyML_Printf("\n. Data set [#%d]\n",num_data_set+1); cdata = Compact_Data(io->data,io); Free_Seq(io->data,cdata->n_otu); for(num_tree=(io->n_trees == 1)?(0):(num_data_set);num_tree < io->n_trees;num_tree++) { if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1; if(orig_random_input_tree == YES && io->n_trees > 1) { PhyML_Printf("\n== Cannot combine random starting trees with multiple input trees."); Exit("\n"); } For(num_rand_tree,io->mod->s_opt->n_rand_starts) { if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE)) if(!io->quiet) PhyML_Printf("\n\n. [Random start %3d/%3d]",num_rand_tree+1,io->mod->s_opt->n_rand_starts); Init_Model(cdata,mod,io); if(io->mod->use_m4mod) M4_Init_Model(mod->m4mod,cdata,mod); //Make the initial tree switch(io->in_tree) { case 0 : case 1 : { tree = Dist_And_BioNJ(cdata,mod,io); break; } case 2 : { tree = Read_User_Tree(cdata,mod,io); break; } } if(io->fp_in_constraint_tree != NULL) { char *s; PhyML_Printf("\n. Reading constraint tree file..."); io->cstr_tree = Read_Tree_File_Phylip(io->fp_in_constraint_tree); if(io->cstr_tree->n_root != NULL) { PhyML_Printf("\n== The constraint tree file must be unrooted"); Exit("\n"); } s = Add_Taxa_To_Constraint_Tree(io->fp_in_constraint_tree,cdata); fflush(NULL); Free_Tree(tree); tree = Read_Tree(&s); io->in_tree = 2; Free(s); Check_Constraint_Tree_Taxa_Names(io->cstr_tree,cdata); Alloc_Bip(io->cstr_tree); Get_Bip(io->cstr_tree->a_nodes[0], io->cstr_tree->a_nodes[0]->v[0], io->cstr_tree); if(!tree->has_branch_lengths) Add_BioNJ_Branch_Lengths(tree,cdata,mod); } if(!tree) continue; time(&t_beg); time(&(tree->t_beg)); tree->mod = mod; tree->io = io; tree->data = cdata; tree->n_pattern = tree->data->crunch_len; tree->n_root = NULL; tree->e_root = NULL; Set_Both_Sides(YES,tree); if(mod->s_opt->random_input_tree) { PhyML_Printf("\n"); Random_Tree(tree); } if((!num_data_set) && (!num_tree) && (!num_rand_tree)) Check_Memory_Amount(tree); if(io->cstr_tree && !Check_Topo_Constraints(tree,io->cstr_tree)) { PhyML_Printf("\n\n== The initial tree does not satisfy the topological constraint."); PhyML_Printf("\n== Please use the user input tree option with an adequate tree topology."); Exit("\n"); } Prepare_Tree_For_Lk(tree); Br_Len_Not_Involving_Invar(tree); Unscale_Br_Len_Multiplier_Tree(tree); #ifdef BEAGLE if(mod->bootstrap == YES) { PhyML_Printf("\n== PhyML-BEAGLE does not support bootstrap analysis yet... "); Exit("\n"); } if(mod->ras->invar == YES) { PhyML_Printf("\n== PhyML-BEAGLE does not support invariant site models yet... "); Exit("\n"); } #endif #ifdef PHYML if(io->in_tree == 1) Spr_Pars(tree); /* /\* ******************** *\/ */ /* Sample_Ancestral_Seq(NO,YES,tree); */ /* tree->mod->augmented = YES; */ /* Lk(NULL,tree); */ /* /\* ******************** *\/ */ if(tree->mod->s_opt->opt_topo) { if(tree->mod->s_opt->topo_search == NNI_MOVE) Simu_Loop(tree); else if(tree->mod->s_opt->topo_search == SPR_MOVE) Speed_Spr_Loop(tree); else Best_Of_NNI_And_SPR(tree); if(tree->n_root) Add_Root(tree->a_edges[0],tree); } else { #ifdef BEAGLE tree->b_inst = create_beagle_instance(tree, io->quiet, io); #endif //Optimize Branch lengths? if(tree->mod->s_opt->opt_subst_param || tree->mod->s_opt->opt_bl) { Round_Optimize(tree,tree->data,ROUND_MAX); } else { //No topology or branch length optimizations Lk(NULL,tree); } } if(tree->mod->gamma_mgf_bl) Optimum_Root_Position_IL_Model(tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); Pars(NULL,tree); Get_Tree_Size(tree); PhyML_Printf("\n\n. Log likelihood of the current tree: %f.",tree->c_lnL); if(tree->io->ancestral == YES) ML_Ancestral_Sequences(tree); /* Build_Distrib_Number_Of_Diff_States_Under_Model(tree); */ /* Exit("\n"); */ Check_Br_Lens(tree); Br_Len_Involving_Invar(tree); Rescale_Br_Len_Multiplier_Tree(tree); #elif defined EVOLVE Evolve(tree->data,tree->mod,tree); Exit("\n. Exiting 'evolve'\n"); #endif if(!tree->n_root) Get_Best_Root_Position(tree); /* Print the tree estimated using the current random (or BioNJ) starting tree */ /* if(io->mod->s_opt->n_rand_starts > 1) */ if(orig_random_input_tree == YES) { Print_Tree(io->fp_out_trees,tree); fflush(NULL); } /* Record the most likely tree in a string of characters */ if(tree->c_lnL > best_lnL) { best_lnL = tree->c_lnL; if(most_likely_tree) Free(most_likely_tree); most_likely_tree = Write_Tree(tree,NO); } time(&t_end); Print_Fp_Out(io->fp_out_stats,t_beg,t_end,tree, io,num_data_set+1, (orig_random_input_tree == YES)?(num_rand_tree):(num_tree), (num_rand_tree == io->mod->s_opt->n_rand_starts-1)?(YES):(NO)); if(tree->io->print_site_lnl) Print_Site_Lk(tree,io->fp_out_lk); /* Start from BioNJ tree */ if((num_rand_tree == io->mod->s_opt->n_rand_starts-1) && (tree->mod->s_opt->random_input_tree)) { /* Do one more iteration in the loop, but don't randomize the tree */ tree->mod->s_opt->n_rand_starts++; tree->mod->s_opt->random_input_tree = NO; } #ifdef BEAGLE finalize_beagle_instance(tree); #endif Free_Spr_List(tree); Free_Triplet(tree->triplet_struct); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); } //Tree done /* Launch bootstrap analysis */ if(mod->bootstrap) { if(!io->quiet) PhyML_Printf("\n\n. Launch bootstrap analysis on the most likely tree..."); #ifdef MPI MPI_Bcast (most_likely_tree, strlen(most_likely_tree)+1, MPI_CHAR, 0, MPI_COMM_WORLD); if(!io->quiet) PhyML_Printf("\n\n. The bootstrap analysis will use %d CPUs.",Global_numTask); #endif most_likely_tree = Bootstrap_From_String(most_likely_tree,cdata,mod,io); PhyML_Printf("\n\n. Completed the bootstrap analysis succesfully."); fflush(NULL); } else if(io->ratio_test != NO) { /* Launch aLRT */ most_likely_tree = aLRT_From_String(most_likely_tree,cdata,mod,io); } /* Print the most likely tree in the output file */ if(!io->quiet) PhyML_Printf("\n\n. Printing the most likely tree in file '%s'.", Basename(io->out_tree_file)); if(io->n_data_sets == 1) rewind(io->fp_out_tree); PhyML_Fprintf(io->fp_out_tree,"%s\n",most_likely_tree); if(io->n_trees > 1 && io->n_data_sets > 1) break; } Free_Cseq(cdata); } else { PhyML_Printf("\n== No data was found.\n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } Free_Model_Complete(mod); } if(most_likely_tree) Free(most_likely_tree); if(mod->s_opt->n_rand_starts > 1) PhyML_Printf("\n. Best log likelihood: %f\n",best_lnL); Free_Optimiz(mod->s_opt); M4_Free_M4_Model(mod->m4mod); Free_Model_Basic(mod); if(io->fp_in_constraint_tree) fclose(io->fp_in_constraint_tree); if(io->fp_in_align) fclose(io->fp_in_align); if(io->fp_in_tree) fclose(io->fp_in_tree); if(io->fp_out_lk) fclose(io->fp_out_lk); if(io->fp_out_tree) fclose(io->fp_out_tree); if(io->fp_out_trees) fclose(io->fp_out_trees); if(io->fp_out_stats) fclose(io->fp_out_stats); if(io->fp_out_trace) fclose(io->fp_out_trace); if(io->fp_in_constraint_tree != NULL) Free_Tree(io->cstr_tree); Free_Input(io); time(&t_end); Print_Time_Info(t_beg,t_end); #ifdef MPI MPI_Finalize(); #endif return 0; } #elif(M4) #include "m4.h" int main(int argc, char **argv) { M4_main(argc, argv); return 1; } #elif(PART) #include "mg.h" int main(int argc, char **argv) { PART_main(argc, argv); return 1; } #elif(PHYTIME) #include "times.h" int main(int argc, char **argv) { TIMES_main(argc, argv); return 1; } #elif(PHYCONT) #include "continuous.h" int main(int argc, char **argv) { CONT_main(argc, argv); return 1; } #elif(RF) int main(int argc, char **argv) { t_tree *tree1, *tree2; FILE *fp_tree1, *fp_tree2; int i,j; fp_tree1 = (FILE *)fopen(argv[1],"r"); fp_tree2 = (FILE *)fopen(argv[2],"r"); tree1 = Read_Tree_File_Phylip(fp_tree1); tree2 = Read_Tree_File_Phylip(fp_tree2); Match_Nodes_In_Small_Tree(tree1,tree2); For(i,2*tree1->n_otu-2) { printf("\n. Node %d in tree1 matches node %d in tree2",i,(tree1->noeud[i]->match_node)?(tree1->noeud[i]->match_node->num):(-1)); } /* t_tree *tree1, *tree2; */ /* FILE *fp_tree1, *fp_tree2; */ /* int i,j,rf,n_edges,n_common,bip_size; */ /* phydbl thresh; */ /* t_edge *b; */ /* fp_tree1 = (FILE *)fopen(argv[1],"r"); */ /* fp_tree2 = (FILE *)fopen(argv[2],"r"); */ /* thresh = (phydbl)atof(argv[3]); */ /* tree1 = Read_Tree_File(fp_tree1); */ /* tree2 = Read_Tree_File(fp_tree2); */ /* Get_Rid_Of_Prefix('_',tree1); */ /* /\* Find_Common_Tips(tree1,tree2); *\/ */ /* Alloc_Bip(tree1); */ /* Alloc_Bip(tree2); */ /* Get_Bip(tree1->noeud[0],tree1->noeud[0]->v[0],tree1); */ /* Get_Bip(tree2->noeud[0],tree2->noeud[0]->v[0],tree2); */ /* /\* PhyML_Printf("\n. rf=%f\n",Compare_Bip_On_Existing_Edges(thresh,tree1,tree2)); *\/ */ /* For(i,2*tree1->n_otu-3) tree1->a_edges[i]->bip_score = 0; */ /* For(i,2*tree2->n_otu-3) tree2->a_edges[i]->bip_score = 0; */ /* rf = 0; */ /* n_edges = 0; */ /* /\* First tree *\/ */ /* For(i,2*tree1->n_otu-3) */ /* { */ /* /\* Consider the branch only if the corresponding bipartition has size > 1 *\/ */ /* b = tree1->a_edges[i]; */ /* bip_size = MIN(b->left->bip_size[b->l_r],b->rght->bip_size[b->r_l]); */ /* if(bip_size > 1) */ /* { */ /* /\* with non-zero length *\/ */ /* if(tree1->a_edges[i]->l > thresh) */ /* { */ /* n_edges++; */ /* /\* This t_edge is not found in tree2 *\/ */ /* if(!tree1->a_edges[i]->bip_score) rf++; ; */ /* } */ /* } */ /* } */ /* /\* Second tree *\/ */ /* For(i,2*tree2->n_otu-3) */ /* { */ /* b = tree2->a_edges[i]; */ /* bip_size = MIN(b->left->bip_size[b->l_r],b->rght->bip_size[b->r_l]); */ /* if(bip_size > 1) */ /* { */ /* if(tree2->a_edges[i]->l > thresh) */ /* { */ /* n_edges++; */ /* /\* This t_edge is not found in tree1 *\/ */ /* if(!tree2->a_edges[i]->bip_score) rf++; ; */ /* } */ /* } */ /* } */ /* if(!n_edges) */ /* { */ /* Exit("\n. No comparable internal edges were found.\n"); */ /* } */ /* else */ /* { */ /* PhyML_Printf("\n. Robinson and Foulds distance: %f.",(double)rf/(n_edges)); */ /* /\* PhyML_Printf("\n. %d internal edges were processed (%d in the first tree, %d in the second).\n",n_edges,n_edges_t1,n_edges-n_edges_t1); *\/ */ /* PhyML_Printf("\n"); */ /* } */ return 1; } #elif(TIPORDER) #include "tiporder.h" int main(int argc, char **argv) { TIPO_main(argc, argv); return 1; } #elif(TEST) #include "xml.h" int main(int argc, char **argv) { } #elif(INVITEE) #include "invitee.h" int main(int argc, char **argv) { /*My_Function(argc, argv);*/ /* PhyTime_XML(argc, argv); */ Get_Input(argc,argv); return 1; } #elif(GEO) #include "geo.h" int main(int argc, char **argv) { GEO_Main(argc,argv); return 1; } #elif(PHYREX) #include "phyrex.h" int main(int argc, char **argv) { PHYREX_Main(argc,argv); return 1; } #elif(CHECKPOINT) #include "checkpoint.h" int main(int argc, char **argv) { CHECK_Main(argc,argv); return 1; } #endif phyml-3.2.0/src/make.c000066400000000000000000001311351263450375500145330ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "make.h" ////////////////////////////////////////////////////////////// void Make_Tree_4_Lk(t_tree *tree, calign *cdata, int n_site) { int i; tree->c_lnL_sorted = (phydbl *)mCalloc(tree->n_pattern,sizeof(phydbl)); tree->cur_site_lk = (phydbl *)mCalloc(tree->n_pattern,sizeof(phydbl)); tree->old_site_lk = (phydbl *)mCalloc(tree->n_pattern,sizeof(phydbl)); tree->site_lk_cat = (phydbl *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(phydbl)); tree->unscaled_site_lk_cat = (phydbl *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->n_pattern,sizeof(phydbl)); tree->fact_sum_scale = (int *)mCalloc(tree->n_pattern,sizeof(int)); tree->log_lks_aLRT = (phydbl **)mCalloc(3,sizeof(phydbl *)); For(i,3) tree->log_lks_aLRT[i] = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl)); For(i,2*tree->n_otu-1) Make_Edge_NNI(tree->a_edges[i]); if(tree->is_mixt_tree == NO) { For(i,2*tree->n_otu-1) Make_Edge_Lk(tree->a_edges[i],tree); For(i,2*tree->n_otu-2) Make_Node_Lk(tree->a_nodes[i]); if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); Init_P_Lk_Loc(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Tree_4_Pars(t_tree *tree, calign *cdata, int n_site) { int i; tree->site_pars = (int *)mCalloc(tree->n_pattern,sizeof(int)); tree->step_mat = (int *)mCalloc(tree->mod->ns * tree->mod->ns,sizeof(int)); For(i,2*tree->n_otu-1) Make_Edge_Pars(tree->a_edges[i],tree); Init_Ui_Tips(tree); Init_P_Pars_Tips(tree); /* Must be called after Init_Ui_Tips is called */ Get_Step_Mat(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_All_Edges_Lk(t_node *a, t_node *d, t_tree *tree) { int i; For(i,3) if((a->v[i]) && (a->v[i] == d)) Make_Edge_Lk(a->b[i],tree); if(d->tax) return; else { For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) Make_All_Edges_Lk(d,d->v[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_New_Edge_Label(t_edge *b) { int i; b->labels = (char **)realloc(b->labels,(b->n_labels+BLOCK_LABELS)*sizeof(char *)); if(!b->labels) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } else { for(i=b->n_labels;in_labels+BLOCK_LABELS;i++) b->labels[i] = (char *)mCalloc(T_MAX_LABEL,sizeof(char)); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_edge *Make_Edge_Light(t_node *a, t_node *d, int num) { t_edge *b; b = (t_edge *)mCalloc(1,sizeof(t_edge)); b->l = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(b->l); b->l_old = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(b->l_old); b->l_var = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(b->l_var); b->l_var_old = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(b->l_var_old); Init_Edge_Light(b,num); if(a && b) { b->left = a; b->rght = d; if(a->tax) {b->rght = a; b->left = d;} /* root */ /* a tip is necessary on the right side of the t_edge */ (b->left == a)? (Set_Edge_Dirs(b,a,d,NULL)): (Set_Edge_Dirs(b,d,a,NULL)); b->l->v = a->l[b->l_r]; if(a->tax) b->l->v = a->l[b->r_l]; b->l_old->v = b->l->v; } else { b->left = NULL; b->rght = NULL; } return b; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Pars(t_edge *b, t_tree *tree) { Make_Edge_Pars_Left(b,tree); Make_Edge_Pars_Rght(b,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Pars_Left(t_edge *b, t_tree *tree) { b->pars_l = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); b->ui_l = (unsigned int *)mCalloc(tree->data->crunch_len,sizeof(unsigned int)); b->p_pars_l = (int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(int )); b->n_diff_states_l = (int *)mCalloc(tree->mod->ns,sizeof(int )); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Pars_Rght(t_edge *b, t_tree *tree) { b->pars_r = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); b->ui_r = (unsigned int *)mCalloc(tree->data->crunch_len,sizeof(unsigned int)); b->p_pars_r = (int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(int )); b->n_diff_states_r = (int *)mCalloc(tree->mod->ns,sizeof(int )); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Lk(t_edge *b, t_tree *tree) { if(tree->is_mixt_tree) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } b->l_old->v = b->l->v; b->Pij_rr = (phydbl *)mCalloc(tree->mod->ras->n_catg*tree->mod->ns*tree->mod->ns,sizeof(phydbl)); Make_Edge_Lk_Left(b,tree); Make_Edge_Lk_Rght(b,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Lk_Left(t_edge *b, t_tree *tree) { int ns = tree->mod->ns; b->div_post_pred_left = (short int *)mCalloc(ns,sizeof(short int)); b->sum_scale_left_cat = (int *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); if(b->left && !b->left->tax) b->sum_scale_left = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); else b->sum_scale_left = NULL; if(b->left) { if((!b->left->tax) || (tree->mod->s_opt->greedy)) { b->p_lk_left = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl)); b->p_lk_tip_l = NULL; } else if(b->left->tax) { b->p_lk_left = NULL; b->p_lk_tip_l = (short int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(short int )); } } else { b->p_lk_left = NULL; b->p_lk_tip_l = NULL; } if(b->num >= 2*tree->n_otu-3) { b->sum_scale_left = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); b->p_lk_left = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl)); } b->patt_id_left = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); b->p_lk_loc_left = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_Lk_Rght(t_edge *b, t_tree *tree) { int ns = tree->mod->ns; b->div_post_pred_rght = (short int *)mCalloc(ns,sizeof(short int)); b->sum_scale_rght_cat = (int *)mCalloc(MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); if(b->rght && !b->rght->tax) b->sum_scale_rght = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); else b->sum_scale_rght = NULL; if(b->rght) { if((!b->rght->tax) || (tree->mod->s_opt->greedy)) { b->p_lk_rght = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl)); b->p_lk_tip_r = NULL; } else if(b->rght->tax) { b->p_lk_rght = NULL; b->p_lk_tip_r = (short int *)mCalloc(tree->data->crunch_len*tree->mod->ns,sizeof(short int)); } } else { b->p_lk_rght = NULL; b->p_lk_tip_r = NULL; } if(b->num >= 2*tree->n_otu-3) { b->sum_scale_rght = (int *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes),sizeof(int)); b->p_lk_rght = (phydbl *)mCalloc(tree->data->crunch_len*MAX(tree->mod->ras->n_catg,tree->mod->n_mixt_classes)*tree->mod->ns,sizeof(phydbl)); } b->patt_id_rght = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); b->p_lk_loc_rght = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Edge_NNI(t_edge *b) { b->nni = Make_NNI(); b->nni->b = b; b->nni->left = b->left; b->nni->rght = b->rght; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// nni *Make_NNI() { nni *a_nni; a_nni = (nni *)mCalloc(1,sizeof(nni )); Init_NNI(a_nni); return a_nni; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_node *Make_Node_Light(int num) { t_node *n; n = (t_node *)mCalloc(1,sizeof(t_node)); n->v = (t_node **)mCalloc(3,sizeof(t_node *)); n->l = (phydbl *)mCalloc(3,sizeof(phydbl)); n->b = (t_edge **)mCalloc(3,sizeof(t_edge *)); n->score = (phydbl *)mCalloc(3,sizeof(phydbl)); n->s_ingrp = (int *)mCalloc(3,sizeof(int)); n->s_outgrp = (int *)mCalloc(3,sizeof(int)); Init_Node_Light(n,num); return n; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Node_Lk(t_node *n) { /* n->n_ex_nodes = (int *)mCalloc(2,sizeof(int)); */ return; } nexcom **Make_Nexus_Com() { nexcom **com; int i; com = (nexcom **)mCalloc(N_MAX_NEX_COM,sizeof(nexcom *)); For(i,N_MAX_NEX_COM) { com[i] = (nexcom *)mCalloc(1,sizeof(nexcom)); com[i]->name = (char *)mCalloc(T_MAX_NEX_COM,sizeof(char)); com[i]->parm = (nexparm **)mCalloc(N_MAX_NEX_PARM,sizeof(nexparm *)); } return com; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// nexparm *Make_Nexus_Parm() { nexparm *parm; parm = (nexparm *)mCalloc(1,sizeof(nexparm)); parm->name = (char *)mCalloc(T_MAX_TOKEN,sizeof(char )); parm->value = (char *)mCalloc(T_MAX_TOKEN,sizeof(char )); return parm; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// matrix *Make_Mat(int n_otu) { matrix *mat; int i; mat = (matrix *)mCalloc(1,sizeof(matrix)); mat->n_otu = n_otu; mat->P = (phydbl **)mCalloc(n_otu,sizeof(phydbl *)); mat->Q = (phydbl **)mCalloc(n_otu,sizeof(phydbl *)); mat->dist = (phydbl **)mCalloc(n_otu,sizeof(phydbl *)); mat->on_off = (int *)mCalloc(n_otu,sizeof(int)); mat->name = (char **)mCalloc(n_otu,sizeof(char *)); mat->tip_node = (t_node **)mCalloc(n_otu,sizeof(t_node *)); For(i,n_otu) { mat->P[i] = (phydbl *)mCalloc(n_otu,sizeof(phydbl)); mat->Q[i] = (phydbl *)mCalloc(n_otu,sizeof(phydbl)); mat->dist[i] = (phydbl *)mCalloc(n_otu,sizeof(phydbl)); mat->name[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); } return mat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Make_Tree_From_Scratch(int n_otu, calign *data) { t_tree *tree; tree = Make_Tree(n_otu); Init_Tree(tree,n_otu); Make_All_Tree_Nodes(tree); Make_All_Tree_Edges(tree); Make_Tree_Path(tree); if(data) { Copy_Tax_Names_To_Tip_Labels(tree,data); tree->data = data; } #ifdef BEAGLE //offset the branch's partial indices because BEAGLE insists on first storing the tips/taxa int num_branches = 2*tree->n_otu-1; int i; for(i=0;i<2*tree->n_otu-1;++i) { //For edgeX, its "left" partial lies at index `num_tax + edgeX->num" tree->a_edges[i]->p_lk_left_idx = tree->n_otu + tree->a_edges[i]->p_lk_left_idx; //For edgeX, its "right" partial lies at index `num_tax + edgeX->num + num_branches" tree->a_edges[i]->p_lk_rght_idx = tree->n_otu + tree->a_edges[i]->p_lk_left_idx + num_branches; } #endif return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Make_Tree(int n_otu) { t_tree *tree; tree = (t_tree *)mCalloc(1,sizeof(t_tree )); tree->t_dir = (short int *)mCalloc((2*n_otu-2)*(2*n_otu-2),sizeof(int)); return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Tree_Path(t_tree *tree) { tree->curr_path = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_All_Tree_Nodes(t_tree *tree) { int i; tree->a_nodes = (t_node **)mCalloc(2*tree->n_otu-1,sizeof(t_node *)); For(i,2*tree->n_otu-1) { tree->a_nodes[i] = (t_node *)Make_Node_Light(i); if(i < tree->n_otu) tree->a_nodes[i]->tax = 1; else tree->a_nodes[i]->tax = 0; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_All_Tree_Edges(t_tree *tree) { int i; tree->a_edges = (t_edge **)mCalloc(2*tree->n_otu-1,sizeof(t_edge *)); For(i,2*tree->n_otu-1) tree->a_edges[i] = (t_edge *)Make_Edge_Light(NULL,NULL,i); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// calign *Make_Cseq(int n_otu, int crunch_len, int state_len, int init_len, char **sp_names) { calign *cdata; int j; cdata = (calign *)mCalloc(1,sizeof(calign)); cdata->n_otu = n_otu; cdata->c_seq = (align **)mCalloc(n_otu,sizeof(align *)); cdata->b_frq = (phydbl *)mCalloc(T_MAX_ALPHABET,sizeof(phydbl)); cdata->wght = (int *)mCalloc(crunch_len,sizeof(int)); cdata->ambigu = (short int *)mCalloc(crunch_len,sizeof(short int)); cdata->invar = (short int *)mCalloc(crunch_len,sizeof(short int)); cdata->sitepatt = (int *)mCalloc(init_len,sizeof(int )); cdata->format = 0; cdata->crunch_len = crunch_len; cdata->init_len = init_len; cdata->obs_pinvar = .0; For(j,n_otu) { cdata->c_seq[j] = (align *)mCalloc(1,sizeof(align)); cdata->c_seq[j]->name = (char *)mCalloc((int)(strlen(sp_names[j])+1),sizeof(char)); strcpy(cdata->c_seq[j]->name,sp_names[j]); cdata->c_seq[j]->state = (char *)mCalloc(crunch_len*state_len,sizeof(char)); cdata->c_seq[j]->d_state = (int *)mCalloc(crunch_len*state_len,sizeof(int)); cdata->c_seq[j]->is_ambigu = (short int *)mCalloc(crunch_len,sizeof(short int)); } return cdata; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_treelist *Make_Treelist(int list_size) { t_treelist *tlist; tlist = (t_treelist *)mCalloc(1,sizeof(t_treelist)); tlist->list_size = list_size; tlist->tree = (t_tree **)mCalloc(list_size,sizeof(t_tree *)); return tlist; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_opt *Make_Optimiz() { t_opt *s_opt; s_opt = (t_opt *)mCalloc(1,sizeof(t_opt)); return s_opt; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Custom_Model(t_mod *mod) { if(!mod->r_mat) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(!mod->r_mat->rr->v) mod->r_mat->rr->v = (phydbl *)mCalloc(mod->ns*(mod->ns-1)/2,sizeof(phydbl)); if(!mod->r_mat->rr_val->v) mod->r_mat->rr_val->v = (phydbl *)mCalloc(mod->ns*(mod->ns-1)/2,sizeof(phydbl)); if(!mod->r_mat->rr_num->v) mod->r_mat->rr_num->v = (int *)mCalloc(mod->ns*(mod->ns-1)/2,sizeof(int *)); if(!mod->r_mat->n_rr_per_cat->v) mod->r_mat->n_rr_per_cat->v = (int *)mCalloc(mod->ns*(mod->ns-1)/2,sizeof(int)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_string *Make_String(int len) { t_string *ts; ts = (t_string *)mCalloc(1,sizeof(t_string)); ts->s = (char *)mCalloc(len,sizeof(char)); return(ts); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_mod *Make_Model_Basic() { t_mod *mod; mod = (t_mod *)mCalloc(1,sizeof(t_mod)); mod->modelname = Make_String(T_MAX_NAME); Init_String(mod->modelname); mod->custom_mod_string = Make_String(T_MAX_NAME); Init_String(mod->custom_mod_string); mod->ras = Make_RAS_Basic(); mod->kappa = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->kappa); mod->lambda = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->lambda); mod->br_len_mult = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->br_len_mult); mod->br_len_mult_unscaled = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->br_len_mult_unscaled); mod->mr = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->mr); mod->user_b_freq = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,mod->user_b_freq); mod->user_b_freq->v = (phydbl *)mCalloc(T_MAX_OPTION,sizeof(phydbl)); mod->e_frq_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->e_frq_weight); mod->r_mat_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(mod->r_mat_weight); mod->aa_rate_mat_file = Make_String(T_MAX_FILE); Init_String(mod->aa_rate_mat_file); return mod; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Call only when the values of mod->ns & ras->n_catg is set to its final value */ void Make_Model_Complete(t_mod *mod) { if(mod->use_m4mod == YES) { M4_Make_Complete(mod->m4mod->n_h,mod->m4mod->n_o,mod->m4mod); mod->ns = mod->m4mod->n_o * mod->m4mod->n_h; } mod->Pij_rr = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,mod->Pij_rr); mod->Pij_rr->v = (phydbl *)mCalloc(mod->ras->n_catg*mod->ns*mod->ns,sizeof(phydbl)); mod->eigen = (eigen *)Make_Eigen_Struct(mod->ns); // If r_mat (e_frq) are not NULL, then they have been created elsewhere and affected. if(!mod->r_mat) { mod->r_mat = (t_rmat *)Make_Rmat(mod->ns); Init_Rmat(mod->r_mat); } if(!mod->e_frq) { mod->e_frq = (t_efrq *)Make_Efrq(mod->ns); Init_Efrq(mod->e_frq); } Make_RAS_Complete(mod->ras); mod->user_b_freq->len = mod->ns; if(mod->whichmodel < 0) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(mod->whichmodel == CUSTOM) { Make_Custom_Model(mod); Translate_Custom_Mod_String(mod); } if(mod->whichmodel == GTR) { Make_Custom_Model(mod); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_ras *Make_RAS_Basic() { t_ras *ras; ras = (t_ras *)mCalloc(1,sizeof(t_ras)); ras->gamma_r_proba = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,ras->gamma_r_proba); ras->gamma_r_proba->v = NULL; ras->gamma_r_proba_unscaled = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,ras->gamma_r_proba_unscaled); ras->gamma_r_proba_unscaled->v = NULL; ras->gamma_rr = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,ras->gamma_rr); ras->gamma_rr->v = NULL; ras->gamma_rr_unscaled = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,ras->gamma_rr_unscaled); ras->gamma_rr_unscaled->v = NULL; ras->alpha = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(ras->alpha); ras->pinvar = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(ras->pinvar); ras->free_rate_mr = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(ras->free_rate_mr); return(ras); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Call only when the value of ras->n_catg is set to its final value */ void Make_RAS_Complete(t_ras *ras) { if(!ras->gamma_r_proba->v) { ras->gamma_r_proba->v = (phydbl *)mCalloc(ras->n_catg,sizeof(phydbl)); ras->gamma_r_proba_unscaled->v = (phydbl *)mCalloc(ras->n_catg,sizeof(phydbl)); ras->gamma_rr->v = (phydbl *)mCalloc(ras->n_catg,sizeof(phydbl)); ras->gamma_rr_unscaled->v = (phydbl *)mCalloc(ras->n_catg,sizeof(phydbl)); ras->skip_rate_cat = (short int *)mCalloc(ras->n_catg,sizeof(short int)); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_efrq *Make_Efrq(int ns) { t_efrq *e_frq; e_frq = (t_efrq *)mCalloc(1,sizeof(t_efrq)); e_frq->pi = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); e_frq->pi->v = (phydbl *)mCalloc(ns,sizeof(phydbl)); e_frq->pi->len = ns; e_frq->pi_unscaled = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); e_frq->pi_unscaled->v = (phydbl *)mCalloc(ns,sizeof(phydbl)); e_frq->pi_unscaled->len = ns; return e_frq; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_rmat *Make_Rmat(int ns) { t_rmat *r_mat; r_mat = (t_rmat *)mCalloc(1,sizeof(t_rmat)); r_mat->qmat = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,r_mat->qmat); r_mat->qmat_buff = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,r_mat->qmat_buff); r_mat->rr = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,r_mat->rr); r_mat->rr_val = (vect_dbl *)mCalloc(1,sizeof(vect_dbl)); Init_Vect_Dbl(0,r_mat->rr_val); r_mat->rr_num = (vect_int *)mCalloc(1,sizeof(vect_int)); Init_Vect_Int(0,r_mat->rr_num); r_mat->n_rr_per_cat = (vect_int *)mCalloc(1,sizeof(vect_int)); Init_Vect_Int(0,r_mat->n_rr_per_cat); r_mat->qmat->v = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); r_mat->qmat_buff->v = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); return(r_mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// option *Make_Input() { int i; option* io = (option *)mCalloc(1,sizeof(option)); io->in_align_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->in_tree_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->in_constraint_tree_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->in_coord_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_tree_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_trees_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_ancestral_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_boot_tree_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_boot_stats_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_stats_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_lk_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_ps_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_summary_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->out_trace_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->nt_or_cd = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->run_id_string = (char *)mCalloc(T_MAX_OPTION,sizeof(char)); io->clade_list_file = (char *)mCalloc(T_MAX_FILE,sizeof(char)); io->alphabet = (char **)mCalloc(T_MAX_ALPHABET,sizeof(char *)); For(i,T_MAX_ALPHABET) io->alphabet[i] = (char *)mCalloc(T_MAX_STATE,sizeof(char )); io->treelist = (t_treelist *)mCalloc(1,sizeof(t_treelist)); io->mcmc = (t_mcmc *)MCMC_Make_MCMC_Struct(); io->rates = (t_rate *)RATES_Make_Rate_Struct(-1); return io; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_mcmc *MCMC_Make_MCMC_Struct() { t_mcmc *mcmc; mcmc = (t_mcmc *)mCalloc(1,sizeof(t_mcmc)); mcmc->out_filename = (char *)mCalloc(T_MAX_FILE,sizeof(char)); return(mcmc); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// eigen *Make_Eigen_Struct(int ns) { eigen *eig; eig = (eigen *)mCalloc(1,sizeof(eigen)); eig->size = ns; eig->space = (phydbl *)mCalloc(2*ns,sizeof(phydbl)); eig->space_int = (int *)mCalloc(2*ns,sizeof(int)); eig->e_val = (phydbl *)mCalloc(ns,sizeof(phydbl)); eig->e_val_im = (phydbl *)mCalloc(ns,sizeof(phydbl)); eig->r_e_vect = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); eig->r_e_vect_im = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); eig->l_e_vect = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); eig->q = (phydbl *)mCalloc(ns*ns,sizeof(phydbl)); Init_Eigen_Struct(eig); return eig; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// triplet *Make_Triplet_Struct(t_mod *mod) { int i,j,k; triplet *triplet_struct; triplet_struct = (triplet *)mCalloc(1,sizeof(triplet)); triplet_struct->size = mod->ns; triplet_struct->pi_bc = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); triplet_struct->pi_cd = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); triplet_struct->pi_bd = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); triplet_struct->F_bc = (phydbl *)mCalloc(mod->ns*mod->ns*mod->ras->n_catg,sizeof(phydbl)); triplet_struct->F_cd = (phydbl *)mCalloc(mod->ns*mod->ns*mod->ras->n_catg,sizeof(phydbl)); triplet_struct->F_bd = (phydbl *)mCalloc(mod->ns*mod->ns,sizeof(phydbl)); triplet_struct->core = (phydbl ****)mCalloc(mod->ras->n_catg,sizeof(phydbl ***)); triplet_struct->p_one_site = (phydbl ***)mCalloc(mod->ns,sizeof(phydbl **)); triplet_struct->sum_p_one_site = (phydbl ***)mCalloc(mod->ns,sizeof(phydbl **)); triplet_struct->eigen_struct = (eigen *)Make_Eigen_Struct(mod->ns); triplet_struct->mod = mod; For(k,mod->ras->n_catg) { triplet_struct->core[k] = (phydbl ***)mCalloc(mod->ns,sizeof(phydbl **)); For(i,mod->ns) { triplet_struct->core[k][i] = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *)); For(j,mod->ns) triplet_struct->core[k][i][j] = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); } } For(i,mod->ns) { triplet_struct->p_one_site[i] = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *)); For(j,mod->ns) triplet_struct->p_one_site[i][j] = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); } For(i,mod->ns) { triplet_struct->sum_p_one_site[i] = (phydbl **)mCalloc(mod->ns,sizeof(phydbl *)); For(j,mod->ns) triplet_struct->sum_p_one_site[i][j] = (phydbl *)mCalloc(mod->ns,sizeof(phydbl )); } return triplet_struct; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Short_L(t_tree *tree) { if(!tree->short_l) tree->short_l = (phydbl *)mCalloc(tree->n_short_l,sizeof(phydbl)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_attr *XML_Make_Attribute(xml_attr *prev, char *attr_name, char *attr_value) { xml_attr *new_attr; new_attr = (xml_attr *)mCalloc(1,sizeof(xml_attr)); new_attr->prev = prev; new_attr->next = NULL; if(prev != NULL) prev->next = new_attr; new_attr->name = (char *)mCalloc(strlen(attr_name)+1,sizeof(char)); strcpy(new_attr->name,attr_name); new_attr->value = (char *)mCalloc(strlen(attr_value)+1,sizeof(char)); strcpy(new_attr->value,attr_value); return new_attr; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Make_Node_Id(xml_node *n, char *id) { if(id) n->id = (char *)mCalloc(strlen(id)+1,sizeof(char)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Make_Node_Value(xml_node *n, char *val) { if(val) n->value = (char *)mCalloc(strlen(val)+1,sizeof(char)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Make_Node(char *name) { xml_node *new_node = (xml_node *)mCalloc(1,sizeof(xml_node)); if(name) { new_node->name = (char *)mCalloc(strlen(name)+1,sizeof(char)); } new_node->ds = (t_ds *)mCalloc(1,sizeof(t_ds)); return new_node; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Best_Spr(t_tree *tree) { tree->best_spr = Make_One_Spr(tree); Init_One_Spr(tree->best_spr); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Spr_List(t_tree *tree) { int i; tree->size_spr_list = 2*tree->n_otu-3; tree->spr_list = (t_spr **)mCalloc(2*tree->n_otu-2,sizeof(t_spr *)); For(i,2*tree->n_otu-2) { tree->spr_list[i] = Make_One_Spr(tree); Init_One_Spr(tree->spr_list[i]); } tree->perform_spr_right_away = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_spr *Make_One_Spr(t_tree *tree) { t_spr *a_spr; a_spr = (t_spr *)mCalloc(1,sizeof(t_spr)); a_spr->path = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); return a_spr; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_rate *RATES_Make_Rate_Struct(int n_otu) { t_rate *rates; rates = (t_rate *)mCalloc(1,sizeof(t_rate)); rates->is_allocated = NO; if(n_otu > 0) { rates->is_allocated = YES; rates->nd_r = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->br_r = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->buff_r = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->true_r = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->nd_t = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->buff_t = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->true_t = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_mean = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_prior = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_prior_min = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_prior_max = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_floor = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_rank = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->t_has_prior = (short int *)mCalloc(2*n_otu-1,sizeof(short int)); rates->dens = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->triplet = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->n_jps = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->t_jps = (int *)mCalloc(2*n_otu-2,sizeof(int)); rates->cov_l = (phydbl *)mCalloc((2*n_otu-2)*(2*n_otu-2),sizeof(phydbl)); rates->invcov = (phydbl *)mCalloc((2*n_otu-2)*(2*n_otu-2),sizeof(phydbl)); rates->mean_l = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->ml_l = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->cur_l = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->u_ml_l = (phydbl *)mCalloc(2*n_otu-3,sizeof(phydbl)); rates->u_cur_l = (phydbl *)mCalloc(2*n_otu-3,sizeof(phydbl)); rates->cov_r = (phydbl *)mCalloc((2*n_otu-2)*(2*n_otu-2),sizeof(phydbl)); rates->cond_var = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->mean_r = (phydbl *)mCalloc(2*n_otu-2,sizeof(phydbl)); rates->mean_t = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->lca = (t_node **)mCalloc((2*n_otu-1)*(2*n_otu-1),sizeof(t_node *)); rates->reg_coeff = (phydbl *)mCalloc((2*n_otu-2)*(2*n_otu-2),sizeof(phydbl)); rates->trip_reg_coeff = (phydbl *)mCalloc((2*n_otu-2)*(6*n_otu-9),sizeof(phydbl)); rates->trip_cond_cov = (phydbl *)mCalloc((2*n_otu-2)*9,sizeof(phydbl)); rates->_2n_vect1 = (phydbl *)mCalloc(2*n_otu,sizeof(phydbl)); rates->_2n_vect2 = (phydbl *)mCalloc(2*n_otu,sizeof(phydbl)); rates->_2n_vect3 = (phydbl *)mCalloc(2*n_otu,sizeof(phydbl)); rates->_2n_vect4 = (phydbl *)mCalloc(2*n_otu,sizeof(phydbl)); rates->_2n_vect5 = (short int *)mCalloc(2*n_otu,sizeof(short int)); rates->_2n2n_vect1 = (phydbl *)mCalloc(4*n_otu*n_otu,sizeof(phydbl)); rates->_2n2n_vect2 = (phydbl *)mCalloc(4*n_otu*n_otu,sizeof(phydbl)); rates->br_do_updt = (short int *)mCalloc(2*n_otu-1,sizeof(short int)); rates->cur_gamma_prior_mean = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->cur_gamma_prior_var = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->n_tips_below = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->time_slice_lims = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->n_time_slice_spans = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->curr_slice = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->has_survived = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->survival_rank = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->survival_dur = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->calib_prob = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->curr_nd_for_cal = (int *)mCalloc(2*n_otu-1,sizeof(int)); rates->t_prior_min_ori = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->t_prior_max_ori = (phydbl *)mCalloc(2*n_otu-1,sizeof(phydbl)); rates->times_partial_proba = (phydbl *)mCalloc(n_otu*n_otu,sizeof(phydbl)); rates->numb_calib_chosen = (int *)mCalloc(n_otu*n_otu,sizeof(phydbl)); } return rates; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_cal *Make_Calib(int n_otu) { t_cal *calib; int i; i = 0; calib = (t_cal *)mCalloc(1, sizeof(t_cal)); calib -> proba = (phydbl *)mCalloc(2 * n_otu, sizeof(phydbl)); calib -> all_applies_to = (t_node **)mCalloc(2 * n_otu - 1, sizeof(t_node *)); For(i, 2 * n_otu - 1) calib -> all_applies_to[i] = (t_node *)mCalloc(1, sizeof(t_node)); return(calib); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Rmat_Weight(t_tree *mixt_tree) { t_tree *tree, *buff_tree; scalar_dbl *curr_weight; tree = mixt_tree; do { if(tree->is_mixt_tree == YES) tree = tree->next; buff_tree = mixt_tree->next; do { if(buff_tree->mod->r_mat_weight == tree->mod->r_mat_weight) break; buff_tree = buff_tree->next; } while(buff_tree != tree); if(buff_tree == tree) Free(tree->mod->r_mat_weight); tree = tree->next; } while(tree); tree = mixt_tree; do { if(tree->is_mixt_tree == YES) tree = tree->next; tree->mod->r_mat_weight = NULL; tree = tree->next; } while(tree); tree = mixt_tree->next; tree->mod->r_mat_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(tree->mod->r_mat_weight); tree->mod->r_mat_weight->v = 1.0; curr_weight = tree->mod->r_mat_weight; buff_tree = tree = mixt_tree; do // For each mixt_tree { if(tree->is_mixt_tree == YES) tree = tree->next; buff_tree = mixt_tree->next; do { if(buff_tree->mod->r_mat == tree->mod->r_mat) { tree->mod->r_mat_weight = buff_tree->mod->r_mat_weight; break; } buff_tree = buff_tree->next; } while(buff_tree != tree); if(!tree->mod->r_mat_weight) { tree->mod->r_mat_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(tree->mod->r_mat_weight); tree->mod->r_mat_weight->v = 1.0; curr_weight->next = tree->mod->r_mat_weight; tree->mod->r_mat_weight->prev = curr_weight; curr_weight = tree->mod->r_mat_weight; } tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Efrq_Weight(t_tree *mixt_tree) { t_tree *tree, *buff_tree; scalar_dbl *curr_weight; tree = mixt_tree; do { if(tree->is_mixt_tree == YES) tree = tree->next; buff_tree = mixt_tree->next; do { if(buff_tree->mod->e_frq_weight == tree->mod->e_frq_weight) break; buff_tree = buff_tree->next; } while(buff_tree != tree); if(buff_tree == tree) { Free(tree->mod->e_frq_weight); } tree = tree->next; } while(tree); tree = mixt_tree; do { if(tree->is_mixt_tree == YES) tree = tree->next; tree->mod->e_frq_weight = NULL; tree = tree->next; } while(tree); tree = mixt_tree->next; tree->mod->e_frq_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(tree->mod->e_frq_weight); tree->mod->e_frq_weight->v = 1.0; curr_weight = tree->mod->e_frq_weight; buff_tree = tree = mixt_tree; do // For each mixt_tree { if(tree->is_mixt_tree == YES) tree = tree->next; buff_tree = mixt_tree->next; do { if(buff_tree->mod->e_frq == tree->mod->e_frq) { tree->mod->e_frq_weight = buff_tree->mod->e_frq_weight; break; } buff_tree = buff_tree->next; } while(buff_tree != tree); if(!tree->mod->e_frq_weight) { tree->mod->e_frq_weight = (scalar_dbl *)mCalloc(1,sizeof(scalar_dbl)); Init_Scalar_Dbl(tree->mod->e_frq_weight); tree->mod->e_frq_weight->v = 1.0; curr_weight->next = tree->mod->e_frq_weight; tree->mod->e_frq_weight->prev = curr_weight; curr_weight = tree->mod->e_frq_weight; } tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_geo *GEO_Make_Geo_Basic() { t_geo *t; t = (t_geo *)mCalloc(1,sizeof(t_geo)); return(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void GEO_Make_Geo_Complete(int ldscape_sz, int n_dim, int n_tax, t_geo *t) { int i; // F matrix t->f_mat = (phydbl *)mCalloc(ldscape_sz*ldscape_sz,sizeof(phydbl)); // R matrix t->r_mat = (phydbl *)mCalloc(ldscape_sz*ldscape_sz,sizeof(phydbl)); // Occupation vectors: one vector for each node t->occup = (int *)mCalloc((2*n_tax-1)*ldscape_sz,sizeof(int)); // Lineage locations t->idx_loc = (int *)mCalloc((int)(2*n_tax-1),sizeof(int)); // Sorted node heights t->sorted_nd = (t_node **)mCalloc((int)(2*n_tax-1),sizeof(t_node *)); // Covariance matrix t->cov = (phydbl *)mCalloc((int)(n_dim*n_dim),sizeof(phydbl)); // gives the location occupied beneath each node in the tree t->idx_loc_beneath = (int *)mCalloc((int)(2*n_tax-1)*ldscape_sz,sizeof(int)); // Locations t->coord_loc = (t_geo_coord **)mCalloc(ldscape_sz,sizeof(t_geo_coord *)); For(i,ldscape_sz) t->coord_loc[i] = GEO_Make_Geo_Coord(n_dim); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_geo_coord *GEO_Make_Geo_Coord(int dim) { t_geo_coord *t; t = (t_geo_coord *)mCalloc(1,sizeof(t_geo_coord)); t->lonlat = (phydbl *)mCalloc(dim,sizeof(phydbl)); t->id = (char *)mCalloc(T_MAX_ID_COORD,sizeof(char)); t->cpy = (t_geo_coord *)mCalloc(1,sizeof(t_geo_coord)); t->cpy->lonlat = (phydbl *)mCalloc(dim,sizeof(phydbl)); t->cpy->id = (char *)mCalloc(T_MAX_ID_COORD,sizeof(char)); return(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_phyrex_mod *PHYREX_Make_Migrep_Model(int dim) { t_phyrex_mod *t; t = (t_phyrex_mod *)mCalloc(1,sizeof(t_phyrex_mod)); t->lim = GEO_Make_Geo_Coord(dim); return(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_dsk *PHYREX_Make_Disk_Event(int n_dim, int n_otu) { t_dsk *t; t = (t_dsk *)mCalloc(1,sizeof(t_dsk)); t->centr = GEO_Make_Geo_Coord(n_dim); t->id = (char *)mCalloc(T_MAX_ID_DISK,sizeof(char)); t->ldsk_a = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *)); return(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_ldsk *PHYREX_Make_Lindisk_Node(int n_dim) { t_ldsk *t; t = (t_ldsk *)mCalloc(1,sizeof(t_ldsk)); t->coord = GEO_Make_Geo_Coord(n_dim); t->cpy_coord = GEO_Make_Geo_Coord(n_dim); return(t); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PHYREX_Make_Lindisk_Next(t_ldsk *t) { if(t->n_next == 0) t->next = (t_ldsk **)mCalloc(NEXT_BLOCK_SIZE,sizeof(t_ldsk *)); else if(!(t->n_next%NEXT_BLOCK_SIZE)) t->next = (t_ldsk **)mRealloc(t->next,t->n_next+NEXT_BLOCK_SIZE,sizeof(t_ldsk *)); t->n_next++; /* printf("\n. make next for ldsk %s n_next set to %d",t->coord->id,t->n_next); */ /* fflush(NULL); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_poly *Make_Poly(int n) { t_poly *p; int i; p = (t_poly *)mCalloc(1,sizeof(t_poly)); p->poly_vert = (t_geo_coord **)mCalloc(n,sizeof(t_geo_coord *)); For(i,n) p->poly_vert[i] = GEO_Make_Geo_Coord(2); return(p); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/make.h000066400000000000000000000047151263450375500145430ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef MAKE_H #define MAKE_H #include "utilities.h" void Make_All_Edges_Lk(t_node *a,t_node *d,t_tree *tree); void Make_New_Edge_Label(t_edge *b); t_edge *Make_Edge_Light(t_node *a,t_node *d,int num); void Make_Edge_Pars(t_edge *b,t_tree *tree); void Make_Edge_Pars_Left(t_edge *b,t_tree *tree); void Make_Edge_Pars_Rght(t_edge *b,t_tree *tree); void Make_Edge_Lk(t_edge *b,t_tree *tree); void Make_Edge_Lk_Left(t_edge *b,t_tree *tree); void Make_Edge_Lk_Rght(t_edge *b,t_tree *tree); void Make_Edge_NNI(t_edge *b); nni *Make_NNI(); t_node *Make_Node_Light(int num); void Make_Node_Lk(t_node *n); nexcom **Make_Nexus_Com(); nexparm *Make_Nexus_Parm(); matrix *Make_Mat(int n_otu); t_tree *Make_Tree_From_Scratch(int n_otu,calign *data); t_tree *Make_Tree(int n_otu); void Make_Tree_Path(t_tree *tree); void Make_All_Tree_Nodes(t_tree *tree); void Make_All_Tree_Edges(t_tree *tree); calign *Make_Cseq(int n_otu,int crunch_len,int state_len,int init_len,char **sp_names); t_treelist *Make_Treelist(int list_size); t_opt *Make_Optimiz(); void Make_Custom_Model(t_mod *mod); t_mod *Make_Model_Basic(); void Make_Model_Complete(t_mod *mod); t_efrq *Make_Efrq(int ns); t_rmat *Make_Rmat(int ns); option *Make_Input(); eigen *Make_Eigen_Struct(int ns); triplet *Make_Triplet_Struct(t_mod *mod); void Make_Short_L(t_tree *tree); void Make_RAS_Complete(t_ras *ras); t_ras *Make_RAS_Basic(); void Make_Best_Spr(t_tree *tree); void Make_Spr_List(t_tree *tree); t_spr *Make_One_Spr(t_tree *tree); void Make_Tree_4_Pars(t_tree *tree, calign *cdata, int n_site); t_string *Make_String(int len); t_mcmc *MCMC_Make_MCMC_Struct(); void Make_Tree_4_Lk(t_tree *tree,calign *cdata,int n_site); t_rate *RATES_Make_Rate_Struct(int n_otu); t_cal *Make_Calib(); void Make_Efrq_Weight(t_tree *mixt_tree); void Make_Rmat_Weight(t_tree *mixt_tree); t_geo *GEO_Make_Geo_Basic(); void GEO_Make_Geo_Complete(int ldscape_sz,int n_dim,int n_tax,t_geo *t); t_geo_coord *GEO_Make_Geo_Coord(int n_dim); t_phyrex_mod *PHYREX_Make_Migrep_Model(); t_dsk *PHYREX_Make_Disk_Event(int n_dim, int n_otu); t_ldsk *PHYREX_Make_Lindisk_Node(int n_dim); void PHYREX_Make_Lindisk_Next(t_ldsk *t); t_poly *Make_Poly(int n); #endif phyml-3.2.0/src/mcmc.c000066400000000000000000007631541263450375500145510ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "mcmc.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC(t_tree *tree) { int move; phydbl u; int first,secod; int i; RATES_Set_Clock_And_Nu_Max(tree); RATES_Set_Birth_Rate_Boundaries(tree); if(tree->mcmc->randomize == YES) { MCMC_Randomize_Birth(tree); MCMC_Randomize_Nu(tree); MCMC_Randomize_Node_Times(tree); MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree); MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree); MCMC_Randomize_Node_Rates(tree); MCMC_Randomize_Clock_Rate(tree); /* Clock Rate must be the last parameter to be randomized */ MCMC_Randomize_Rate_Across_Sites(tree); MCMC_Randomize_Kappa(tree); MCMC_Randomize_Covarion_Rates(tree); MCMC_Randomize_Covarion_Switch(tree); } else { MCMC_Read_Param_Vals(tree); } /* #ifdef INVITEE */ /* tree -> rates -> node_height_dens_log_norm_const_update = Norm_Constant_Prior_Times(tree); */ /* #endif */ Switch_Eigen(YES,tree->mod); MCMC_Initialize_Param_Val(tree->mcmc,tree); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); RATES_Lk_Rates(tree); #ifdef INVITEE tree->rates->update_time_norm_const = YES; #endif TIMES_Lk_Times(tree); #ifdef INVITEE tree->rates->update_time_norm_const = NO; #endif /* printf("\n"); */ /* printf("\n. current calibration: %d ", tree->rates->cur_comb_numb); */ /* printf("\n"); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP0 Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ /* Exit("\n"); */ Set_Both_Sides(NO,tree); if(tree->mcmc->use_data) Lk(NULL,tree); else tree->c_lnL = 0.0; Switch_Eigen(NO,tree->mod); MCMC_Print_Param(tree->mcmc,tree); ////////////////// if(tree->io->mutmap == YES) { int j; char *s,*t; FILE *fp; Make_MutMap(tree); For(j,tree->n_otu) { s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(s,tree->a_nodes[j]->name); tree->a_nodes[j]->name = s; } s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); t = (char *)mCalloc(T_MAX_NAME,sizeof(char)); tree->write_tax_names = YES; For(i,tree->n_pattern) { For(j,tree->n_otu) { strcpy(t,tree->a_nodes[j]->name); s[0]=tree->data->c_seq[j]->state[i]; s[1]='\0'; strcat(s,"--"); sprintf(s+strlen(s),"%.0f",tree->rates->nd_t[j]); /* strcat(s,tree->a_nodes[j]->name); */ strcpy(tree->a_nodes[j]->name,s); } strcpy(s,"rosettatree."); sprintf(s+strlen(s),"%d",i); fp = fopen(s,"w"); s = Write_Tree(tree,NO); PhyML_Fprintf(fp,"%s",s); fclose(fp); For(j,tree->n_otu) strcpy(tree->a_nodes[j]->name,t); } Free(s); Free(t); } first = 2; secod = 1; do { /* if(tree->mcmc->ess[tree->mcmc->num_move_tree_height] > 100 && */ /* tree->mcmc->ess[tree->mcmc->num_move_nu] > 100 && */ /* tree->mcmc->ess[tree->mcmc->num_move_clock_r] > 100 && */ /* tree->mcmc->run > 1000) */ /* { */ /* FILE *fp; */ /* char *s; */ /* s = (char *)mCalloc(100,sizeof(char)); */ /* sprintf(s,"simul_par.%d",getpid()); */ /* fclose(tree->mcmc->out_fp_stats); */ /* tree->mcmc->out_fp_stats = fopen(s,"w"); */ /* tree->mcmc->run = 0; */ /* tree->mcmc->nd_t_digits = 4; */ /* MCMC_Print_Param(tree->mcmc,tree); */ /* RATES_Update_Cur_Bl(tree); */ /* printf("\n. %s",Write_Tree(tree,NO)); */ /* Evolve(tree->data,tree->mod,tree); */ /* sprintf(s,"simul_seq.%d",getpid()); */ /* fp = fopen(s,"w"); */ /* Print_CSeq(fp,NO,tree->data); */ /* fflush(NULL); */ /* fclose(fp); */ /* Free(s); */ /* Exit("\n"); */ /* } */ /* if(tree->mcmc->ess[tree->mcmc->num_move_tree_height] > 100 && */ /* tree->mcmc->ess[tree->mcmc->num_move_nu] > 100 && */ /* tree->mcmc->ess[tree->mcmc->num_move_clock_r] > 100 && */ /* tree->mcmc->run > 1000) */ /* { */ /* FILE *fp; */ /* char *s,*t; */ /* s = (char *)mCalloc(100,sizeof(char)); */ /* t = strrchr(tree->io->in_align_file,'.'); */ /* sprintf(s,"res%s",t); */ /* fp = fopen(s,"w"); */ /* fclose(tree->mcmc->out_fp_stats); */ /* tree->mcmc->out_fp_stats = fopen(s,"w"); */ /* tree->mcmc->run = 0; */ /* MCMC_Print_Param(tree->mcmc,tree); */ /* fclose(fp); */ /* Free(s); */ /* Exit("\n"); */ /* } */ u = Uni(); For(move,tree->mcmc->n_moves) if(tree->mcmc->move_weight[move] > u) break; if(u < .5) { first = 2; secod = 1; } else { first = 1; secod = 2; } /* Clock rate */ if(!strcmp(tree->mcmc->move_name[move],"clock")) { For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; MCMC_Clock_R(tree); } /* Nu */ else if(!strcmp(tree->mcmc->move_name[move],"nu")) { For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; MCMC_Nu(tree); } /* Tree height */ else if(!strcmp(tree->mcmc->move_name[move],"tree_height")) { MCMC_Tree_Height(tree); } /* Subtree height */ else if(!strcmp(tree->mcmc->move_name[move],"subtree_height")) { MCMC_Subtree_Height(tree); } /* Subtree rates */ else if(!strcmp(tree->mcmc->move_name[move],"subtree_rates")) { MCMC_Subtree_Rates(tree); } /* Birth rate */ else if(!strcmp(tree->mcmc->move_name[move],"birth_rate")) { MCMC_Birth_Rate(tree); } /* Swing rates */ else if(!strcmp(tree->mcmc->move_name[move],"tree_rates")) { MCMC_Tree_Rates(tree); } else if(!strcmp(tree->mcmc->move_name[move],"updown_nu_cr")) { MCMC_Updown_Nu_Cr(tree); } else if(!strcmp(tree->mcmc->move_name[move],"updown_t_cr")) { MCMC_Updown_T_Cr(tree); } else if(!strcmp(tree->mcmc->move_name[move],"updown_t_br")) { MCMC_Updown_T_Br(tree); } /* Ts/tv ratio */ else if(!strcmp(tree->mcmc->move_name[move],"kappa")) { MCMC_Kappa(tree); } /* Gamma shape parameter */ else if(!strcmp(tree->mcmc->move_name[move],"ras")) { MCMC_Rate_Across_Sites(tree); } /* Covarion change calibration interval */ else if(!strcmp(tree->mcmc->move_name[move],"jump_calibration")) { MCMC_Jump_Calibration(tree); } /* Covarion model parameters */ else if(!strcmp(tree->mcmc->move_name[move],"cov_rates")) { MCMC_Covarion_Rates(tree); } /* Covarion model parameters */ else if(!strcmp(tree->mcmc->move_name[move],"cov_switch")) { MCMC_Covarion_Switch(tree); } /* Times */ else if(!strcmp(tree->mcmc->move_name[move],"time")) { Set_Both_Sides(YES,tree); if(tree->mcmc->use_data == YES) Lk(NULL,tree); Set_Both_Sides(NO,tree); if(tree->mcmc->is == NO || tree->rates->model_log_rates == YES) { MCMC_Root_Time(tree); MCMC_One_Time(tree->n_root,tree->n_root->v[first],YES,tree); MCMC_One_Time(tree->n_root,tree->n_root->v[secod],YES,tree); } else { /* MCMC_One_Time(tree->n_root,tree->n_root->v[first],YES,tree); */ /* MCMC_One_Time(tree->n_root,tree->n_root->v[secod],YES,tree); */ RATES_Posterior_One_Time(tree->n_root,tree->n_root->v[first],YES,tree); RATES_Posterior_One_Time(tree->n_root,tree->n_root->v[secod],YES,tree); } } /* Node Rates */ else if(!strcmp(tree->mcmc->move_name[move],"nd_rate")) { MCMC_One_Node_Rate(tree->n_root,tree->n_root->v[first],YES,tree); MCMC_One_Node_Rate(tree->n_root,tree->n_root->v[secod],YES,tree); } /* Edge Rates */ else if(!strcmp(tree->mcmc->move_name[move],"br_rate")) { Set_Both_Sides(YES,tree); if(tree->mcmc->use_data == YES) Lk(NULL,tree); Set_Both_Sides(NO,tree); if(tree->mcmc->is == NO) { /* MCMC_Slice_One_Rate(tree->n_root,tree->n_root->v[first],YES,tree); */ /* MCMC_Slice_One_Rate(tree->n_root,tree->n_root->v[secod],YES,tree); */ MCMC_One_Rate(tree->n_root,tree->n_root->v[first],YES,tree); MCMC_One_Rate(tree->n_root,tree->n_root->v[secod],YES,tree); } else { RATES_Posterior_One_Rate(tree->n_root,tree->n_root->v[first],YES,tree); RATES_Posterior_One_Rate(tree->n_root,tree->n_root->v[secod],YES,tree); } /* MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree); */ /* MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree); */ /* if(tree->mcmc->use_data == YES) Lk(NULL,tree); */ /* RATES_Lk_Rates(tree); */ } /* printf("\n. move: '%s' lnL: %f",tree->mcmc->move_name[move],tree->rates->c_lnL_times); */ /* int i; */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nLOOP Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ tree->mcmc->run++; MCMC_Get_Acc_Rates(tree->mcmc); MCMC_Print_Param(tree->mcmc,tree); MCMC_Print_Param_Stdin(tree->mcmc,tree); if(tree->io->mutmap == YES) { if(!(tree->mcmc->run%tree->mcmc->sample_interval)) { Sample_Ancestral_Seq(YES,!tree->mcmc->use_data,tree); phydbl sum = 0.0; int edge,site,mut; char *s; FILE *fp; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(s,tree->mcmc->io->in_align_file); strcat(s,"_"); strcat(s,tree->mcmc->out_filename); strcat(s,".mutmap"); fp = fopen(s,"w"); Free(s); For(i,(2*tree->n_otu-3)*(tree->n_pattern)*6) sum += tree->mutmap[i]; PhyML_Fprintf(fp,"edge\t site\t mut\t count"); For(i,(2*tree->n_otu-3)*(tree->n_pattern)*6) { Get_Mutmap_Coord(i,&edge,&site,&mut,tree); PhyML_Fprintf(fp,"\n%4d\t %4d\t %4d\t %10f",edge,site,mut,(phydbl)tree->mutmap[i]/sum); } fclose(fp); } } (void)signal(SIGINT,MCMC_Terminate); } while(tree->mcmc->run < tree->mcmc->chain_len); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Single_Param_Generic(phydbl *val, phydbl lim_inf, phydbl lim_sup, int move_num, phydbl *lnPrior, phydbl *lnLike, phydbl (*prior_func)(t_edge *,t_tree *,supert_tree *), phydbl (*like_func)(t_edge *,t_tree *,supert_tree *), int move_type, int _log, /* _log == YES: the model describes the distribution of log(val) but the move applies to val. Need a correction factor */ t_edge *branch, t_tree *tree, supert_tree *stree) { phydbl cur_val,new_val,new_lnLike,new_lnPrior,cur_lnLike,cur_lnPrior; phydbl u,alpha,ratio; phydbl K; phydbl new_lnval, cur_lnval; Record_Br_Len(tree); cur_val = *val; new_val = -1.0; ratio = 0.0; K = tree->mcmc->tune_move[move_num]; cur_lnval = LOG(*val); new_lnval = cur_lnval; if(lnLike) { cur_lnLike = *lnLike; new_lnLike = *lnLike; } else { cur_lnLike = 0.0; new_lnLike = 0.0; } if(lnPrior) { cur_lnPrior = *lnPrior; new_lnPrior = *lnPrior; } else { cur_lnPrior = 0.0; new_lnPrior = 0.0; } MCMC_Make_Move(&cur_val,&new_val,lim_inf,lim_sup,&ratio,K,move_type); if(new_val < lim_sup && new_val > lim_inf) { *val = new_val; if(tree->rates) RATES_Update_Cur_Bl(tree); if(_log == YES) ratio += (cur_lnval - new_lnval); if(prior_func) /* Prior ratio */ { new_lnPrior = (*prior_func)(branch,tree,stree); ratio += (new_lnPrior - cur_lnPrior); } /* if(like_func && tree->mcmc->use_data == YES) /\* Likelihood ratio *\/ */ if(like_func) /* Likelihood ratio */ { new_lnLike = (*like_func)(branch,tree,stree); ratio += (new_lnLike - cur_lnLike); } /* printf("\n. %s cur_val: %f new_val:%f cur_lnL: %f new_lnL: %f cur_lnPrior: %f new_lnPrior: %f ratio: %f", */ /* tree->mcmc->move_name[move_num], */ /* cur_val, */ /* new_val, */ /* cur_lnLike, */ /* new_lnLike, */ /* cur_lnPrior, */ /* new_lnPrior, */ /* ratio); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_lnLike > UNLIKELY) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { *val = cur_val; new_val = cur_val; if(lnPrior) *lnPrior = cur_lnPrior; if(lnLike) *lnLike = cur_lnLike; Restore_Br_Len(tree); if(tree->mod && tree->mod->update_eigen) Update_Eigen(tree->mod); } else /* Accept */ { tree->mcmc->acc_move[move_num]++; if(lnPrior) *lnPrior = new_lnPrior; if(lnLike) *lnLike = new_lnLike; } } tree->mcmc->run_move[move_num]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Formula from ``Markov chain Monte Carlo in practice: a roundtable discussion'', Kass, Robert E and Carlin, Bradley P and Gelman, Andrew and Neal, Radford M The American Statistician, 1998 */ void MCMC_Update_Effective_Sample_Size(int move_num, t_mcmc *mcmc, t_tree *tree) { int i,N,lag; phydbl rho,mean,var,old_rho,act,ess; int burnin; N = mcmc->sample_num+1; burnin = (int)(0.1*N); if(burnin < 1) return; N -= burnin; mean = Weighted_Mean(mcmc->sampled_val+move_num*mcmc->sample_size+burnin,NULL,N); var = Variance(mcmc->sampled_val+move_num*mcmc->sample_size+burnin,N); /* if(move_num == tree->mcmc->num_move_phyrex_sigsq) */ /* printf("\n. %d %f %f\n",N,mean,var); */ act = -1.0; old_rho = 1.0; For(lag,MIN(N,mcmc->max_lag)) { rho = 0.0; For(i,N-lag) rho += (mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i] - mean) * (mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i+lag] - mean) ; rho /= (N - lag)*var; if(old_rho + rho < 0.0) { break; /* Geyer (1992) stopping criterion */ } old_rho = rho; act += 2.*rho; } if(act > 0.0) ess = N/act; else ess = 0.0; mcmc->ess[move_num] = ess; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Update_Mode(int move_num, t_mcmc *mcmc, t_tree *tree) { int i,j,N,best_bin; int burnin,breaks,*bin_score,best_score; phydbl min,max; breaks = 100; bin_score = (int *)mCalloc(breaks,sizeof(int)); N = mcmc->sample_num+1; burnin = (int)(0.1*N); if(burnin < 1) return; N -= burnin; min = +INFINITY; For(i,N) if(mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i] < min) min = mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i]; max = -INFINITY; For(i,N) if(mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i] > max) max = mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i]; For(i,N) { for(j=1;j mcmc->sampled_val[move_num*mcmc->sample_size+burnin+i]) { bin_score[j-1]++; break; } } best_score = 0; best_bin = 0; For(j,breaks) if(bin_score[j] > best_score) { best_score = bin_score[j]; best_bin = j; } mcmc->mode[move_num] = min + best_bin*(max-min)/breaks; Free(bin_score); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Clock_R(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { MCMC_Single_Param_Generic(&(tree->rates->clock_r), mixt_tree->rates->min_clock, mixt_tree->rates->max_clock, mixt_tree->mcmc->num_move_clock_r, NULL,&(mixt_tree->c_lnL), NULL,Wrap_Lk, mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_clock_r], NO,NULL,mixt_tree,NULL); tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef GEO // Sample dispersal parameter from a phylogeo model void MCMC_GEO_Sigma(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { MCMC_Single_Param_Generic(&(tree->geo->sigma), mixt_tree->geo->min_sigma, mixt_tree->geo->max_sigma, mixt_tree->mcmc->num_move_geo_sigma, NULL,&(mixt_tree->geo->c_lnL), NULL,GEO_Wrap_Lk, mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_geo_sigma], NO,NULL,mixt_tree,NULL); GEO_Update_Fmat(tree->geo); tree = tree->next; } while(tree); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef GEO // Sample competition parameter from a phylogeo model void MCMC_GEO_Lbda(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { MCMC_Single_Param_Generic(&(tree->geo->lbda), mixt_tree->geo->min_lbda, mixt_tree->geo->max_lbda, mixt_tree->mcmc->num_move_geo_lambda, NULL,&(mixt_tree->geo->c_lnL), NULL,GEO_Wrap_Lk, mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_geo_lambda], NO,NULL,mixt_tree,NULL); tree = tree->next; } while(tree); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef GEO // Sample global migration rate parameter from a phylogeo model void MCMC_GEO_Tau(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { MCMC_Single_Param_Generic(&(tree->geo->tau), mixt_tree->geo->min_tau, mixt_tree->geo->max_tau, mixt_tree->mcmc->num_move_geo_tau, NULL,&(mixt_tree->geo->c_lnL), NULL,GEO_Wrap_Lk, mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_geo_tau], NO,NULL,mixt_tree,NULL); tree = tree->next; } while(tree); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef GEO void MCMC_GEO_Dum(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { MCMC_Single_Param_Generic(&(tree->geo->dum), mixt_tree->geo->min_dum, mixt_tree->geo->max_dum, mixt_tree->mcmc->num_move_geo_dum, NULL,&(mixt_tree->geo->c_lnL), NULL,GEO_Wrap_Lk, mixt_tree->mcmc->move_type[mixt_tree->mcmc->num_move_geo_dum], NO,NULL,mixt_tree,NULL); tree = tree->next; } while(tree); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef GEO void MCMC_GEO_Loc(t_tree *tree) { int target; int *rec_loc; // recorded locations int i; phydbl cur_lnL, new_lnL; phydbl u, ratio, alpha; phydbl sum; phydbl *probs; cur_lnL = tree->geo->c_lnL; rec_loc = (int *)mCalloc(2*tree->n_otu-1,sizeof(int)); For(i,2*tree->n_otu-1) rec_loc[i] = tree->geo->idx_loc[i]; // Choose an internal node (including the root) at random target = Rand_Int(tree->n_otu,2*tree->n_otu-2); target = 2*tree->n_otu-2; // Root node is special. Select new location uniformly at random if(tree->a_nodes[target] == tree->n_root) { probs = (phydbl *)mCalloc(tree->geo->ldscape_sz,sizeof(phydbl)); sum = 0.0; For(i,tree->geo->ldscape_sz) sum += tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]; For(i,tree->geo->ldscape_sz) probs[i] = tree->geo->idx_loc_beneath[tree->n_root->num * tree->geo->ldscape_sz + i]/sum; tree->geo->idx_loc[tree->n_root->num] = Sample_i_With_Proba_pi(probs,tree->geo->ldscape_sz); Free(probs); } // Randomize the locations below the selected node GEO_Randomize_Locations(tree->a_nodes[target], tree->geo, tree); new_lnL = GEO_Lk(tree->geo,tree); ratio = (new_lnL - cur_lnL); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { For(i,2*tree->n_otu-1) tree->geo->idx_loc[i] = rec_loc[i]; tree->geo->c_lnL = GEO_Lk(tree->geo,tree); // TO DO: you only need to update the occupation vector here... } Free(rec_loc); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Sample_Joint_Rates_Prior(t_tree *tree) { int i,dim; phydbl T; phydbl *r,*t,*lambda; phydbl *min_r,*max_r; phydbl k; dim = 2*tree->n_otu-2; lambda = tree->rates->_2n_vect1; min_r = tree->rates->_2n_vect2; max_r = tree->rates->_2n_vect3; r = tree->rates->br_r; t = tree->rates->nd_t; For(i,dim) tree->rates->mean_r[i] = 1.0; RATES_Fill_Lca_Table(tree); RATES_Covariance_Mu(tree); T = .0; For(i,dim) T += (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num]); For(i,dim) lambda[i] = (t[tree->a_nodes[i]->num] - t[tree->a_nodes[i]->anc->num])/T; For(i,dim) r[i] = 1.0; For(i,dim) min_r[i] = tree->rates->min_rate; For(i,dim) max_r[i] = tree->rates->max_rate; k = 1.; /* We want \sum_i lambda[i] r[i] = 1 */ Rnorm_Multid_Trunc_Constraint(tree->rates->mean_r, tree->rates->cov_r, min_r,max_r, lambda, k, r, dim); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree) { t_edge *b; int i; phydbl u; phydbl new_lnL_data, cur_lnL_data, new_lnL_rate, cur_lnL_rate; phydbl ratio, alpha; phydbl new_mu, cur_mu; phydbl r_min, r_max; t_edge *b1,*b2,*b3; t_node *v2,*v3; int move_num; phydbl K; if(tree->rates->model == STRICTCLOCK) return; b = NULL; if(a == tree->n_root) b = tree->e_root; else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; } cur_mu = tree->rates->br_r[d->num]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; r_min = tree->rates->min_rate; r_max = tree->rates->max_rate; ratio = 0.0; move_num = d->num+tree->mcmc->num_move_br_r; K = tree->mcmc->tune_move[move_num]; Record_Br_Len(tree); u = Uni(); MCMC_Make_Move(&cur_mu,&new_mu,r_min,r_max,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_br_r+d->num]); /* phydbl dt,sd,mean; */ /* int err; */ /* dt = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]; */ /* sd = SQRT(tree->rates->nu * dt); */ /* mean = tree->rates->br_r[a->num]; */ /* new_mu = Rnorm_Trunc(mean,sd,r_min,r_max,&err); */ /* ratio = Log_Dnorm_Trunc(cur_mu,mean,sd,r_min,r_max,&err) - Log_Dnorm_Trunc(new_mu,mean,sd,r_min,r_max,&err); */ if(new_mu > r_min && new_mu < r_max) { tree->rates->br_r[d->num] = new_mu; v2 = v3 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v2) { v2 = d->v[i]; } else { v3 = d->v[i]; } } b1 = NULL; if(a == tree->n_root) b1 = tree->e_root; else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; } b2 = b3 = NULL; if(!d->tax) { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!b2) { b2 = d->b[i]; } else { b3 = d->b[i]; } } } tree->rates->br_do_updt[d->num] = YES; if(!d->tax) { tree->rates->br_do_updt[v2->num] = YES; tree->rates->br_do_updt[v3->num] = YES; } RATES_Update_Cur_Bl(tree); /* printf("\n. r0=%f r1=%f cr=%f mean=%f var=%f nu=%f dt=%f", */ /* r0,r1,tree->rates->clock_r,b1->gamma_prior_mean,b1->gamma_prior_var,nu,t1-t0); */ if(tree->mcmc->use_data) { if(tree->io->lk_approx == EXACT) { Update_PMat_At_Given_Edge(b1,tree); if(!d->tax) { Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); } Update_P_Lk(tree,b1,d); } new_lnL_data = Lk(b1,tree); /* tree->both_sides = NO; */ /* new_lnL_data = Lk(tree); */ } new_lnL_rate = RATES_Lk_Rates(tree); /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->rates->br_r[d->num] = cur_mu; tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; Restore_Br_Len(tree); if(tree->mcmc->use_data && tree->io->lk_approx == EXACT) { Update_PMat_At_Given_Edge(b1,tree); if(!d->tax) { Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); } Update_P_Lk(tree,b1,d); } /* tree->both_sides = YES; */ /* new_lnL_data = Lk(tree); */ /* tree->both_sides = NO; */ } else { tree->mcmc->acc_move[tree->mcmc->num_move_br_r+d->num]++; } } tree->mcmc->run_move[tree->mcmc->num_move_br_r+d->num]++; if(traversal == YES) { if(d->tax == YES) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */ MCMC_One_Rate(d,d->v[i],YES,tree); } } if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_One_Node_Rate(t_node *a, t_node *d, int traversal, t_tree *tree) { t_edge *b; int i; b = NULL; if(a == tree->n_root) b = tree->e_root; else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; } /* Only the LOG_RANDWALK move seems to work here. Change with caution then. */ tree->rates->br_do_updt[d->num] = YES; MCMC_Single_Param_Generic(&(tree->rates->nd_r[d->num]), tree->rates->min_rate, tree->rates->max_rate, tree->mcmc->num_move_nd_r+d->num, &(tree->rates->c_lnL_rates),NULL, Wrap_Lk_Rates,NULL, tree->mcmc->move_type[tree->mcmc->num_move_nd_r+d->num], NO,NULL,tree,NULL); Update_PMat_At_Given_Edge(b,tree); if(traversal == YES) { if(d->tax == YES) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { MCMC_One_Node_Rate(d,d->v[i],YES,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree) { phydbl u; phydbl t_min,t_max; phydbl t1_cur, t1_new; phydbl cur_lnL_data, new_lnL_data; phydbl cur_lnL_rate, new_lnL_rate; phydbl cur_lnL_time, new_lnL_time; phydbl ratio,alpha; t_edge *b1,*b2,*b3; int i; phydbl t0,t2,t3; t_node *v2,*v3; phydbl K; int move_num; if(d->tax) return; /* Won't change time at tip */ /* if(FABS(tree->rates->t_prior_min[d->num] - tree->rates->t_prior_max[d->num]) < 1.E-10) return; */ Record_Br_Len(tree); RATES_Record_Rates(tree); RATES_Record_Times(tree); move_num = d->num-tree->n_otu+tree->mcmc->num_move_nd_t; K = tree->mcmc->tune_move[move_num]; cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; t1_cur = tree->rates->nd_t[d->num]; new_lnL_data = cur_lnL_data; new_lnL_rate = cur_lnL_rate; ratio = 0.0; cur_lnL_time = tree->rates->c_lnL_times; new_lnL_time = cur_lnL_time; v2 = v3 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v2) { v2 = d->v[i]; } else { v3 = d->v[i]; } } b1 = NULL; if(a == tree->n_root) b1 = tree->e_root; else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; } b2 = b3 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!b2) { b2 = d->b[i]; } else { b3 = d->b[i]; } } t0 = tree->rates->nd_t[a->num]; t2 = tree->rates->nd_t[v2->num]; t3 = tree->rates->nd_t[v3->num]; /* t_min = MAX(t0,tree->rates->t_prior_min[d->num]); */ /* t_max = MIN(MIN(t2,t3),tree->rates->t_prior_max[d->num]);*/ t_min = t0; t_max = MIN(t2,t3); t_min += tree->rates->min_dt; t_max -= tree->rates->min_dt; if(t_min > t_max) { PhyML_Printf("\n== t_min = %f t_max = %f",t_min,t_max); PhyML_Printf("\n== prior_min = %f prior_max = %f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]); if(t1_new > t_min && t1_new < t_max) { tree->rates->nd_t[d->num] = t1_new; new_lnL_time = TIMES_Lk_Times(tree); ratio += (new_lnL_time - cur_lnL_time); if(isinf(new_lnL_time) == NO) // Proposed value of t is inside its boundary { /* Update branch lengths */ tree->rates->br_do_updt[d->num] = YES; tree->rates->br_do_updt[v2->num] = YES; tree->rates->br_do_updt[v3->num] = YES; RATES_Update_Cur_Bl(tree); new_lnL_rate = RATES_Lk_Rates(tree); ratio += (new_lnL_rate - cur_lnL_rate); if(tree->mcmc->use_data) { if(tree->io->lk_approx == EXACT) { Update_PMat_At_Given_Edge(b1,tree); Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); Update_P_Lk(tree,b1,d); } new_lnL_data = Lk(b1,tree); /* /\* !!!!!!!!!!!!!!!!!!!!1 *\/ */ /* if(FABS(Lk(tree) - new_lnL_data) > 1.E-5) */ /* { */ /* PhyML_Printf("\n. b1->l->v=%f b2->l->v=%f b3->l->v=%f",b1->l->v,b2->l->v,b3->l->v); */ /* PhyML_Printf("\n. a->num=%d d->num=%d root=%d (%d %d)",a->num,d->num,a==tree->n_root,tree->n_root->v[2]->num,tree->n_root->v[1]->num); */ /* PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); */ /* PhyML_Printf("\n. t1_new=%f t1_cur=%f",t1_new,t1_cur); */ /* PhyML_Printf("\n. %f %f",cur_lnL_data,tree->c_lnL); */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ } if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); } /* if(d->num == 7) */ /* { */ /* printf("\n. nd_t: %f %f new_lnL_rate: %f cur_lnL_rate: %f new_lnL_time: %f cur_lnL_time: %f ratio: %f", */ /* t1_cur, */ /* tree->rates->nd_t[d->num], */ /* new_lnL_rate, */ /* cur_lnL_rate, */ /* new_lnL_time, */ /* cur_lnL_time, */ /* ratio); */ /* } */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { //if(d -> num == 7) PhyML_Printf("\n. t_cur = %f t_rej = %f", t1_cur, t1_new); tree->rates->nd_t[d->num] = t1_cur; tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; if(isinf(new_lnL_time) == NO) { Restore_Br_Len(tree); RATES_Reset_Rates(tree); RATES_Reset_Times(tree); if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { Update_PMat_At_Given_Edge(b1,tree); Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); Update_P_Lk(tree,b1,d); } } } else { /* printf("\n. A new_lnL_data = %f cur_lnL_data = %f t_new=%f t_cur=%f tmin=%f tmax=%f", */ /* new_lnL_data,cur_lnL_data,t1_new,t1_cur,t_min,t_max); */ tree->mcmc->acc_move[move_num]++; } if(t1_new < t0) { t1_new = t0+1.E-4; PhyML_Printf("\n"); PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO")); PhyML_Printf("\n== t0 = %f t1_new = %f",t0,t1_new); PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(t1_new > MIN(t2,t3)) { PhyML_Printf("\n"); PhyML_Printf("\n== a is root -> %s",(a == tree->n_root)?("YES"):("NO")); PhyML_Printf("\n== t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1_cur,t2,t3,MIN(t2,t3)); PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(isnan(t1_new)) { PhyML_Printf("\n== run=%d",tree->mcmc->run); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } } tree->mcmc->run_move[move_num]++; if(traversal == YES) { if(d->tax == YES) return; else For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */ MCMC_One_Time(d,d->v[i],YES,tree); } if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b1,d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) {tree->both_sides = YES; Lk(tree); } */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Jump_Calibration(t_tree *tree) { #ifdef INVITEE phydbl u; phydbl *calib_prior_cumprob, *calib_prior_prob, *uniform_prob; phydbl cur_lnL_data, new_lnL_data; phydbl cur_lnL_rate, new_lnL_rate; phydbl cur_lnL_time, new_lnL_time; phydbl cur_lnL_K; phydbl times_log_hastings_ratio; int new_calib_comb_num, cur_calib_comb_num; phydbl ratio, alpha; int i, result; int move_num; int tot_num_of_calib_comb; int *buff_calib_num; int n_pos_probs; tot_num_of_calib_comb = Number_Of_Comb(tree -> rates -> calib); tree->rates->update_time_norm_const = YES; if(tot_num_of_calib_comb > 1) { calib_prior_prob = tree -> rates -> times_partial_proba; calib_prior_cumprob = (phydbl *)mCalloc(tot_num_of_calib_comb + 1, sizeof(phydbl)); uniform_prob = (phydbl *)mCalloc(tot_num_of_calib_comb + 1, sizeof(phydbl)); /////////////////////////////////////////////////////////////////////////////////////////// /* for(i = tree -> n_otu; i < 2 * tree -> n_otu - 1; i++) printf("\n. '%f' '%f' \n", tree -> rates -> t_prior_min[i], tree -> rates -> t_prior_max[i]); */ //for(i = tree -> n_otu; i < 2 * tree -> n_otu - 1; i++) printf("\n. '%f' \n", tree -> rates -> nd_t[i]); /////////////////////////////////////////////////////////////////////////////////////////// Record_Br_Len(tree); RATES_Record_Rates(tree); RATES_Record_Times(tree); TIMES_Record_Prior_Times(tree); move_num = tree -> mcmc -> num_move_jump_calibration; cur_lnL_data = tree -> c_lnL; cur_lnL_rate = tree -> rates -> c_lnL_rates; new_lnL_data = cur_lnL_data; new_lnL_rate = cur_lnL_rate; ratio = 0.0; cur_lnL_time = tree -> rates -> c_lnL_times; new_lnL_time = cur_lnL_time; cur_calib_comb_num = tree -> rates -> cur_comb_numb; new_calib_comb_num = cur_calib_comb_num; cur_lnL_K = tree->rates->log_K_cur; /* new_calib_comb_num = Sample_i_With_Proba_pi(calib_prior_prob,tot_num_of_calib_comb); */ u = Uni(); if(u < 0.5) { For(i,tot_num_of_calib_comb) uniform_prob[i] = calib_prior_prob[i] > .0 ? 1. : 0.; new_calib_comb_num = Sample_i_With_Proba_pi(uniform_prob,tot_num_of_calib_comb); } else { buff_calib_num = (int *)mCalloc(tot_num_of_calib_comb,sizeof(int)); n_pos_probs = 0; For(i,tot_num_of_calib_comb) if(calib_prior_prob[i] > 1.E-10) { buff_calib_num[n_pos_probs] = i; n_pos_probs++; } int curr_pos=0; while(buff_calib_num[curr_pos] != cur_calib_comb_num) { curr_pos++; } u = Uni(); if(u < 0.5) new_calib_comb_num = buff_calib_num[Modulo(curr_pos-1,n_pos_probs)]; else new_calib_comb_num = buff_calib_num[Modulo(curr_pos+1,n_pos_probs)]; Free(buff_calib_num); } /* printf("\n"); */ /* printf("\n. current calibration: %d ", cur_calib_comb_num); */ /* printf("\n"); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP0 Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\n. Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f]. \n", i, tree -> rates -> t_prior_min[i], tree -> rates -> t_prior_max[i], tree -> rates -> nd_t[i]); */ /* Exit("\n"); */ if(!Are_Equal(cur_calib_comb_num, new_calib_comb_num, 1.E-10)) { /* printf("\n"); */ /* printf("\n. current calibration: %d == new_calibration: %d", cur_calib_comb_num, new_calib_comb_num); */ /* printf("\n"); */ /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */ /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nAV Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ Set_Current_Calibration(new_calib_comb_num, tree); TIMES_Set_All_Node_Priors(tree); result = TRUE; /* Check_Node_Time(tree -> n_root, tree -> n_root -> v[1], &result, tree); */ /* Check_Node_Time(tree -> n_root, tree -> n_root -> v[2], &result, tree); */ /* printf("\n. New calibration %d", new_calib_comb_num); */ /* printf("\n"); */ /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */ /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nAP Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ times_log_hastings_ratio = 0.0; Jump_Calibration_Move_Pre(tree->n_root,tree->n_root->v[1],tree->rates->nd_t[tree->n_root->num],×_log_hastings_ratio,tree); Jump_Calibration_Move_Pre(tree->n_root,tree->n_root->v[2],tree->rates->nd_t[tree->n_root->num],×_log_hastings_ratio,tree); /* Update_Current_Times_Down_Tree(tree -> n_root, tree -> n_root -> v[1], tree); */ /* Update_Current_Times_Down_Tree(tree -> n_root, tree -> n_root -> v[2], tree); */ /* new_lnL_proposal_density = 0.0; */ /* Multiple_Time_Proposal_Density(tree -> n_root, tree -> n_root -> v[1], &new_lnL_proposal_density, tree); */ /* Multiple_Time_Proposal_Density(tree -> n_root, tree -> n_root -> v[2], &new_lnL_proposal_density, tree); */ result = TRUE; Check_Node_Time(tree -> n_root, tree -> n_root -> v[1], &result, tree); Check_Node_Time(tree -> n_root, tree -> n_root -> v[2], &result, tree); if(result != TRUE) { PhyML_Printf("\n. ...................... OLD CALIBRATION.....................................\n"); for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\n. Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f]. \n", i, tree -> rates -> t_prior_min_ori[i], tree -> rates -> t_prior_max_ori[i], tree -> rates -> buff_t[i]); PhyML_Printf("\n. ...........................................................................\n"); PhyML_Printf("\n. ................. NEW PROPOSED CALIBRATION ................................\n"); for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\n. Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f]. \n", i, tree -> rates -> t_prior_min[i], tree -> rates -> t_prior_max[i], tree -> rates -> nd_t[i]); PhyML_Printf("\n. ...........................................................................\n"); PhyML_Printf("\n== There is a problem with calibration information.\n"); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); /* printf("\n. JUMP cur_lnL_time: %f new_lnL_time: %f",cur_lnL_time,new_lnL_time); */ /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP1 Node number:[%d] Lower bound:[%f] Upper bound:[%f] Node time:[%f].", i, */ /* tree -> rates -> t_prior_min[i], */ /* tree -> rates -> t_prior_max[i], */ /* tree -> rates -> nd_t[i]); */ /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); ratio += (LOG(calib_prior_prob[new_calib_comb_num]) - LOG(calib_prior_prob[cur_calib_comb_num])); ratio += times_log_hastings_ratio; ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { RATES_Reset_Times(tree); Restore_Br_Len(tree); TIMES_Reset_Prior_Times(tree); tree -> c_lnL = cur_lnL_data; tree -> rates -> c_lnL_rates = cur_lnL_rate; tree -> rates -> c_lnL_times = cur_lnL_time; tree -> rates -> log_K_cur = cur_lnL_K; tree -> rates -> cur_comb_numb = cur_calib_comb_num; /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP3 Node number:[%d] Lower bound:[%f,%f] Upper bound:[%f,%f] Node time:[%f].", i, */ /* tree->rates->t_prior_min[i],tree->rates->t_prior_min_ori[i], */ /* tree->rates->t_prior_max[i],tree->rates->t_prior_max_ori[i], */ /* tree->rates->nd_t[i]); */ Set_Current_Calibration(tree -> rates -> cur_comb_numb, tree); /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP4 Node number:[%d] Lower bound:[%f,%f] Upper bound:[%f,%f] Node time:[%f].", i, */ /* tree->rates->t_prior_min[i],tree->rates->t_prior_min_ori[i], */ /* tree->rates->t_prior_max[i],tree->rates->t_prior_max_ori[i], */ /* tree->rates->nd_t[i]); */ TIMES_Set_All_Node_Priors(tree); /* printf("\n. ......................REJECTED.....................................\n"); */ tree -> rates -> numb_calib_chosen[cur_calib_comb_num]++; } else { tree -> rates -> cur_comb_numb = new_calib_comb_num; tree->mcmc->acc_move[move_num]++; /* printf("\n. ......................ACCEPTED.....................................\n"); */ tree -> rates -> numb_calib_chosen[new_calib_comb_num]++; } /* for(i = tree -> n_otu; i < 2 * tree -> n_otu -1; i++) printf("\nJUMP2 Node number:[%d] Lower bound:[%f,%f] Upper bound:[%f,%f] Node time:[%f].", i, */ /* tree->rates->t_prior_min[i],tree->rates->t_prior_min_ori[i], */ /* tree->rates->t_prior_max[i],tree->rates->t_prior_max_ori[i], */ /* tree->rates->nd_t[i]); */ Check_Node_Time(tree -> n_root, tree -> n_root -> v[1], &result, tree); Check_Node_Time(tree -> n_root, tree -> n_root -> v[2], &result, tree); if(result != TRUE) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); tree->mcmc->run_move[move_num]++; Free(calib_prior_cumprob); Free(uniform_prob); } } tree->rates->update_time_norm_const = NO; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Root_Time(t_tree *tree) { phydbl u; phydbl t_min,t_max; phydbl t1_cur, t1_new; phydbl cur_lnL_data, new_lnL_data; phydbl cur_lnL_rate, new_lnL_rate; phydbl cur_lnL_time, new_lnL_time; phydbl ratio,alpha; t_edge *b1; phydbl t0,t2,t3; t_node *v2,*v3; phydbl K; int move_num; t_node *root; root = tree->n_root; if(FABS(tree->rates->t_prior_min[root->num] - tree->rates->t_prior_max[root->num]) < 1.E-10) return; Record_Br_Len(tree); RATES_Record_Rates(tree); RATES_Record_Times(tree); move_num = root->num-tree->n_otu+tree->mcmc->num_move_nd_t; K = tree->mcmc->tune_move[move_num]; cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; t1_cur = tree->rates->nd_t[root->num]; new_lnL_data = cur_lnL_data; new_lnL_rate = cur_lnL_rate; ratio = 0.0; cur_lnL_time = tree->rates->c_lnL_times; new_lnL_time = cur_lnL_time; v2 = root->v[2]; v3 = root->v[1]; b1 = tree->e_root; t0 = tree->rates->t_prior_min[root->num]; t2 = tree->rates->nd_t[v2->num]; t3 = tree->rates->nd_t[v3->num]; /* printf("\n %d t0= %f %d t2= %f %d t3= %f \n", root -> num, t0, v2 -> num, t2, v3 -> num, t3); */ t_min = t0; /* t_max = MIN(MIN(t2,t3),tree->rates->t_prior_max[root->num]); */ t_max = MIN(t2,t3); t_min += tree->rates->min_dt; t_max -= tree->rates->min_dt; if(t_min > t_max) { PhyML_Printf("\n== t0 = %f t2 = %f t3 = %f",t0,t2,t3); PhyML_Printf("\n== t_min = %f t_max = %f",t_min,t_max); PhyML_Printf("\n== prior_min = %f prior_max = %f",tree->rates->t_prior_min[root->num],tree->rates->t_prior_max[root->num]); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } MCMC_Make_Move(&t1_cur,&t1_new,t_min,t_max,&ratio,K,tree->mcmc->move_type[move_num]); if(t1_new > t_min && t1_new < t_max) { tree->rates->nd_t[root->num] = t1_new; /* Update branch lengths */ RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(b1,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->rates->nd_t[root->num] = t1_cur; tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; Restore_Br_Len(tree); RATES_Reset_Rates(tree); RATES_Reset_Times(tree); } else { tree->mcmc->acc_move[move_num]++; } if(t1_new < t0) { t1_new = t0+1.E-4; PhyML_Printf("\n"); PhyML_Printf("\n== t0 = %f t1_new = %f",t0,t1_new); PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(t1_new > MIN(t2,t3)) { PhyML_Printf("\n"); PhyML_Printf("\n== t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1_cur,t2,t3,MIN(t2,t3)); PhyML_Printf("\n== t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n== (t1-t0)=%f (t2-t1)=%f",t1_cur-t0,t2-t1_cur); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(isnan(t1_new)) { PhyML_Printf("\n== run=%d",tree->mcmc->run); PhyML_Printf("\n== Err/ in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } } tree->mcmc->run_move[move_num]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Tree_Height(t_tree *tree) { int i; phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_data,new_lnL_data; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_time,new_lnL_time; phydbl floor; int n_nodes; if(FABS(tree->rates->t_prior_max[tree->n_root->num] - tree->rates->t_prior_min[tree->n_root->num]) < 1.E-10) return; RATES_Record_Times(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_tree_height]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; ratio = 0.0; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; cur_lnL_time = tree->rates->c_lnL_times; u = Uni(); mult = EXP(K*(u-0.5)); /* WARNING: It must not be floor = tree->rates->t_prior_max[tree->n_root->num]; floor is the maximum value a node height can take when one ignores the calibration nodes, i.e., floor is set by the height of the tips */ /* floor = 0.0; */ floor = tree->rates->t_floor[tree->n_root->num]; /* floor = tree->rates->t_prior_max[tree->n_root->num]; */ Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree); /* For(i,2*tree->n_otu-1) */ /* { */ /* if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || */ /* tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) */ /* { */ /* RATES_Reset_Times(tree); */ /* Restore_Br_Len(tree); */ /* tree->mcmc->run_move[tree->mcmc->num_move_tree_height]++; */ /* return; */ /* } */ /* } */ For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); /* The Hastings ratio is actually mult^(n) when changing the absolute node heights. When considering the relative heights, this ratio combined to the Jacobian for the change of variable ends up to being equal to mult. */ /* ratio += LOG(mult); */ ratio += (phydbl)(n_nodes)*LOG(mult); /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); /* phydbl diff = (new_lnL_time - cur_lnL_time)+(phydbl)(n_nodes-1.)*LOG(mult); */ /* printf("\n. diff_lk = %12f -(n-1)*log(mult) = %12f n_nodes=%d [%12f] log(mult)=%f", */ /* (new_lnL_time - cur_lnL_time), */ /* -(phydbl)(n_nodes-1.)*LOG(mult), */ /* n_nodes, */ /* diff, */ /* LOG(mult)); */ /* !!!!!!!!!!!! */ /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); /* printf("\n. cur_lnL_time: %f new_lnL_time: %f",cur_lnL_time,new_lnL_time); */ if(u > alpha) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; } else { tree->mcmc->acc_move[tree->mcmc->num_move_tree_height]++; tree->mcmc->acc_move[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]++; /* printf("\n. ACCEPT\n"); */ } tree->mcmc->run_move[tree->mcmc->num_move_tree_height]++; tree->mcmc->run_move[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Updown_T_Cr(t_tree *tree) { /*! TO DO: make sure to change the values of clock_r across the different data partitions */ int i; phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_data,new_lnL_data; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_time,new_lnL_time; phydbl floor; int n_nodes; /*! Check that sequences are isochronous. */ For(i,tree->n_otu-1) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; if(FABS(tree->rates->t_prior_max[tree->n_root->num] - tree->rates->t_prior_min[tree->n_root->num]) < 1.E-10) return; RATES_Record_Times(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_updown_t_cr]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; ratio = 0.0; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; cur_lnL_time = tree->rates->c_lnL_times; u = Uni(); mult = EXP(K*(u-0.5)); floor = 0.0; Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree); For(i,2*tree->n_otu-1) { if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_t_cr]++; return; } } if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); tree->rates->clock_r /= mult; if(tree->rates->clock_r < tree->rates->min_clock || tree->rates->clock_r > tree->rates->max_clock) { tree->rates->clock_r *= mult; RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_t_cr]++; return; } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); /* The Hastings ratio is actually mult^(n) when changing the absolute node heights. When considering the relative heights, this ratio combined to the Jacobian for the change of variable ends up to being equal to mult. */ ratio += (n_nodes - 1)*LOG(mult); /* ratio += -LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */ /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); /* !!!!!!!!!!!!1 */ /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); /* printf("\n. t_old = %f t_new = %f cr_old = %f cr_new = %f", */ /* tree->rates->nd_t[tree->n_root->num]/mult, */ /* tree->rates->nd_t[tree->n_root->num], */ /* tree->rates->clock_r*mult, */ /* tree->rates->clock_r); */ if(u > alpha) { RATES_Reset_Times(tree); tree->rates->clock_r *= mult; Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; } else { tree->mcmc->acc_move[tree->mcmc->num_move_updown_t_cr]++; } tree->mcmc->run_move[tree->mcmc->num_move_updown_t_cr]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Updown_T_Br(t_tree *tree) { int i; phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_data,new_lnL_data; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_time,new_lnL_time; phydbl floor; int n_nodes; /*! Check that sequences are isochronous. */ For(i,tree->n_otu-1) if(!Are_Equal(tree->rates->nd_t[i+1],tree->rates->nd_t[i],1.E-10)) return; if(FABS(tree->rates->t_prior_max[tree->n_root->num] - tree->rates->t_prior_min[tree->n_root->num]) < 1.E-10) return; RATES_Record_Times(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_updown_t_br]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; ratio = 0.0; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; cur_lnL_time = tree->rates->c_lnL_times; u = Uni(); mult = EXP(K*(u-0.5)); floor = 0.0; Scale_Subtree_Height(tree->n_root,mult,floor,&n_nodes,tree); For(i,2*tree->n_otu-1) { if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_t_br]++; return; } } if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); tree->rates->birth_rate /= mult; if(tree->rates->birth_rate < tree->rates->birth_rate_min || tree->rates->birth_rate > tree->rates->birth_rate_max) { tree->rates->birth_rate *= mult; RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_t_br]++; return; } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); /* The Hastings ratio is actually mult^(n) when changing the absolute node heights. When considering the relative heights, this ratio combined to the Jacobian for the change of variable ends up to being equal to mult. */ ratio += (n_nodes - 1)*LOG(mult); /* ratio += -LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */ /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); /* !!!!!!!!!!!!1 */ /* ratio += LOG(Dexp(FABS(new_height-floor),1./10.) / Dexp(FABS(cur_height-floor),1./10.)); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); /* printf("\n. t_old = %f t_new = %f br_old = %f br_new = %f mult = %f K=%f", */ /* tree->rates->nd_t[tree->n_root->num]/mult, */ /* tree->rates->nd_t[tree->n_root->num], */ /* tree->rates->birth_rate*mult, */ /* tree->rates->birth_rate,mult,K); */ if(u > alpha) { RATES_Reset_Times(tree); tree->rates->birth_rate *= mult; Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; } else { tree->mcmc->acc_move[tree->mcmc->num_move_updown_t_br]++; } tree->mcmc->run_move[tree->mcmc->num_move_updown_t_br]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Subtree_Height(t_tree *tree) { int i; phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_data,new_lnL_data; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_time,new_lnL_time; phydbl floor; int target; int n_nodes; RATES_Record_Times(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_subtree_height]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; ratio = 0.0; cur_lnL_time = tree->rates->c_lnL_times; u = Uni(); mult = EXP(K*(u-0.5)); /* mult = Rgamma(1./K,K); */ target = Rand_Int(tree->n_otu,2*tree->n_otu-3); floor = tree->rates->t_floor[target]; if(tree->a_nodes[target] == tree->n_root) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(!Scale_Subtree_Height(tree->a_nodes[target],mult,floor,&n_nodes,tree)) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_subtree_height]++; return; } For(i,2*tree->n_otu-1) { if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_subtree_height]++; return; } } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); new_lnL_time = TIMES_Lk_Times(tree); /* The Hastings ratio here is mult^(n_nodes) and the ratio of the prior joint densities of the modified node heigths given the unchanged one is 1. This is different from the case where all the nodes, including the root node, are scaled. */ ratio += (phydbl)(n_nodes)*LOG(mult); /* Likelihood ratio */ if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_time - cur_lnL_time); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { RATES_Reset_Times(tree); Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; tree->rates->c_lnL_times = cur_lnL_time; } else { tree->mcmc->acc_move[tree->mcmc->num_move_subtree_height]++; } tree->mcmc->run_move[tree->mcmc->num_move_subtree_height]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Tree_Rates(t_tree *tree) { phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_data,new_lnL_data; int n_nodes; phydbl init_clock; if(tree->rates->model == STRICTCLOCK) return; RATES_Record_Rates(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_tree_rates]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; init_clock = tree->rates->clock_r; ratio = 0.0; u = Uni(); mult = EXP(K*(u-0.5)); /* mult = Rgamma(1./K,K); */ /* Multiply branch rates (or add to log of rates) */ if(!Scale_Subtree_Rates(tree->n_root,mult,&n_nodes,tree)) { RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++; return; } if(n_nodes != 2*tree->n_otu-2) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /* Divide clock_r */ tree->rates->clock_r /= mult; if(tree->rates->clock_r < tree->rates->min_clock || tree->rates->clock_r > tree->rates->max_clock) { tree->rates->clock_r = init_clock; RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++; return; } /* if(tree->rates->model == GUINDON) */ /* { */ int i; For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); /* } */ new_lnL_rate = RATES_Lk_Rates(tree); /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */ ratio += (+(2*tree->n_otu-2)-1)*LOG(mult); /* ratio += (+(2*tree->n_otu-2)-1-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */ /* If modelling log of rates instead of rates */ if(tree->rates->model_log_rates == YES) ratio -= (2*tree->n_otu-2)*LOG(mult); /* Prior density ratio */ ratio += (new_lnL_rate - cur_lnL_rate); /* Likelihood density ratio */ ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); /* printf("\n. cur_lnL=%f new_lnL=%f ratio=%f mult=%f %f [%f %f]", */ /* cur_lnL_rate,new_lnL_rate,ratio,mult,(+(2*tree->n_otu-2)-1-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)),new_lnL_data,cur_lnL_data); */ if(u > alpha) { /* PhyML_Printf("\n. Reject mult=%f",mult); */ tree->rates->clock_r = init_clock; RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; } else { /* PhyML_Printf("\n. Accept mult=%f",mult); */ tree->mcmc->acc_move[tree->mcmc->num_move_tree_rates]++; } tree->mcmc->run_move[tree->mcmc->num_move_tree_rates]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Subtree_Rates(t_tree *tree) { phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_data,new_lnL_data; int target; int n_nodes; if(tree->rates->model == STRICTCLOCK) return; RATES_Record_Rates(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_subtree_rates]; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = cur_lnL_rate; cur_lnL_data = tree->c_lnL; new_lnL_data = cur_lnL_data; ratio = 0.0; u = Uni(); mult = EXP(K*(u-0.5)); /* mult = Rgamma(1./K,K); */ target = Rand_Int(tree->n_otu,2*tree->n_otu-3); /* Multiply branch rates */ if(!Scale_Subtree_Rates(tree->a_nodes[target],mult,&n_nodes,tree)) { RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_subtree_rates]++; return; } new_lnL_rate = RATES_Lk_Rates(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */ ratio += (+n_nodes)*LOG(mult); /* ratio += (n_nodes-2)*LOG(mult) + LOG(Dgamma(1./mult,1./K,K)/Dgamma(mult,1./K,K)); */ /* If modelling log of rates instead of rates */ if(tree->rates->model_log_rates == YES) ratio -= (n_nodes)*LOG(mult); /* Prior density ratio */ ratio += (new_lnL_rate - cur_lnL_rate); /* Likelihood density ratio */ ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; } else { tree->mcmc->acc_move[tree->mcmc->num_move_subtree_rates]++; } tree->mcmc->run_move[tree->mcmc->num_move_subtree_rates]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Swing(t_tree *tree) { int i; phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_data,new_lnL_data; phydbl cur_lnL_rate,new_lnL_rate; if(tree->rates->model == STRICTCLOCK) return; RATES_Record_Times(tree); RATES_Record_Rates(tree); Record_Br_Len(tree); K = 3.; cur_lnL_data = tree->c_lnL; new_lnL_data = cur_lnL_data; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = cur_lnL_rate; ratio = 0.0; u = Uni(); /* mult = EXP(K*(u-0.5)); */ mult = u*(K - 1./K) + 1./K; For(i,2*tree->n_otu-1) { if(tree->a_nodes[i]->tax == NO) { tree->rates->nd_t[i] *= mult; } if(tree->rates->nd_t[i] > tree->rates->t_prior_max[i] || tree->rates->nd_t[i] < tree->rates->t_prior_min[i]) { RATES_Reset_Times(tree); Restore_Br_Len(tree); return; } } For(i,2*tree->n_otu-2) { tree->rates->br_r[i] /= mult; if(tree->rates->br_r[i] > tree->rates->max_rate || tree->rates->br_r[i] < tree->rates->min_rate) { RATES_Reset_Times(tree); RATES_Reset_Rates(tree); Restore_Br_Len(tree); return; } } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); ratio += (-(tree->n_otu-1.)-2.)*LOG(mult); ratio += (new_lnL_rate - cur_lnL_rate); if(tree->mcmc->use_data) ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { RATES_Reset_Times(tree); RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; tree->rates->c_lnL_rates = cur_lnL_rate; /* printf("\n. Reject %8f",mult); */ } else { /* printf("\n. Accept %8f",mult); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Updown_Nu_Cr(t_tree *tree) { phydbl K,mult,u,alpha,ratio; phydbl cur_lnL_rate,new_lnL_rate; phydbl cur_lnL_data,new_lnL_data; int i; RATES_Record_Rates(tree); Record_Br_Len(tree); K = tree->mcmc->tune_move[tree->mcmc->num_move_updown_nu_cr]; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; u = Uni(); mult = EXP(K*(u-0.5)); /* Multiply branch rates */ /* if(!Scale_Subtree_Rates(tree->n_root,mult,&n_nodes,tree)) */ /* { */ /* RATES_Reset_Rates(tree); */ /* Restore_Br_Len(tree); */ /* tree->mcmc->run_move[tree->mcmc->num_move_updown_nu_cr]++; */ /* return; */ /* } */ tree->rates->clock_r /= mult; if(tree->rates->clock_r < tree->rates->min_clock || tree->rates->clock_r > tree->rates->max_clock) { tree->rates->clock_r *= mult; RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_nu_cr]++; return; } tree->rates->nu *= mult; if(tree->rates->nu < tree->rates->min_nu || tree->rates->nu > tree->rates->max_nu) { tree->rates->nu /= mult; tree->rates->clock_r *= mult; RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->mcmc->run_move[tree->mcmc->num_move_updown_nu_cr]++; return; } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); new_lnL_rate = RATES_Lk_Rates(tree); ratio = 0.0; /* Proposal ratio: 2n-2=> number of multiplications, 1=>number of divisions */ /* ratio += n_nodes*LOG(mult); /\* (1-1)*LOG(mult); *\/ */ ratio += 0.0*LOG(mult); /* (1-1)*LOG(mult); */ /* Prior density ratio */ ratio += (new_lnL_rate - cur_lnL_rate); /* Likelihood density ratio */ ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { tree->rates->clock_r *= mult; tree->rates->nu /= mult; RATES_Reset_Rates(tree); Restore_Br_Len(tree); tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; } else { tree->mcmc->acc_move[tree->mcmc->num_move_updown_nu_cr]++; } tree->mcmc->run_move[tree->mcmc->num_move_updown_nu_cr]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Print_Param_Stdin(t_mcmc *mcmc, t_tree *tree) { time_t cur_time; phydbl min; int i; time(&cur_time); min = MDBL_MAX; For(i,tree->n_otu-1) { /* printf("\n. %d %f %f %f %f",i, */ /* tree->mcmc->new_param_val[tree->mcmc->num_move_nd_t+i], */ /* tree->mcmc->old_param_val[tree->mcmc->num_move_nd_t+i], */ /* tree->mcmc->ess[tree->mcmc->num_move_nd_t+i], */ /* tree->mcmc->sum_val[tree->mcmc->num_move_nd_t+i]); */ if(tree->mcmc->ess[tree->mcmc->num_move_nd_t+i] < min) min = tree->mcmc->ess[tree->mcmc->num_move_nd_t+i]; } if(mcmc->run == 1) { PhyML_Printf("\n\n"); PhyML_Printf("%9s","Run"); PhyML_Printf(" %5s","Time"); PhyML_Printf(" %10s","Likelihood"); PhyML_Printf(" %10s","Prior"); PhyML_Printf(" %19s","SubstRate[ ESS ]"); PhyML_Printf(" %17s","TreeHeight[ ESS ]"); if(tree->rates->model == THORNE || tree->rates->model == GUINDON) PhyML_Printf(" %16s","AutoCor[ ESS ]"); else PhyML_Printf(" %16s","RateVar[ ESS ]"); PhyML_Printf(" %15s","BirthR[ ESS ]"); PhyML_Printf(" %8s","MinESS"); } if((cur_time - mcmc->t_last_print) > mcmc->print_every) { mcmc->t_last_print = cur_time; PhyML_Printf("\n"); PhyML_Printf("%9d",tree->mcmc->run); PhyML_Printf(" %5d",(int)(cur_time-mcmc->t_beg)); PhyML_Printf(" %10.2f",tree->c_lnL); PhyML_Printf(" %10.2f",(tree->rates ? tree->rates->c_lnL_rates+tree->rates->c_lnL_times : +1)); PhyML_Printf(" %12.6f[%5.0f]",RATES_Average_Substitution_Rate(tree),tree->mcmc->ess[tree->mcmc->num_move_clock_r]); /* PhyML_Printf("\t%12.6f[%5.0f]",tree->rates->clock_r,tree->mcmc->ess[tree->mcmc->num_move_clock_r]); */ PhyML_Printf(" %10.1f[%5.0f]", (tree->rates ? tree->rates->nd_t[tree->n_root->num] : -1.), tree->mcmc->ess[tree->mcmc->num_move_nd_t+tree->n_root->num-tree->n_otu]); PhyML_Printf(" %9f[%5.0f]", (tree->rates ? tree->rates->nu : -1.), tree->mcmc->ess[tree->mcmc->num_move_nu]); PhyML_Printf(" %8f[%5.0f]", (tree->rates ? tree->rates->birth_rate : -1.), tree->mcmc->ess[tree->mcmc->num_move_birth_rate]); PhyML_Printf(" %8.0f",min); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree) { int i; FILE *fp; char *s; int orig_approx; phydbl orig_lnL; char *s_tree; if(tree->mcmc->run > mcmc->chain_len) return; s = (char *)mCalloc(100,sizeof(char)); fp = mcmc->out_fp_stats; /* if(tree->mcmc->run == 0) */ /* { */ /* PhyML_Fprintf(stdout," ["); */ /* fflush(NULL); */ /* } */ /* if(!(mcmc->run%(mcmc->chain_len/10))) */ /* { */ /* PhyML_Fprintf(stdout,"."); */ /* fflush(NULL); */ /* } */ /* if(tree->mcmc->run == mcmc->chain_len) */ /* { */ /* PhyML_Fprintf(stdout,"]"); */ /* fflush(NULL); */ /* } */ /* MCMC_Print_Means(mcmc,tree); */ /* MCMC_Print_Last(mcmc,tree); */ if(!(mcmc->run%mcmc->sample_interval)) { MCMC_Copy_To_New_Param_Val(tree->mcmc,tree); For(i,tree->mcmc->n_moves) { if((tree->mcmc->acc_rate[i] > .1) && (tree->mcmc->start_ess[i] == NO)) tree->mcmc->start_ess[i] = YES; if(tree->mcmc->start_ess[i] == YES) MCMC_Update_Effective_Sample_Size(i,tree->mcmc,tree); if(tree->mcmc->run > (int) tree->mcmc->chain_len * 0.1) tree->mcmc->adjust_tuning[i] = NO; } if(tree->mcmc->run == 0) { time(&(mcmc->t_beg)); time(&(mcmc->t_last_print)); PhyML_Fprintf(fp,"# Random seed: %d",tree->io->r_seed); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"Run\t"); /* PhyML_Fprintf(fp,"Time\t"); */ /* PhyML_Fprintf(fp,"MeanRate\t"); */ /* PhyML_Fprintf(fp,"NormFact\t"); */ /* For(i,mcmc->n_moves) */ /* { */ /* strcpy(s,"Acc."); */ /* PhyML_Fprintf(fp,"%s%d\t",strcat(s,mcmc->move_name[i]),i); */ /* } */ /* For(i,mcmc->n_moves) */ /* { */ /* strcpy(s,"Tune."); */ /* PhyML_Fprintf(fp,"%s%d\t",strcat(s,mcmc->move_name[i]),i); */ /* } */ /* For(i,mcmc->n_moves) */ /* { */ /* strcpy(s,"Run."); */ /* PhyML_Fprintf(fp,"%s\t",strcat(s,mcmc->move_name[i])); */ /* } */ PhyML_Fprintf(fp,"LnLike[Exact]\t"); PhyML_Fprintf(fp,"LnLike[Approx]\t"); PhyML_Fprintf(fp,"LnRates\t"); PhyML_Fprintf(fp,"LnTimes\t"); PhyML_Fprintf(fp,"LnPosterior\t"); PhyML_Fprintf(fp,"ClockRate\t"); PhyML_Fprintf(fp,"EvolRate\t"); PhyML_Fprintf(fp,"Nu\t"); PhyML_Fprintf(fp,"BirthRate\t"); PhyML_Fprintf(fp,"TsTv\t"); if(tree->mod->ras->n_catg > 1) { if(tree->mod->ras->free_mixt_rates == NO) PhyML_Fprintf(fp,"Alpha\t"); else { For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"p%d\t",i); For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"r%d\t",i); } } if(tree->mod->m4mod->n_h > 1 && tree->mod->use_m4mod == YES) { For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"cov_p%d\t",i); For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"cov_r%d\t",i); PhyML_Fprintf(fp,"cov_switch\t"); } if(fp != stdout) { for(i=tree->n_otu;i<2*tree->n_otu-1;i++) { if(tree->a_nodes[i] == tree->n_root->v[2]) PhyML_Fprintf(fp,"T%d%s\t",i,"[LeftRoot]"); else if(tree->a_nodes[i] == tree->n_root->v[1]) PhyML_Fprintf(fp,"T%d%s\t",i,"[RightRoot]"); else if(tree->a_nodes[i] == tree->n_root) PhyML_Fprintf(fp,"T%d%s\t",i,"[Root]"); else PhyML_Fprintf(fp,"T%d[%d]\t",i,tree->a_nodes[i]->anc->num); } } /* if(fp != stdout) */ /* { */ /* For(i,2*tree->n_otu-1) */ /* { */ /* if(tree->a_nodes[i] == tree->n_root->v[2]) */ /* PhyML_Fprintf(fp,"R%d[LeftRoot]\t",i); */ /* else if(tree->a_nodes[i] == tree->n_root->v[1]) */ /* PhyML_Fprintf(fp,"R%d[RightRoot]\t",i); */ /* else if(tree->a_nodes[i] != tree->n_root) */ /* PhyML_Fprintf(fp," R%d[%d]\t",i,tree->a_nodes[i]->anc->num); */ /* else */ /* PhyML_Fprintf(fp," R%d[Root]\t",i); */ /* /\* PhyML_Fprintf(fp," R%d[%f]\t",i,tree->rates->mean_l[i]); *\/ */ /* } */ /* } */ if(fp != stdout) { For(i,2*tree->n_otu-2) { if(tree->a_nodes[i] == tree->n_root->v[2]) PhyML_Fprintf(fp,"B%d[LeftRoot]\t",i); else if(tree->a_nodes[i] == tree->n_root->v[1]) PhyML_Fprintf(fp,"B%d[RightRoot]\t",i); else PhyML_Fprintf(fp," B%d[%d]\t",i,tree->a_nodes[i]->anc->num); /* PhyML_Fprintf(fp," R%d[%f]\t",i,tree->rates->mean_l[i]); */ } } /* if(fp != stdout) */ /* { */ /* For(i,2*tree->n_otu-2) */ /* { */ /* if(tree->a_nodes[i] == tree->n_root->v[2]) */ /* PhyML_Fprintf(fp,"G%d[LeftRoot]\t",i); */ /* else if(tree->a_nodes[i] == tree->n_root->v[1]) */ /* PhyML_Fprintf(fp,"G%d[RightRoot]\t",i); */ /* else */ /* PhyML_Fprintf(fp," G%d[%f]\t",i,tree->rates->ml_l[i]); */ /* /\* PhyML_Fprintf(fp," R%d[%f]\t",i,tree->rates->mean_l[i]); *\/ */ /* } */ /* } */ /* if(fp != stdout) */ /* { */ /* For(i,2*tree->n_otu-3) */ /* { */ /* if(tree->a_edges[i] == tree->e_root) */ /* PhyML_Fprintf(fp,"*L[%f]%d\t",i,tree->rates->u_ml_l[i]); */ /* else */ /* PhyML_Fprintf(fp," L[%f]%d\t",i,tree->rates->u_ml_l[i]); */ /* } */ /* } */ PhyML_Fprintf(mcmc->out_fp_trees,"#NEXUS\n"); PhyML_Fprintf(mcmc->out_fp_trees,"BEGIN TREES;\n"); PhyML_Fprintf(mcmc->out_fp_trees,"\tTRANSLATE\n"); For(i,tree->n_otu-1) PhyML_Fprintf(mcmc->out_fp_trees,"\t%3d\t%s,\n",tree->a_nodes[i]->num+1,tree->a_nodes[i]->name); PhyML_Fprintf(mcmc->out_fp_trees,"\t%3d\t%s;\n",tree->a_nodes[i]->num+1,tree->a_nodes[i]->name); tree->write_tax_names = NO; } PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"%6d\t",tree->mcmc->run); /* time(&mcmc->t_cur); */ /* PhyML_Fprintf(fp,"%6d\t",(int)(mcmc->t_cur-mcmc->t_beg)); */ /* RATES_Update_Cur_Bl(tree); */ /* PhyML_Fprintf(fp,"%f\t",RATES_Check_Mean_Rates(tree)); */ /* PhyML_Fprintf(fp,"%f\t",tree->rates->norm_fact); */ /* For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%f\t",tree->mcmc->acc_rate[i]); */ /* For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%f\t",(phydbl)(tree->mcmc->tune_move[i])); */ /* For(i,tree->mcmc->n_moves) PhyML_Fprintf(fp,"%d\t",(int)(tree->mcmc->run_move[i])); */ orig_approx = tree->io->lk_approx; orig_lnL = tree->c_lnL; tree->io->lk_approx = EXACT; if(tree->mcmc->use_data) Lk(NULL,tree); else tree->c_lnL = 0.0; PhyML_Fprintf(fp,"%.1f\t",tree->c_lnL); tree->io->lk_approx = NORMAL; tree->c_lnL = 0.0; if(tree->mcmc->use_data) Lk(NULL,tree); else tree->c_lnL = 0.0; PhyML_Fprintf(fp,"%.1f\t",tree->c_lnL); tree->io->lk_approx = orig_approx; tree->c_lnL = orig_lnL; /* PhyML_Fprintf(fp,"0\t0\t"); */ PhyML_Fprintf(fp,"%G\t",tree->rates->c_lnL_rates); PhyML_Fprintf(fp,"%G\t",tree->rates->c_lnL_times); PhyML_Fprintf(fp,"%G\t",tree->c_lnL+tree->rates->c_lnL_rates+tree->rates->c_lnL_times); PhyML_Fprintf(fp,"%G\t",tree->rates->clock_r); PhyML_Fprintf(fp,"%G\t",RATES_Average_Substitution_Rate(tree)); PhyML_Fprintf(fp,"%G\t",tree->rates->nu); PhyML_Fprintf(fp,"%G\t",tree->rates->birth_rate); PhyML_Fprintf(fp,"%G\t",tree->mod->kappa->v); if(tree->mod->ras->n_catg > 1) { if(tree->mod->ras->free_mixt_rates == NO) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->alpha->v); else { For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba->v[i]); For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr->v[i]); /* For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_r_proba_unscaled[i]); */ /* For(i,tree->mod->ras->n_catg) PhyML_Fprintf(fp,"%G\t",tree->mod->ras->gamma_rr_unscaled[i]); */ } } if(tree->mod->m4mod->n_h > 1 && tree->mod->use_m4mod == YES) { For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->h_fq[i]); For(i,tree->mod->m4mod->n_h) PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->multipl[i]); PhyML_Fprintf(fp,"%G\t",tree->mod->m4mod->delta); } char *format = (char *)mCalloc(100,sizeof(char)); sprintf(format,"%%.%df\t",tree->mcmc->nd_t_digits); for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,format,tree->rates->nd_t[i]); Free(format); /* for(i=0;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,"%.4f\t",LOG(tree->rates->nd_r[i])); */ // Average rate along edges: length divided by elapsed time For(i,2*tree->n_otu-2) PhyML_Fprintf(fp,"%.4f\t", tree->rates->cur_l[i]/(tree->rates->nd_t[tree->a_nodes[i]->num] - tree->rates->nd_t[tree->a_nodes[i]->anc->num])); /* fp_pred = fopen("predict.txt","a"); */ /* for(i=0;i<2*tree->n_otu-2;i++) */ /* PhyML_Fprintf(fp_pred,"B%d\t%12f\t%12f\t%4d\n",i,EXP(tree->rates->br_r[i]),tree->rates->nd_t[i],tree->rates->has_survived[i]); */ /* fclose(fp_pred); */ /* phydbl p,sd,mean; */ /* for(i=0;i<2*tree->n_otu-2;i++) */ /* { */ /* sd = tree->rates->nu * (tree->rates->nd_t[i] - tree->rates->nd_t[tree->a_nodes[i]->anc->num]); */ /* mean = tree->rates->br_r[tree->a_nodes[i]->anc->num] - .5*sd*sd; */ /* p = Pnorm(tree->rates->br_r[i],mean,sd); */ /* PhyML_Fprintf(fp,"%f\t",p); */ /* tree->rates->mean_r[i] += p; */ /* } */ /* for(i=0;i<2*tree->n_otu-2;i++) PhyML_Fprintf(fp,"%.4f\t",tree->rates->cur_gamma_prior_mean[i]); */ /* if(fp != stdout) for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(fp,"%G\t",tree->rates->t_prior[i]); */ /* For(i,2*tree->n_otu-3) PhyML_Fprintf(fp,"%f\t",EXP(tree->a_edges[i]->l->v)); */ /* RATES_Update_Cur_Bl(tree); */ /* For(i,2*tree->n_otu-3) PhyML_Fprintf(fp,"%f\t",tree->a_edges[i]->l->v); */ For(i,2*tree->n_otu-2) tree->rates->mean_r[i] = EXP(tree->rates->br_r[i]); For(i,2*tree->n_otu-1) tree->rates->mean_t[i] = tree->rates->nd_t[i]; /* Time_To_Branch(tree); */ /* char *s; */ /* s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */ /* strcpy(s,mcmc->io->in_align_file); */ /* strcat(s,"_"); */ /* strcat(s,mcmc->out_filename); */ /* strcat(s,".ps"); */ /* DR_Draw_Tree(s,tree); */ /* Free(s); */ /* FILE *fp; */ /* int j; */ /* t_node *d, *v1, *v2; */ /* int n1, n2; */ /* phydbl r1, r2; */ /* s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */ /* strcpy(s,mcmc->io->in_align_file); */ /* strcat(s,"_"); */ /* strcat(s,mcmc->out_filename); */ /* strcat(s,".corr"); */ /* fp = fopen(s,"w"); */ /* n1 = n2 = 0; */ /* r1 = r2 = 0.f; */ /* For(i,2*tree->n_otu-3) */ /* { */ /* if(tree->a_nodes[i]->tax == NO) */ /* { */ /* d = tree->a_nodes[i]; */ /* v1 = v2 = NULL; */ /* For(j,3) */ /* { */ /* if(d->v[j] != d->anc && d->b[j] != tree->e_root) */ /* { */ /* if(!v1) v1 = d->v[j]; */ /* else v2 = d->v[j]; */ /* } */ /* } */ /* For(j,3) */ /* { */ /* if(v1->v[j] && v1->v[j] == d) */ /* { */ /* n1 = v1->bip_size[j]; */ /* /\* r1 = RATES_Get_Mean_Rate_In_Subtree(v1,tree); *\/ */ /* r1 = EXP(tree->rates->br_r[v1->num]); */ /* break; */ /* } */ /* } */ /* For(j,3) */ /* { */ /* if(v2->v[j] && v2->v[j] == d) */ /* { */ /* n2 = v2->bip_size[j]; */ /* /\* r2 = RATES_Get_Mean_Rate_In_Subtree(v2,tree); *\/ */ /* r2 = EXP(tree->rates->br_r[v2->num]); */ /* break; */ /* } */ /* } */ /* fprintf(fp,"\n%4d %4d %15f %15f",n1,n2,r1,r2); */ /* } */ /* } */ /* fclose(fp); */ // TREES Time_To_Branch(tree); tree->bl_ndigits = 3; s_tree = Write_Tree(tree,NO); tree->bl_ndigits = 7; PhyML_Fprintf(mcmc->out_fp_trees,"TREE %8d [%f] = [&R] %s\n",mcmc->run,tree->c_lnL,s_tree); Free(s_tree); } if(tree->mcmc->run == mcmc->chain_len) PhyML_Fprintf(mcmc->out_fp_trees,"END;\n"); fflush(NULL); Free(s); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Print_Means(t_mcmc *mcmc, t_tree *tree) { if(!(mcmc->run%mcmc->sample_interval)) { int i; char *s; s = (char *)mCalloc(T_MAX_FILE,sizeof(char)); strcpy(s,tree->mcmc->out_filename); strcat(s,".means"); fclose(mcmc->out_fp_means); mcmc->out_fp_means = fopen(s,"w"); PhyML_Fprintf(mcmc->out_fp_means,"#"); for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(mcmc->out_fp_means,"T%d\t",i); PhyML_Fprintf(mcmc->out_fp_means,"\n"); for(i=tree->n_otu;i<2*tree->n_otu-1;i++) tree->rates->t_mean[i] *= (phydbl)(mcmc->run / mcmc->sample_interval); for(i=tree->n_otu;i<2*tree->n_otu-1;i++) { tree->rates->t_mean[i] += tree->rates->nd_t[i]; tree->rates->t_mean[i] /= (phydbl)(mcmc->run / mcmc->sample_interval + 1); /* PhyML_Fprintf(tree->mcmc->out_fp_means,"%d\t",tree->mcmc->run / tree->mcmc->sample_interval); */ PhyML_Fprintf(tree->mcmc->out_fp_means,"%.1f\t",tree->rates->t_mean[i]); } PhyML_Fprintf(tree->mcmc->out_fp_means,"\n"); fflush(NULL); Free(s); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Print_Last(t_mcmc *mcmc, t_tree *tree) { if(!(mcmc->run%mcmc->sample_interval)) { int i; char *s; s = (char *)mCalloc(T_MAX_FILE,sizeof(char)); strcpy(s,tree->mcmc->out_filename); strcat(s,".lasts"); fclose(mcmc->out_fp_last); mcmc->out_fp_last = fopen(s,"w"); /* rewind(mcmc->out_fp_last); */ PhyML_Fprintf(mcmc->out_fp_last,"#"); PhyML_Fprintf(tree->mcmc->out_fp_last,"Time\t"); for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(tree->mcmc->out_fp_last,"T%d\t",i); PhyML_Fprintf(tree->mcmc->out_fp_last,"\n"); if(mcmc->run) { time(&(mcmc->t_cur)); PhyML_Fprintf(tree->mcmc->out_fp_last,"%d\t",(int)(mcmc->t_cur-mcmc->t_beg)); /* PhyML_Fprintf(tree->mcmc->out_fp_last,"%d\t",(int)(mcmc->t_beg)); */ } for(i=tree->n_otu;i<2*tree->n_otu-1;i++) PhyML_Fprintf(tree->mcmc->out_fp_last,"%.1f\t",tree->rates->nd_t[i]); PhyML_Fprintf(tree->mcmc->out_fp_last,"\n"); fflush(NULL); Free(s); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Pause(t_mcmc *mcmc) { char choice; char *s; int len; s = (char *)mCalloc(100,sizeof(char)); if(!(mcmc->run%mcmc->chain_len) && (mcmc->is_burnin == NO)) { PhyML_Printf("\n. Do you wish to stop the analysis [N/y] "); if(!scanf("%c",&choice)) Exit("\n"); if(choice == '\n') choice = 'N'; else getchar(); /* \n */ Uppercase(&choice); switch(choice) { case 'N': { len = 1E+4; PhyML_Printf("\n. How many extra generations is required [default: 1E+4] "); Getstring_Stdin(s); if(s[0] == '\0') len = 1E+4; else len = (int)atof(s); if(len < 0) { PhyML_Printf("\n. The value entered must be an integer greater than 0.\n"); Exit("\n"); } mcmc->chain_len += len; break; } case 'Y': { PhyML_Printf("\n. Ok. Done.\n"); Exit("\n"); break; } default: { PhyML_Printf("\n. Please enter 'Y' or 'N'.\n"); Exit("\n"); } } } Free(s); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Terminate() { char choice; PhyML_Printf("\n\n. Do you really want to terminate [Y/n]: "); if(!scanf("%c",&choice)) Exit("\n"); if(choice == '\n') choice = 'Y'; else getchar(); /* \n */ Uppercase(&choice); if(choice == 'Y') raise(SIGTERM); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Copy_MCMC_Struct(t_mcmc *ori, t_mcmc *cpy, char *filename) { int pid; int i; cpy->use_data = ori->use_data ; cpy->sample_interval = ori->sample_interval ; cpy->chain_len = ori->chain_len ; cpy->randomize = ori->randomize ; cpy->norm_freq = ori->norm_freq ; cpy->n_moves = ori->n_moves ; cpy->max_tune = ori->max_tune ; cpy->min_tune = ori->min_tune ; cpy->print_every = ori->print_every ; cpy->is_burnin = ori->is_burnin ; cpy->is = ori->is ; cpy->io = ori->io ; cpy->in_fp_par = ori->in_fp_par ; cpy->nd_t_digits = ori->nd_t_digits ; cpy->max_lag = ori->max_lag ; For(i,cpy->n_moves) { cpy->start_ess[i] = ori->start_ess[i]; cpy->ess_run[i] = ori->ess_run[i]; cpy->ess[i] = ori->ess[i]; cpy->move_weight[i] = ori->move_weight[i]; cpy->run_move[i] = ori->run_move[i]; cpy->acc_move[i] = ori->acc_move[i]; cpy->prev_run_move[i] = ori->prev_run_move[i]; cpy->prev_acc_move[i] = ori->prev_acc_move[i]; cpy->acc_rate[i] = ori->acc_rate[i]; cpy->tune_move[i] = ori->tune_move[i]; strcpy(cpy->move_name[i],ori->move_name[i]); cpy->adjust_tuning[i] = ori->adjust_tuning[i]; } if(filename) { char *s; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(cpy->out_filename,filename); pid = getpid(); sprintf(cpy->out_filename+strlen(cpy->out_filename),"_%d",pid); strcpy(s,cpy->io->in_align_file); strcat(s,"_"); strcat(s,cpy->out_filename); strcat(s,"_stats"); cpy->out_fp_stats = fopen(s,"w"); strcpy(s,cpy->io->in_align_file); strcat(s,"_"); strcat(s,cpy->out_filename); strcat(s,"_trees"); cpy->out_fp_trees = fopen(s,"w"); strcpy(s,cpy->io->in_align_file); strcat(s,"_"); strcat(s,cpy->out_filename); strcat(s,"_constree"); cpy->out_fp_constree = fopen(s,"w"); Free(s); } else { cpy->out_fp_stats = stderr; cpy->out_fp_trees = stderr; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Close_MCMC(t_mcmc *mcmc) { fclose(mcmc->out_fp_trees); fclose(mcmc->out_fp_stats); fclose(mcmc->out_fp_constree); /* fclose(mcmc->out_fp_means); */ /* fclose(mcmc->out_fp_last); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Kappa(t_tree *tree) { tree->mod->kappa->v = Uni()*5.; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Rate_Across_Sites(t_tree *tree) { if(tree->mod->ras->n_catg == 1) return; if(tree->mod->ras->free_mixt_rates == YES) { int i; For(i,tree->mod->ras->n_catg-1) tree->mod->ras->gamma_r_proba_unscaled->v[i] = Uni()*100.; tree->mod->ras->gamma_r_proba_unscaled->v[tree->mod->ras->n_catg-1] = 100.; For(i,tree->mod->ras->n_catg) tree->mod->ras->gamma_rr_unscaled->v[i] = (phydbl)i+1.; /* Do not randomize those as their ordering matter */ } else { tree->mod->ras->alpha->v = Uni()*5.; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Covarion_Rates(t_tree *tree) { if(tree->mod->use_m4mod == NO) return; if(tree->mod->m4mod->n_h == 1) return; int i; For(i,tree->mod->m4mod->n_h) { tree->mod->m4mod->multipl_unscaled[i] = (phydbl)i+1.; tree->mod->m4mod->h_fq_unscaled[i] = Uni()*(100.-0.01) + 0.01; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Covarion_Switch(t_tree *tree) { if(tree->mod->use_m4mod == NO) return; tree->mod->m4mod->delta = Uni()*(10.-0.01)+0.01; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Branch_Lengths(t_tree *tree) { int i; if(tree->mod->log_l == NO) For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = Rexp(10.); else For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = -4* Uni(); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Node_Rates(t_tree *tree) { int i,err; phydbl mean_r, var_r; phydbl min_r, max_r; mean_r = 1.0; var_r = 0.5; min_r = tree->rates->min_rate; max_r = tree->rates->max_rate; For(i,2*tree->n_otu-2) if(tree->a_nodes[i] != tree->n_root) tree->rates->nd_r[i] = Rnorm_Trunc(mean_r,SQRT(var_r),min_r,max_r,&err); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Rates(t_tree *tree) { /* Should be called once t_node times have been determined */ int i; For(i,2*tree->n_otu-2) tree->rates->br_r[i] = 1.0; /* For(i,2*tree->n_otu-2) */ /* { */ /* u = Uni(); */ /* u = u * (r_max-r_min) + r_min; */ /* tree->rates->br_r[i] = u; */ /* if(tree->rates->br_r[i] < tree->rates->min_rate) tree->rates->br_r[i] = tree->rates->min_rate; */ /* if(tree->rates->br_r[i] > tree->rates->max_rate) tree->rates->br_r[i] = tree->rates->max_rate; */ /* } */ MCMC_Randomize_Rates_Pre(tree->n_root,tree->n_root->v[2],tree); MCMC_Randomize_Rates_Pre(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Rates_Pre(t_node *a, t_node *d, t_tree *tree) { int i; phydbl mean_r, var_r; phydbl min_r, max_r; int err; /* mean_r = tree->rates->br_r[a->num]; */ /* var_r = tree->rates->nu * (tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]); */ mean_r = 1.0; var_r = 0.5; min_r = tree->rates->min_rate; max_r = tree->rates->max_rate; tree->rates->br_r[d->num] = Rnorm_Trunc(mean_r,SQRT(var_r),min_r,max_r,&err); if(d->tax) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) MCMC_Randomize_Rates_Pre(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Birth(t_tree *tree) { phydbl min_b,max_b; phydbl u; min_b = tree->rates->birth_rate_min; max_b = MIN(0.5,tree->rates->birth_rate_max); u = Uni(); tree->rates->birth_rate = (max_b - min_b) * u + min_b; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Nu(t_tree *tree) { phydbl min_nu,max_nu; phydbl u; /* It is preferable to start with small values of nu as if is difficult for the MCMC sampler to sample equal rates on edge (i.e., molecular clock) since such combination of rate lies on the boundary of the space of all edge rate combination. We give here a bit of help to the sampler by considering starting points close to the molecular clock constraint. */ min_nu = tree->rates->min_nu; max_nu = tree->rates->max_nu/10.; u = Uni(); tree->rates->nu = (max_nu - min_nu) * u + min_nu; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Clock_Rate(t_tree *tree) { phydbl u; u = Uni(); tree->rates->clock_r = u * (tree->rates->max_clock - tree->rates->min_clock) + tree->rates->min_clock; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Alpha(t_tree *tree) { phydbl u; u = Uni(); tree->rates->alpha = u*6.0+1.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Node_Times(t_tree *tree) { phydbl t_sup, t_inf; phydbl u; int iter; int i; phydbl dt,min_dt; int min_node; t_inf = tree->rates->t_prior_min[tree->n_root->num]; t_sup = tree->rates->t_prior_max[tree->n_root->num]; u = Uni(); u *= (t_sup - t_inf); u += t_inf; tree->rates->nd_t[tree->n_root->num] = u; MCMC_Randomize_Node_Times_Top_Down(tree->n_root,tree->n_root->v[2],tree); MCMC_Randomize_Node_Times_Top_Down(tree->n_root,tree->n_root->v[1],tree); min_node = -1; iter = 0; do { min_dt = MDBL_MAX; For(i,2*tree->n_otu-2) { dt = tree->rates->nd_t[i] - tree->rates->nd_t[tree->a_nodes[i]->anc->num]; if(dt < min_dt) { min_dt = dt; min_node = i; } } if(min_dt > 0.01 * FABS(tree->rates->nd_t[tree->n_root->num])/(phydbl)(tree->n_otu-1)) break; RATES_Record_Times(tree); For(i,2*tree->n_otu-1) { if(tree->a_nodes[i]->tax == NO) tree->rates->nd_t[i] -= 0.1*FABS(tree->rates->nd_t[tree->n_root->num])/(phydbl)(tree->n_otu-1); if(tree->rates->nd_t[i] < tree->rates->t_prior_min[i] || tree->rates->nd_t[i] > tree->rates->t_prior_max[i]) { RATES_Reset_Times(tree); break; } } MCMC_Randomize_Node_Times_Bottom_Up(tree->n_root,tree->n_root->v[2],tree); MCMC_Randomize_Node_Times_Bottom_Up(tree->n_root,tree->n_root->v[1],tree); iter++; } while(iter < 1000); if(iter == 1000) { PhyML_Printf("\n== min_dt = %f",min_dt); PhyML_Printf("\n== min->t=%f min->anc->t=%f",tree->rates->nd_t[min_node],tree->rates->nd_t[tree->a_nodes[min_node]->anc->num]); PhyML_Printf("\n== d up=%f down=%f",tree->rates->t_prior_min[min_node],tree->rates->t_prior_max[min_node]); PhyML_Printf("\n== a up=%f down=%f",tree->rates->t_prior_min[tree->a_nodes[min_node]->anc->num],tree->rates->t_prior_max[tree->a_nodes[min_node]->anc->num]); PhyML_Printf("\n== up=%f down=%f",tree->rates->t_prior_min[min_node],tree->rates->t_floor[tree->a_nodes[min_node]->anc->num]); PhyML_Printf("\n== min_node = %d",min_node); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } /* PhyML_Printf("\n. Needed %d iterations to randomize node heights.",iter); */ /* TIMES_Print_Node_Times(tree->n_root,tree->n_root->v[2],tree); */ /* TIMES_Print_Node_Times(tree->n_root,tree->n_root->v[1],tree); */ if(RATES_Check_Node_Times(tree)) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Node_Times_Bottom_Up(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; phydbl u; phydbl t_inf, t_sup; t_node *v1, *v2; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { MCMC_Randomize_Node_Times_Bottom_Up(d,d->v[i],tree); } } v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } } t_sup = MIN(tree->rates->nd_t[v1->num],tree->rates->nd_t[v2->num]); t_inf = tree->rates->nd_t[a->num]; u = Uni(); u *= (t_sup - t_inf); u += t_inf; if(u > tree->rates->t_prior_min[d->num] && u < tree->rates->t_prior_max[d->num]) tree->rates->nd_t[d->num] = u; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Randomize_Node_Times_Top_Down(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; phydbl u; phydbl t_inf, t_sup; t_inf = MAX(tree->rates->nd_t[a->num],tree->rates->t_prior_min[d->num]); t_sup = tree->rates->t_prior_max[d->num]; u = Uni(); u *= (t_sup - t_inf); u += t_inf; tree->rates->nd_t[d->num] = u; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { MCMC_Randomize_Node_Times_Top_Down(d,d->v[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Get_Acc_Rates(t_mcmc *mcmc) { int i; phydbl eps; int lag; if(mcmc->run < (int)(0.01*mcmc->chain_len)) lag = 100; else lag = 100; eps = 1.E-6; For(i,mcmc->n_moves) { if(mcmc->run_move[i] - mcmc->prev_run_move[i] > lag) { mcmc->acc_rate[i] = (phydbl)(mcmc->acc_move[i] - mcmc->prev_acc_move[i] + eps) / (phydbl)(mcmc->run_move[i] - mcmc->prev_run_move[i] + eps) ; mcmc->prev_run_move[i] = mcmc->run_move[i]; mcmc->prev_acc_move[i] = mcmc->acc_move[i]; MCMC_Adjust_Tuning_Parameter(i,mcmc); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc) { if(mcmc->adjust_tuning[move]) { phydbl scale; phydbl rate; phydbl rate_inf,rate_sup; if(mcmc->run < (int)(0.01*mcmc->chain_len)) scale = 1.5; else scale = 1.2; if(!strcmp(mcmc->move_name[move],"tree_height")) { rate_inf = 0.1; rate_sup = 0.1; } else if(!strcmp(mcmc->move_name[move],"subtree_height")) { rate_inf = 0.2; rate_sup = 0.2; } else if(!strcmp(mcmc->move_name[move],"updown_t_cr")) { rate_inf = 0.1; rate_sup = 0.1; } else if(!strcmp(mcmc->move_name[move],"clock")) { rate_inf = 0.1; rate_sup = 0.1; } /* if(!strcmp(mcmc->move_name[move],"tree_rates")) */ /* { */ /* rate_inf = 0.05; */ /* rate_sup = 0.05; */ /* } */ else if(!strcmp(mcmc->move_name[move],"phyrex_lbda")) { rate_inf = 0.234; rate_sup = 0.234; } else if(!strcmp(mcmc->move_name[move],"phyrex_mu")) { rate_inf = 0.234; rate_sup = 0.234; } else if(!strcmp(mcmc->move_name[move],"phyrex_rad")) { rate_inf = 0.234; rate_sup = 0.234; } else if(!strcmp(mcmc->move_name[move],"phyrex_ldsk_and_disk")) { rate_inf = 0.234; rate_sup = 0.234; } else if(!strcmp(mcmc->move_name[move],"phyrex_ldsk_multi")) { rate_inf = 0.234; rate_sup = 0.234; } else if(!strcmp(mcmc->move_name[move],"phyrex_disk_multi")) { rate_inf = 0.234; rate_sup = 0.234; } else { rate_inf = 0.234; // Gareth Robert's magic number ! rate_sup = 0.234; } rate = mcmc->acc_rate[move]; if(rate < rate_inf) { mcmc->tune_move[move] /= scale; } else if(rate > rate_sup) { mcmc->tune_move[move] *= scale; } if(mcmc->tune_move[move] > mcmc->max_tune) mcmc->tune_move[move] = mcmc->max_tune; if(mcmc->tune_move[move] < mcmc->min_tune) mcmc->tune_move[move] = mcmc->min_tune; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_One_Length(t_edge *b, t_tree *tree) { phydbl u; phydbl new_lnL_data, cur_lnL_data; phydbl ratio, alpha; phydbl new_l, cur_l; phydbl K,mult; cur_l = b->l->v; cur_lnL_data = tree->c_lnL; K = 0.1; u = Uni(); mult = EXP(K*(u-0.5)); /* mult = u*(K-1./K)+1./K; */ new_l = cur_l * mult; if(new_l < tree->mod->l_min || new_l > tree->mod->l_max) return; b->l->v = new_l; new_lnL_data = Lk(b,tree); /* tree->both_sides = NO; */ /* new_lnL_data = Lk(tree); */ ratio = (new_lnL_data - cur_lnL_data) + (LOG(mult)); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { b->l->v = cur_l; Update_PMat_At_Given_Edge(b,tree); tree->c_lnL = cur_lnL_data; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Scale_Br_Lens(t_tree *tree) { phydbl u; phydbl new_lnL_data, cur_lnL_data; phydbl ratio, alpha; phydbl K,mult; int i; Record_Br_Len(tree); cur_lnL_data = tree->c_lnL; K = 1.2; u = Uni(); mult = u*(K-1./K)+1./K; For(i,2*tree->n_otu-3) { tree->a_edges[i]->l->v *= mult; if(tree->a_edges[i]->l->v < tree->mod->l_min || tree->a_edges[i]->l->v > tree->mod->l_max) return; } Set_Both_Sides(NO,tree); new_lnL_data = Lk(NULL,tree); ratio = (new_lnL_data - cur_lnL_data) + (2*tree->n_otu-5) * (LOG(mult)); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { Restore_Br_Len(tree); tree->c_lnL = cur_lnL_data; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Br_Lens(t_tree *tree) { MCMC_Br_Lens_Pre(tree->a_nodes[0], tree->a_nodes[0]->v[0], tree->a_nodes[0]->b[0],tree); /* int i; */ /* For(i,2*tree->n_otu-3) */ /* { */ /* MCMC_One_Length(tree->a_edges[Rand_Int(0,2*tree->n_otu-4)],acc,run,tree); */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Br_Lens_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { int i; if(a == tree->n_root || d == tree->n_root) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); MCMC_One_Length(b,tree); if(d->tax) return; else { For(i,3) if(d->v[i] != a) { Update_P_Lk(tree,d->b[i],d); MCMC_Br_Lens_Pre(d,d->v[i],d->b[i],tree); } Update_P_Lk(tree,b,d); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Kappa(t_tree *tree) { int change,i; change = NO; Switch_Eigen(YES,tree->mod); if(tree->io->lk_approx == NORMAL) { tree->io->lk_approx = EXACT; if(tree->mcmc->use_data == YES) Lk(NULL,tree); change = YES; } For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = NO; MCMC_Single_Param_Generic(&(tree->mod->kappa->v),0.,100.,tree->mcmc->num_move_kappa, NULL,&(tree->c_lnL), NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_kappa],NO,NULL,tree,NULL); if(change == YES) { tree->io->lk_approx = NORMAL; if(tree->mcmc->use_data == YES) Lk(NULL,tree); } Switch_Eigen(NO,tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Rate_Across_Sites(t_tree *tree) { if(tree->mod->ras->n_catg == 1) return; if(tree->mod->ras->free_mixt_rates == YES) { MCMC_Free_Mixt_Rate(tree); } else { MCMC_Alpha(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Alpha(t_tree *tree) { int i; For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = NO; MCMC_Single_Param_Generic(&(tree->mod->ras->alpha->v),0.,100.,tree->mcmc->num_move_ras, NULL,&(tree->c_lnL), NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_ras],NO,NULL,tree,NULL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Free_Mixt_Rate(t_tree *tree) { phydbl num,denom; phydbl Jnow,Jthen; phydbl *z,*y; phydbl y_cur,z_cur; phydbl low_bound,up_bound; int c,i; int c2updt; phydbl u; phydbl hr; int n_moves; phydbl cur_lnL_data, new_lnL_data; phydbl ratio,alpha; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; c = tree->mod->ras->n_catg; z = tree->mod->ras->gamma_rr_unscaled->v; y = tree->mod->ras->gamma_r_proba_unscaled->v; num = z[c-1]*(y[c-1]-y[c-2]); denom = z[0]*y[0]; for(i=1;imcmc->use_data == YES) ratio += (new_lnL_data - cur_lnL_data); ratio += LOG(hr); ratio = EXP(ratio); alpha = MIN(1.,ratio); /* printf("\n. class=%d new_val=%f cur_val=%f ratio=%f hr=%f y=%f denom=%f",c2updt,y[c2updt],y_cur,ratio,Jthen/Jnow,y[c-1],denom); */ u = Uni(); if(u > alpha) /* Reject */ { y[c2updt] = y_cur; tree->c_lnL = cur_lnL_data; } else /* Accept */ { cur_lnL_data = new_lnL_data; /* Update the Jacobian */ num = z[c-1]*(y[c-1]-y[c-2]); denom = z[0]*y[0]; for(i=1;imod->ras->n_catg-1); // Proposal move. u = Uni(); /* K = tree->mcmc->tune_move[tree->mcmc->num_move_ras+c2updt+c]; */ /* z_cur = z[c2updt]; */ /* mult = EXP(K*(u-0.5)); */ /* z[c2updt] *= mult; */ u = Uni(); low_bound = (c2updt==0)?(.0):(z[c2updt-1]); up_bound = (c2updt==c-1)?(100.0):(z[c2updt+1]); z_cur = z[c2updt]; z[c2updt] = low_bound + u*(up_bound - low_bound); // Calculate the Jacobian for the change of variable from unscaled // frequencies to the frequencies themselves. num = z[c-1]*(y[c-1]-y[c-2]); denom = z[0]*y[0]; for(i=1;imcmc->use_data == YES) ratio += (new_lnL_data - cur_lnL_data); ratio += LOG(hr); /* ratio += LOG(mult); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) { z[c2updt] = z_cur; tree->c_lnL = cur_lnL_data; } else { cur_lnL_data = new_lnL_data; // Update the Jacobian num = z[c-1]*(y[c-1]-y[c-2]); denom = z[0]*y[0]; for(i=1;imod->use_m4mod == NO) return; Switch_Eigen(YES,tree->mod); For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; class = Rand_Int(0,tree->mod->m4mod->n_h-1); min = 0.01; max = 100.; u = Uni(); if(u < .5) { if(!class) { min = 0.01; max = tree->mod->m4mod->multipl_unscaled[1]; } else if(class == tree->mod->m4mod->n_h-1) { min = tree->mod->m4mod->multipl_unscaled[tree->mod->m4mod->n_h-2]; max = +100.; } else { min = MIN(tree->mod->m4mod->multipl_unscaled[class-1],tree->mod->m4mod->multipl_unscaled[class+1]); max = MAX(tree->mod->m4mod->multipl_unscaled[class-1],tree->mod->m4mod->multipl_unscaled[class+1]); } MCMC_Single_Param_Generic(&(tree->mod->m4mod->multipl_unscaled[class]),min,max,tree->mcmc->num_move_cov_rates+class+tree->mod->m4mod->n_h, NULL,&(tree->c_lnL), NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_cov_rates+class+tree->mod->m4mod->n_h],NO,NULL,tree,NULL); } else { MCMC_Single_Param_Generic(&(tree->mod->m4mod->h_fq_unscaled[class]),0.01,+100.,tree->mcmc->num_move_cov_rates+class, NULL,&(tree->c_lnL), NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_cov_rates+class],NO,NULL,tree,NULL); } Switch_Eigen(NO,tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Covarion_Switch(t_tree *tree) { if(tree->mod->use_m4mod == NO) return; Switch_Eigen(YES,tree->mod); MCMC_Single_Param_Generic(&(tree->mod->m4mod->delta),0.01,+100.,tree->mcmc->num_move_cov_switch, NULL,&(tree->c_lnL), NULL,Wrap_Lk,tree->mcmc->move_type[tree->mcmc->num_move_cov_switch],NO,NULL,tree,NULL); Switch_Eigen(NO,tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Birth_Rate(t_tree *tree) { /* printf("\n. BIRTH cur_lnL_time: %f ",tree->rates->c_lnL_times); */ #ifdef INVITEE tree->rates->update_time_norm_const = YES; #endif MCMC_Single_Param_Generic(&(tree->rates->birth_rate), tree->rates->birth_rate_min, tree->rates->birth_rate_max, tree->mcmc->num_move_birth_rate, &(tree->rates->c_lnL_times),NULL, Wrap_Lk_Times,NULL,tree->mcmc->move_type[tree->mcmc->num_move_birth_rate],NO,NULL,tree,NULL); #ifdef INVITEE TIMES_Lk_Times(tree); tree->rates->update_time_norm_const = NO; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Nu(t_tree *tree) { phydbl cur_nu,new_nu,cur_lnL_rate,new_lnL_rate; phydbl u,alpha,ratio; phydbl min_nu,max_nu; phydbl K; phydbl cur_lnL_data, new_lnL_data; int i; Record_Br_Len(tree); cur_nu = -1.0; new_nu = -1.0; ratio = 0.0; K = tree->mcmc->tune_move[tree->mcmc->num_move_nu]; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_rate = tree->rates->c_lnL_rates; cur_lnL_data = tree->c_lnL; new_lnL_data = tree->c_lnL; cur_nu = tree->rates->nu; min_nu = tree->rates->min_nu; max_nu = tree->rates->max_nu; MCMC_Make_Move(&cur_nu,&new_nu,min_nu,max_nu,&ratio,K,tree->mcmc->move_type[tree->mcmc->num_move_nu]); if(new_nu < max_nu && new_nu > min_nu) { tree->rates->nu = new_nu; new_lnL_rate = RATES_Lk_Rates(tree); if((tree->rates->model == GUINDON) && (tree->mcmc->use_data)) { For(i,2*tree->n_otu-2) tree->rates->br_do_updt[i] = YES; new_lnL_data = Lk(NULL,tree); } ratio += (new_lnL_rate - cur_lnL_rate); ratio += (new_lnL_data - cur_lnL_data); /* !!!!!!!!!!!!!!!! */ /* Modelling exp(nu) and making move on nu */ /* ratio += (new_nu - cur_nu); */ /* Exponential prior on nu */ /* ratio += LOG(Dexp(new_nu,10.) / Dexp(cur_nu,10.)); */ ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->rates->nu = cur_nu; tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; Restore_Br_Len(tree); } else { tree->mcmc->acc_move[tree->mcmc->num_move_nu]++; } } tree->mcmc->run_move[tree->mcmc->num_move_nu]++; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_All_Rates(t_tree *tree) { phydbl cur_lnL_data, new_lnL_data, cur_lnL_rate; phydbl u, ratio, alpha; new_lnL_data = tree->c_lnL; cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; ratio = 0.0; Record_Br_Len(tree); RATES_Record_Rates(tree); MCMC_Sim_Rate(tree->n_root,tree->n_root->v[2],tree); MCMC_Sim_Rate(tree->n_root,tree->n_root->v[1],tree); new_lnL_data = Lk(NULL,tree); ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { Restore_Br_Len(tree); RATES_Reset_Rates(tree); tree->rates->c_lnL_rates = cur_lnL_rate; } else { tree->rates->c_lnL_rates = RATES_Lk_Rates(tree);; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Only works when simulating from prior */ void MCMC_Sim_Rate(t_node *a, t_node *d, t_tree *tree) { int err; phydbl mean,sd,br_r_a,dt_d; br_r_a = tree->rates->br_r[a->num]; dt_d = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]; sd = SQRT(dt_d*tree->rates->nu); if(tree->rates->model_log_rates == YES) { mean = br_r_a - .5*sd*sd; } else { mean = br_r_a; } if(tree->rates->model == STRICTCLOCK) tree->rates->br_r[d->num] = 1.0; else tree->rates->br_r[d->num] = Rnorm_Trunc(mean,sd,tree->rates->min_rate,tree->rates->max_rate,&err); if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) MCMC_Sim_Rate(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree) { int i; phydbl sum; mcmc->io = tree->io; mcmc->n_moves = 0; mcmc->num_move_nd_r = mcmc->n_moves; mcmc->n_moves += 2*tree->n_otu-1; mcmc->num_move_br_r = mcmc->n_moves; mcmc->n_moves += 2*tree->n_otu-2; mcmc->num_move_nd_t = mcmc->n_moves; mcmc->n_moves += tree->n_otu-1; mcmc->num_move_nu = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_clock_r = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_tree_height = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_subtree_height = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_kappa = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_tree_rates = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_subtree_rates = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_updown_nu_cr = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_ras = mcmc->n_moves; mcmc->n_moves += (tree->mod ? 2*tree->mod->ras->n_catg : 1); mcmc->num_move_updown_t_cr = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_cov_rates = mcmc->n_moves; mcmc->n_moves += (tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1); mcmc->num_move_cov_switch = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_birth_rate = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_updown_t_br = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_jump_calibration = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_lambda = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_sigma = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_tau = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_updown_tau_lbda = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_updown_lbda_sigma = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_geo_dum = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_lbda = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_mu = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_rad = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_indel_disk = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_move_disk_ud = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_swap_disk = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_indel_hit = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_spr = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_scale_times = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_ldscape_lim = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_sigsq = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_sim = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_traj = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_lbda_times = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_indel_disk_serial = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_sim_plus = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_indel_hit_serial = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_ldsk_given_disk = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_disk_given_ldsk = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_ldsk_and_disk = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_ldsk_multi = mcmc->n_moves; mcmc->n_moves += 1; mcmc->num_move_phyrex_disk_multi = mcmc->n_moves; mcmc->n_moves += 1; mcmc->run_move = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->acc_move = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->prev_run_move = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->prev_acc_move = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->acc_rate = (phydbl *)mCalloc(mcmc->n_moves,sizeof(phydbl)); mcmc->move_weight = (phydbl *)mCalloc(mcmc->n_moves,sizeof(phydbl)); mcmc->move_type = (int *)mCalloc(mcmc->n_moves,sizeof(int)); /* TO DO: instead of n_moves here we should have something like n_param */ mcmc->ess = (phydbl *)mCalloc(mcmc->n_moves,sizeof(phydbl)); mcmc->ess_run = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->start_ess = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->adjust_tuning = (int *)mCalloc(mcmc->n_moves,sizeof(int)); mcmc->tune_move = (phydbl *)mCalloc(mcmc->n_moves,sizeof(phydbl)); mcmc->sampled_val = (phydbl *)mCalloc((int)mcmc->n_moves*(mcmc->chain_len/mcmc->sample_interval + 1),sizeof(phydbl)); mcmc->mode = (phydbl *)mCalloc((int)mcmc->n_moves,sizeof(phydbl)); mcmc->move_name = (char **)mCalloc(mcmc->n_moves,sizeof(char *)); For(i,mcmc->n_moves) mcmc->move_name[i] = (char *)mCalloc(T_MAX_MCMC_MOVE_NAME,sizeof(char)); For(i,mcmc->n_moves) mcmc->adjust_tuning[i] = YES; for(i=mcmc->num_move_br_r;inum_move_br_r+2*tree->n_otu-2;i++) strcpy(mcmc->move_name[i],"br_rate"); for(i=mcmc->num_move_nd_r;inum_move_nd_r+2*tree->n_otu-1;i++) strcpy(mcmc->move_name[i],"nd_rate"); for(i=mcmc->num_move_nd_t;inum_move_nd_t+tree->n_otu-1;i++) strcpy(mcmc->move_name[i],"time"); strcpy(mcmc->move_name[mcmc->num_move_nu],"nu"); strcpy(mcmc->move_name[mcmc->num_move_clock_r],"clock"); strcpy(mcmc->move_name[mcmc->num_move_tree_height],"tree_height"); strcpy(mcmc->move_name[mcmc->num_move_subtree_height],"subtree_height"); strcpy(mcmc->move_name[mcmc->num_move_kappa],"kappa"); strcpy(mcmc->move_name[mcmc->num_move_tree_rates],"tree_rates"); strcpy(mcmc->move_name[mcmc->num_move_subtree_rates],"subtree_rates"); strcpy(mcmc->move_name[mcmc->num_move_updown_nu_cr],"updown_nu_cr"); for(i=mcmc->num_move_ras;inum_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) strcpy(mcmc->move_name[i],"ras"); strcpy(mcmc->move_name[mcmc->num_move_updown_t_cr],"updown_t_cr"); for(i=mcmc->num_move_cov_rates;inum_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) strcpy(mcmc->move_name[i],"cov_rates"); strcpy(mcmc->move_name[mcmc->num_move_cov_switch],"cov_switch"); strcpy(mcmc->move_name[mcmc->num_move_birth_rate],"birth_rate"); strcpy(mcmc->move_name[mcmc->num_move_updown_t_br],"updown_t_br"); strcpy(mcmc->move_name[mcmc->num_move_jump_calibration],"jump_calibration"); strcpy(mcmc->move_name[mcmc->num_move_geo_lambda],"geo_lambda"); strcpy(mcmc->move_name[mcmc->num_move_geo_sigma],"geo_sigma"); strcpy(mcmc->move_name[mcmc->num_move_geo_tau],"geo_tau"); strcpy(mcmc->move_name[mcmc->num_move_geo_updown_tau_lbda],"geo_updown_tau_lbda"); strcpy(mcmc->move_name[mcmc->num_move_geo_updown_lbda_sigma],"geo_updown_lbda_sigma"); strcpy(mcmc->move_name[mcmc->num_move_geo_dum],"geo_dum"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_lbda],"phyrex_lbda"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_mu],"phyrex_mu"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_rad],"phyrex_rad"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_indel_disk],"phyrex_indel_disk"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_move_disk_ud],"phyrex_move_disk_ud"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_swap_disk],"phyrex_swap_disk"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_indel_hit],"phyrex_indel_hit"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_spr],"phyrex_spr"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_scale_times],"phyrex_scale_times"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_ldscape_lim],"phyrex_ldscape_lim"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_sigsq],"phyrex_sigsq"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_sim],"phyrex_sim"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_traj],"phyrex_traj"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_lbda_times],"phyrex_lbda_times"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_indel_disk_serial],"phyrex_indel_disk_serial"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_sim_plus],"phyrex_sim_plus"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_indel_hit_serial],"phyrex_indel_hit_serial"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_ldsk_multi],"phyrex_ldsk_multi"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_disk_multi],"phyrex_disk_multi"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_ldsk_and_disk],"phyrex_ldsk_and_disk"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_disk_given_ldsk],"phyrex_disk_given_ldsk"); strcpy(mcmc->move_name[mcmc->num_move_phyrex_ldsk_given_disk],"phyrex_ldsk_given_disk"); For(i,mcmc->n_moves) mcmc->move_type[i] = -1; if(tree->rates && tree->rates->model_log_rates == YES) for(i=mcmc->num_move_br_r;inum_move_br_r+2*tree->n_otu-2;i++) mcmc->move_type[i] = MCMC_MOVE_RANDWALK_NORMAL; else for(i=mcmc->num_move_br_r;inum_move_br_r+2*tree->n_otu-2;i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE; for(i=mcmc->num_move_nd_r;inum_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE; /* for(i=mcmc->num_move_nd_t;inum_move_nd_t+tree->n_otu-1;i++) mcmc->move_type[i] = MCMC_MOVE_RANDWALK_UNIFORM; */ for(i=mcmc->num_move_nd_t;inum_move_nd_t+tree->n_otu-1;i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_nu] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_clock_r] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_tree_height] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_subtree_height] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_kappa] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_tree_rates] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_subtree_rates] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_updown_nu_cr] = MCMC_MOVE_RANDWALK_NORMAL; for(i=mcmc->num_move_ras;inum_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_type[i] = MCMC_MOVE_RANDWALK_NORMAL; mcmc->move_type[mcmc->num_move_updown_t_cr] = MCMC_MOVE_SCALE_THORNE; for(i=mcmc->num_move_cov_rates;inum_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_type[i] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_cov_switch] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_birth_rate] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_updown_t_br] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_jump_calibration] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_lambda] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_sigma] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_tau] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_updown_tau_lbda] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_updown_lbda_sigma] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_geo_dum] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_phyrex_lbda] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_phyrex_mu] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_phyrex_rad] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_phyrex_scale_times] = MCMC_MOVE_SCALE_THORNE; mcmc->move_type[mcmc->num_move_phyrex_sigsq] = MCMC_MOVE_SCALE_THORNE; /* We start with small tuning parameter values in order to have inflated ESS for clock_r */ For(i,mcmc->n_moves) { switch(mcmc->move_type[i]) { case MCMC_MOVE_RANDWALK_NORMAL: { /* mcmc->tune_move[i] = 1.E-1; */ mcmc->tune_move[i] = 100.; break; } case MCMC_MOVE_RANDWALK_UNIFORM: { /* mcmc->tune_move[i] = 2.0; */ mcmc->tune_move[i] = 20.0; break; } case MCMC_MOVE_SCALE_GAMMA: { mcmc->tune_move[i] = 1.0; /* mcmc->tune_move[i] = 10.0; */ break; } case MCMC_MOVE_SCALE_THORNE: { mcmc->tune_move[i] = 1.0; break; } default : { mcmc->tune_move[i] = 1.0; break; } } } for(i=mcmc->num_move_br_r;inum_move_br_r+2*tree->n_otu-2;i++) mcmc->move_weight[i] = (phydbl)(1./(2.*tree->n_otu-2)); /* Rates */ for(i=mcmc->num_move_nd_r;inum_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_weight[i] = 0.0; /* Node rates */ for(i=mcmc->num_move_nd_t;inum_move_nd_t+tree->n_otu-1;i++) mcmc->move_weight[i] = (phydbl)(1./(tree->n_otu-1)); /* Times */ mcmc->move_weight[mcmc->num_move_clock_r] = 1.0; mcmc->move_weight[mcmc->num_move_tree_height] = 2.0; mcmc->move_weight[mcmc->num_move_subtree_height] = 0.0; mcmc->move_weight[mcmc->num_move_nu] = 2.0; mcmc->move_weight[mcmc->num_move_kappa] = 0.5; mcmc->move_weight[mcmc->num_move_tree_rates] = 1.0; mcmc->move_weight[mcmc->num_move_subtree_rates] = 0.5; mcmc->move_weight[mcmc->num_move_updown_nu_cr] = 0.0; for(i=mcmc->num_move_ras;inum_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod ? (phydbl)tree->mod->ras->n_catg : 1)); mcmc->move_weight[mcmc->num_move_updown_t_cr] = 0.0; /* Does not seem to work well (does not give uniform prior on root height when sampling from prior) */ for(i=mcmc->num_move_cov_rates;inum_move_cov_rates+(tree->mod->m4mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod->m4mod ? (phydbl)tree->mod->m4mod->n_h : 1)); mcmc->move_weight[mcmc->num_move_cov_switch] = 1.0; mcmc->move_weight[mcmc->num_move_birth_rate] = 2.0; mcmc->move_weight[mcmc->num_move_updown_t_br] = 1.0; #if defined (INVITEE) mcmc->move_weight[mcmc->num_move_jump_calibration] = 0.1; #else mcmc->move_weight[mcmc->num_move_jump_calibration] = 0.0; #endif mcmc->move_weight[mcmc->num_move_geo_lambda] = 1.0; mcmc->move_weight[mcmc->num_move_geo_sigma] = 1.0; mcmc->move_weight[mcmc->num_move_geo_tau] = 1.0; mcmc->move_weight[mcmc->num_move_geo_updown_tau_lbda] = 1.0; mcmc->move_weight[mcmc->num_move_geo_updown_lbda_sigma] = 1.0; mcmc->move_weight[mcmc->num_move_geo_dum] = 1.0; # if defined (PHYREX) mcmc->move_weight[mcmc->num_move_phyrex_lbda] = 5.0; mcmc->move_weight[mcmc->num_move_phyrex_mu] = 8.0; mcmc->move_weight[mcmc->num_move_phyrex_rad] = 5.0; mcmc->move_weight[mcmc->num_move_phyrex_sigsq] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_disk] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_hit] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_move_disk_ud] = 5.0; mcmc->move_weight[mcmc->num_move_phyrex_swap_disk] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_spr] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_scale_times] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_ldscape_lim] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_sim] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_traj] = 3.0; mcmc->move_weight[mcmc->num_move_phyrex_lbda_times] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_sim_plus] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_disk_serial] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_hit_serial] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_given_disk] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_disk_given_ldsk] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_and_disk] = 1.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_multi] = 2.0; mcmc->move_weight[mcmc->num_move_phyrex_disk_multi] = 2.0; # else mcmc->move_weight[mcmc->num_move_phyrex_lbda] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_mu] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_rad] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_sigsq] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_disk] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_hit] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_move_disk_ud] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_swap_disk] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_spr] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_scale_times] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_ldscape_lim] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_sim] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_traj] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_lbda_times] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_sim_plus] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_disk_serial] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_indel_hit_serial] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_given_disk] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_disk_given_ldsk] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_and_disk] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_ldsk_multi] = 0.0; mcmc->move_weight[mcmc->num_move_phyrex_disk_multi] = 0.0; #endif /* for(i=mcmc->num_move_br_r;inum_move_br_r+2*tree->n_otu-2;i++) mcmc->move_weight[i] = 0.0; /\* Rates *\/ */ /* for(i=mcmc->num_move_nd_r;inum_move_nd_r+2*tree->n_otu-1;i++) mcmc->move_weight[i] = 0.0; /\* Node rates *\/ */ /* for(i=mcmc->num_move_nd_t;inum_move_nd_t+tree->n_otu-1;i++) mcmc->move_weight[i] = 0.0; /\* Times *\/ */ /* mcmc->move_weight[mcmc->num_move_clock_r] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_tree_height] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_subtree_height] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_tree_height] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_subtree_height] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_nu] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_kappa] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_tree_rates] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_subtree_rates] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_updown_nu_cr] = 0.0; */ /* for(i=mcmc->num_move_ras;inum_move_ras+(tree->mod ? 2*tree->mod->ras->n_catg : 1);i++) mcmc->move_weight[i] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_updown_t_cr] = 0.0; /\* Does not seem to work well (does not give uniform prior on root height */ /* when sampling from prior) *\/ */ /* for(i=mcmc->num_move_cov_rates;inum_move_cov_rates+(tree->mod ? 2*tree->mod->m4mod->n_h : 1);i++) mcmc->move_weight[i] = 0.5*(1./(tree->mod ? (phydbl)tree->mod->m4mod->n_h : 1)); */ /* mcmc->move_weight[mcmc->num_move_cov_switch] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_birth_rate] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_updown_t_br] = 0.0; */ /* #if defined (INVITEE) */ /* mcmc->move_weight[mcmc->num_move_jump_calibration] = 1.0; */ /* #else */ /* mcmc->move_weight[mcmc->num_move_jump_calibration] = 0.0; */ /* #endif */ /* mcmc->move_weight[mcmc->num_move_geo_lambda] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_geo_sigma] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_geo_tau] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_geo_updown_tau_lbda] = 0.0; */ /* mcmc->move_weight[mcmc->num_move_geo_updown_lbda_sigma] = 0.0; */ sum = 0.0; For(i,mcmc->n_moves) sum += mcmc->move_weight[i]; For(i,mcmc->n_moves) mcmc->move_weight[i] /= sum; for(i=1;in_moves;i++) mcmc->move_weight[i] += mcmc->move_weight[i-1]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree) { /* int i; */ /* mcmc->lag_param_val[mcmc->num_move_nu] = tree->rates->nu; */ /* mcmc->lag_param_val[mcmc->num_move_clock_r] = tree->rates->clock_r; */ /* mcmc->lag_param_val[mcmc->num_move_tree_height] = tree->rates->nd_t[tree->n_root->num]; */ /* mcmc->lag_param_val[mcmc->num_move_kappa] = tree->mod->kappa->v; */ /* For(i,2*tree->n_otu-2) */ /* mcmc->lag_param_val[mcmc->num_move_br_r+i] = tree->rates->br_r[i]; */ /* For(i,tree->n_otu-1) */ /* mcmc->lag_param_val[mcmc->num_move_nd_t+i] = tree->rates->nd_t[tree->n_otu+i]; */ /* For(i,2*tree->n_otu-1) */ /* mcmc->lag_param_val[mcmc->num_move_nd_r+i] = tree->rates->nd_r[i]; */ /* For(i,mcmc->n_moves) tree->mcmc->new_param_val[i] = tree->mcmc->lag_param_val[i]; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Copy_To_New_Param_Val(t_mcmc *mcmc, t_tree *tree) { mcmc->sampled_val[mcmc->num_move_nu*mcmc->sample_size+mcmc->sample_num] = tree->rates->nu; mcmc->sampled_val[mcmc->num_move_clock_r*mcmc->sample_size+mcmc->sample_num] = tree->rates->clock_r; mcmc->sampled_val[mcmc->num_move_tree_height*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_t[tree->n_root->num]; mcmc->sampled_val[mcmc->num_move_kappa*mcmc->sample_size+mcmc->sample_num] = tree->mod ? tree->mod->kappa->v : -1.; mcmc->sampled_val[mcmc->num_move_birth_rate*mcmc->sample_size+mcmc->sample_num] = tree->rates->birth_rate; /* For(i,2*tree->n_otu-2) */ /* mcmc->sampled_val[(mcmc->num_move_br_r+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->br_r[i]; */ /* For(i,tree->n_otu-1) */ /* mcmc->sampled_val[(mcmc->num_move_nd_t+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_t[tree->n_otu+i]; */ /* For(i,2*tree->n_otu-1) */ /* mcmc->sampled_val[(mcmc->num_move_nd_r+i)*mcmc->sample_size+mcmc->sample_num] = tree->rates->nd_r[i]; */ mcmc->sampled_val[mcmc->num_move_geo_tau*mcmc->sample_size+mcmc->sample_num] = tree->geo ? tree->geo->tau : -1.; mcmc->sampled_val[mcmc->num_move_geo_lambda*mcmc->sample_size+mcmc->sample_num] = tree->geo ? tree->geo->lbda : -1.; mcmc->sampled_val[mcmc->num_move_geo_sigma*mcmc->sample_size+mcmc->sample_num] = tree->geo ? tree->geo->sigma : -1.; mcmc->sampled_val[mcmc->num_move_geo_dum*mcmc->sample_size+mcmc->sample_num] = tree->geo ? tree->geo->dum : -1.; #ifdef PHYREX mcmc->sampled_val[mcmc->num_move_phyrex_lbda*mcmc->sample_size+mcmc->sample_num] = tree->mmod ? tree->mmod->lbda : -1.; mcmc->sampled_val[mcmc->num_move_phyrex_mu*mcmc->sample_size+mcmc->sample_num] = tree->mmod ? PHYREX_Neighborhood_Size(tree) : -1.; mcmc->sampled_val[mcmc->num_move_phyrex_sigsq*mcmc->sample_size+mcmc->sample_num] = tree->mmod ? PHYREX_Update_Sigsq(tree) : -1.; mcmc->sampled_val[mcmc->num_move_phyrex_rad*mcmc->sample_size+mcmc->sample_num] = tree->mmod ? tree->mmod->rad : -1.; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Slice_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree) { phydbl L,R; /* Left and Right limits of the slice */ phydbl w; /* window width */ phydbl u; phydbl x0,x1; phydbl logy; t_edge *b; int i; b = NULL; if(a == tree->n_root) b = tree->e_root; else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; } w = 0.05; /* w = 10.; */ x0 = tree->rates->br_r[d->num]; logy = tree->c_lnL+tree->rates->c_lnL_rates - Rexp(1.); u = Uni(); L = x0 - w*u; R = L + w; do { tree->rates->br_r[d->num] = L; tree->rates->br_do_updt[d->num] = YES; RATES_Update_Cur_Bl(tree); Lk(b,tree); RATES_Lk_Rates(tree); if(L < tree->rates->min_rate) { L = tree->rates->min_rate - w; break;} L = L - w; } while(tree->c_lnL + tree->rates->c_lnL_rates > logy); L = L + w; do { tree->rates->br_r[d->num] = R; tree->rates->br_do_updt[d->num] = YES; RATES_Update_Cur_Bl(tree); Lk(b,tree); RATES_Lk_Rates(tree); if(R > tree->rates->max_rate) { R = tree->rates->max_rate + w; break;} R = R + w; } while(tree->c_lnL + tree->rates->c_lnL_rates > logy); R = R - w; for(;;) { u = Uni(); x1 = L + u*(R-L); tree->rates->br_r[d->num] = x1; tree->rates->br_do_updt[d->num] = YES; RATES_Update_Cur_Bl(tree); Lk(b,tree); RATES_Lk_Rates(tree); if(tree->c_lnL + tree->rates->c_lnL_rates > logy) break; if(x1 < x0) L = x1; else R = x1; } if(traversal == YES) { if(d->tax == YES) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */ MCMC_Slice_One_Rate(d,d->v[i],YES,tree); } } if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Make_Move(phydbl *cur, phydbl *new, phydbl inf, phydbl sup, phydbl *loghr, phydbl tune, int move_type) { phydbl u; switch(move_type) { case MCMC_MOVE_RANDWALK_NORMAL: { *new = *cur + Rnorm(0.0,tune); /* Do not use reflection here */ *loghr = 0.0; break; } case MCMC_MOVE_RANDWALK_UNIFORM: { u = Uni(); /* *new = u * (2.*tune) + (*cur) - tune; */ /* *new = Reflect(*new,inf,sup); */ *new = u*(sup-inf)+inf; *loghr = 0.0; break; } case MCMC_MOVE_SCALE_THORNE: { u = Uni(); *new = (*cur) * EXP(tune*(u-.5)); *loghr = LOG((*new)/(*cur)); break; } case MCMC_MOVE_SCALE_GAMMA: { phydbl r; *new = (*cur) * Rgamma(1./tune,tune); r = (*new)/(*cur); *loghr = -LOG(r) + LOG(Dgamma(1./r,1./tune,tune)/Dgamma(r,1./tune,tune)); break; } default : { PhyML_Printf("\n. Move not implemented"); Exit(""); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MCMC_Read_Param_Vals(t_tree *tree) { char *token; int sizemax; FILE *in_fp; phydbl val; int i,v; in_fp = tree->mcmc->in_fp_par; sizemax = T_MAX_LINE; token = (char *)mCalloc(sizemax,sizeof(char)); if(fgets(token,sizemax,in_fp) == NULL) // Skip first line { PhyML_Printf("\n== Wrong file format."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } if(fgets(token,sizemax,in_fp) == NULL) // Skip second { PhyML_Printf("\n== Wrong file format."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } v=fscanf(in_fp,"%lf\t",&val); // Run /* PhyML_Printf("\n. Run = %d",(int)val); */ v=fscanf(in_fp,"%lf\t",&val); // LnLike[Exact] /* PhyML_Printf("\n. LnLike = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // LnLike[Approx] /* PhyML_Printf("\n. LnLike = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // LnPriorRate /* PhyML_Printf("\n. LnPrior = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // LnPriorTime /* PhyML_Printf("\n. LnPrior = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // LnPosterior /* PhyML_Printf("\n. LnPost = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // ClockRate tree->rates->clock_r = val; /* PhyML_Printf("\n. Clock = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // EvolRate v=fscanf(in_fp,"%lf\t",&val); // Nu tree->rates->nu = val; /* PhyML_Printf("\n. Nu = %f",val); */ v=fscanf(in_fp,"%lf\t",&val); // Birth rate tree->rates->birth_rate = val; v=fscanf(in_fp,"%lf\t",&val); // TsTv tree->mod->kappa->v = val; /* PhyML_Printf("\n. TsTv = %f",val); */ For(i,tree->n_otu-1) { v=fscanf(in_fp,"%lf\t",&val); // Node heights tree->rates->nd_t[i+tree->n_otu] = val; } For(i,2*tree->n_otu-2) { v=fscanf(in_fp,"%lf\t",&val); // Edge average rates tree->rates->br_r[i] = LOG(val); } v++; Free(token); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef PHYREX void MCMC_PHYREX_Lbda(t_tree *tree) { MCMC_Single_Param_Generic(&(tree->mmod->lbda), tree->mmod->min_lbda, tree->mmod->max_lbda, tree->mcmc->num_move_phyrex_lbda, NULL,&(tree->mmod->c_lnL), NULL,PHYREX_Wrap_Lk, tree->mcmc->move_type[tree->mcmc->num_move_phyrex_lbda], NO,NULL,tree,NULL); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef PHYREX void MCMC_PHYREX_Mu(t_tree *tree) { /* phydbl u,alpha,ratio; */ /* phydbl cur_glnL, new_glnL, hr; */ /* phydbl ori_mu; */ /* phydbl ori_beta,new_beta; */ /* phydbl K; */ /* tree->mcmc->run_move[tree->mcmc->num_move_phyrex_mu]++; */ /* new_glnL = UNLIKELY; */ /* cur_glnL = tree->mmod->c_lnL; */ /* hr = 0.0; */ /* ratio = 0.0; */ /* ori_mu = tree->mmod->mu; */ /* ori_beta = (1./tree->mmod->mu)-1.; */ /* K = tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_mu]; */ /* u = Uni(); */ /* new_beta = ori_beta * EXP(K*(u-.5)); */ /* hr += LOG(new_beta/ori_beta); */ /* tree->mmod->mu = 1./(new_beta+1.); */ /* new_glnL = PHYREX_Lk(tree); */ /* ratio += (new_glnL - cur_glnL); */ /* ratio += hr; */ /* ratio = EXP(ratio); */ /* alpha = MIN(1.,ratio); */ /* /\* Always accept move *\/ */ /* if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; */ /* u = Uni(); */ /* if(u > alpha) /\* Reject *\/ */ /* { */ /* tree->mmod->mu = ori_mu; */ /* tree->mmod->c_lnL = cur_glnL; */ /* /\* new_glnL = MIGREP_Lk(tree); *\/ */ /* /\* if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) *\/ */ /* /\* { *\/ */ /* /\* PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); *\/ */ /* /\* Generic_Exit(__FILE__,__LINE__,__FUNCTION__); *\/ */ /* /\* } *\/ */ /* } */ /* else */ /* { */ /* tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_mu]++; */ /* /\* printf("- Accept"); *\/ */ /* } */ MCMC_Single_Param_Generic(&(tree->mmod->mu), tree->mmod->min_mu, tree->mmod->max_mu, tree->mcmc->num_move_phyrex_mu, NULL,&(tree->mmod->c_lnL), NULL,PHYREX_Wrap_Lk, tree->mcmc->move_type[tree->mcmc->num_move_phyrex_mu], NO,NULL,tree,NULL); } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef PHYREX void MCMC_PHYREX_Radius(t_tree *tree) { MCMC_Single_Param_Generic(&(tree->mmod->rad), tree->mmod->min_rad, tree->mmod->max_rad, tree->mcmc->num_move_phyrex_rad, NULL,&(tree->mmod->c_lnL), NULL,PHYREX_Wrap_Lk, tree->mcmc->move_type[tree->mcmc->num_move_phyrex_rad], NO,NULL,tree,NULL); /* phydbl u,alpha,ratio; */ /* phydbl cur_glnL, new_glnL, hr; */ /* phydbl cur_rad, new_rad; */ /* phydbl rate; */ /* tree->mcmc->run_move[tree->mcmc->num_move_phyrex_rad]++; */ /* new_glnL = tree->mmod->c_lnL; */ /* cur_glnL = tree->mmod->c_lnL; */ /* hr = 0.0; */ /* ratio = 0.0; */ /* cur_rad = tree->mmod->rad; */ /* new_rad = tree->mmod->rad; */ /* rate = 1.0; */ /* new_rad = Rexp_Trunc(rate, */ /* tree->mmod->min_rad, */ /* tree->mmod->max_rad); */ /* tree->mmod->rad = new_rad; */ /* hr += rate*(new_rad - cur_rad); */ /* new_glnL = PHYREX_Lk(tree); */ /* ratio += (new_glnL - cur_glnL); */ /* ratio += hr; */ /* ratio = EXP(ratio); */ /* alpha = MIN(1.,ratio); */ /* /\* Always accept move *\/ */ /* if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; */ /* u = Uni(); */ /* if(u > alpha) /\* Reject *\/ */ /* { */ /* tree->mmod->rad = cur_rad; */ /* PHYREX_Lk(tree); */ /* } */ /* else */ /* { */ /* tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_rad]++; */ /* } */ } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Sigsq(t_tree *tree) { tree->mmod->update_rad = YES; MCMC_Single_Param_Generic(&(tree->mmod->sigsq), tree->mmod->min_sigsq, tree->mmod->max_sigsq, tree->mcmc->num_move_phyrex_sigsq, NULL,&(tree->mmod->c_lnL), NULL,PHYREX_Wrap_Lk, tree->mcmc->move_type[tree->mcmc->num_move_phyrex_sigsq], NO,NULL,tree,NULL); tree->mmod->rad = PHYREX_Update_Radius(tree); tree->mmod->update_rad = NO; } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Indel_Disk(t_tree *tree) { int cur_n_disk, new_n_disk; int cur_n_int; int cur_n_hit; phydbl hr; phydbl cur_lbda,new_lbda; phydbl cur_mu,new_mu; phydbl cur_rad,new_rad; phydbl T; T = PHYREX_Tree_Height(tree); T = FABS(T); hr = 0.0; new_lbda = tree->mmod->lbda; cur_lbda = tree->mmod->lbda; new_mu = tree->mmod->mu; cur_mu = tree->mmod->mu; new_rad = tree->mmod->rad; cur_rad = tree->mmod->rad; /* new_lbda = cur_lbda * EXP(0.5*(Uni()-.5)); */ /* hr += LOG(new_lbda/cur_lbda); */ /* new_mu = cur_mu * EXP(0.5*(Uni()-.5)); */ /* hr += LOG(new_mu/cur_mu); */ /* new_rad = cur_rad * EXP(0.5*(Uni()-.5)); */ /* hr += LOG(new_rad/cur_rad); */ if(new_rad > tree->mmod->max_rad || new_rad < tree->mmod->min_rad) return; if(new_mu > tree->mmod->max_mu || new_mu < tree->mmod->min_mu) return; if(new_lbda > tree->mmod->max_lbda || new_lbda < tree->mmod->min_lbda) return; tree->mmod->lbda = new_lbda; tree->mmod->mu = new_mu; tree->mmod->rad = new_rad; cur_n_hit = PHYREX_Total_Number_Of_Hit_Disks(tree); cur_n_int = PHYREX_Total_Number_Of_Intervals(tree); cur_n_disk = cur_n_int - cur_n_hit; if(cur_n_hit == 0) { new_n_disk = (int)Rpois(cur_n_disk+1); hr += Dpois(cur_n_disk,new_n_disk+1,YES); hr -= Dpois(new_n_disk,cur_n_disk+1,YES); } else { new_n_disk = (int)Rpois(T*new_lbda*(phydbl)cur_n_disk/(cur_n_hit+cur_n_disk)); hr += Dpois(cur_n_disk,T*cur_lbda*(phydbl)new_n_disk/(cur_n_hit+new_n_disk),YES); hr -= Dpois(new_n_disk,T*new_lbda*(phydbl)cur_n_disk/(cur_n_hit+cur_n_disk),YES); } if(new_n_disk < cur_n_disk) MCMC_PHYREX_Delete_Disk(hr, cur_n_disk - new_n_disk , cur_lbda, cur_mu, cur_rad, tree); else MCMC_PHYREX_Insert_Disk(hr, new_n_disk - cur_n_disk, cur_lbda, cur_mu, cur_rad, tree); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Insert or delete a disk that does not affect any ldisk */ #ifdef PHYREX void MCMC_PHYREX_Delete_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phydbl cur_mu, phydbl cur_rad, t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL; phydbl T; t_dsk *disk,**target_disk,**valid_disks; int i,j,block,n_valid_disks,*permut; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_disk]++; if(n_delete_disks == 0) { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } valid_disks = NULL; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; ratio = 0.0; block = 100; disk = tree->disk->prev; if(!disk->prev) { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } n_valid_disks = 0; do { if(!disk->ldsk) { if(!n_valid_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_valid_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); valid_disks[n_valid_disks] = disk; n_valid_disks++; } disk = disk->prev; } while(disk && disk->prev); if(!n_valid_disks) { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } if(n_valid_disks - n_delete_disks < 0) { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } target_disk = (t_dsk **)mCalloc(n_delete_disks,sizeof(t_dsk *)); permut = Permutate(n_valid_disks); For(j,n_delete_disks) { /* Uniform selection of a disk where no coalescent nor 'hit' occurred */ target_disk[j] = valid_disks[permut[j]]; PHYREX_Remove_Disk(target_disk[j]); For(i,tree->mmod->n_dim) hr += LOG(1./tree->mmod->lim->lonlat[i]); } T = PHYREX_Tree_Height(tree); hr += LnChoose(n_valid_disks,n_delete_disks); hr -= n_delete_disks * LOG(-T); hr += LnFact(n_delete_disks); new_glnL = PHYREX_Lk(tree); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Delete new_glnL: %f [%f] hr: %f u:%f alpha: %f",new_glnL,cur_glnL,hr,u,alpha); */ if(u > alpha) /* Reject */ { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; For(j,n_delete_disks) PHYREX_Insert_Disk(target_disk[j],tree); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; } } else { For(j,n_delete_disks) Free_Disk(target_disk[j]); tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_disk]++; } Free(valid_disks); Free(target_disk); Free(permut); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Insert_Disk(phydbl hr, int n_insert_disks, phydbl cur_lbda, phydbl cur_mu, phydbl cur_rad, t_tree *tree) { t_dsk *disk,**new_disk,**target_disk; phydbl T,t; phydbl cur_glnL, new_glnL; phydbl u,alpha,ratio; int i,j,n_valid_disks; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_disk]++; if(n_insert_disks == 0) { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); T = PHYREX_Tree_Height(tree); disk = tree->disk->prev; n_valid_disks = 0; do { if(!disk->ldsk) n_valid_disks++; disk = disk->prev; } while(disk && disk->prev); target_disk = (t_dsk **)mCalloc(n_insert_disks,sizeof(t_dsk *)); new_disk = (t_dsk **)mCalloc(n_insert_disks,sizeof(t_dsk *)); For(j,n_insert_disks) { t = Uni()*T; disk = tree->disk->prev; while(disk && disk->time > t) disk = disk->prev; assert(disk->next); target_disk[j] = disk->next; new_disk[j] = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu); PHYREX_Init_Disk_Event(new_disk[j],tree->mmod->n_dim,tree->mmod); new_disk[j]->time = t; PHYREX_Insert_Disk(new_disk[j],tree); For(i,tree->mmod->n_dim) new_disk[j]->centr->lonlat[i] = Uni()*tree->mmod->lim->lonlat[i]; For(i,tree->mmod->n_dim) hr -= LOG(1./tree->mmod->lim->lonlat[i]); } hr -= LnChoose(n_valid_disks+n_insert_disks,n_insert_disks); hr += n_insert_disks * LOG(-T); hr -= LnFact(n_insert_disks); new_glnL = PHYREX_Lk(tree); ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n+ Insert new_glnL: %f [%f] hr: %f u: %f alpha: %f",new_glnL,cur_glnL,hr,u,alpha); */ if(u > alpha) /* Reject */ { tree->mmod->lbda = cur_lbda; tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; /* printf("\nI Reject"); */ For(j,n_insert_disks) { PHYREX_Remove_Disk(new_disk[j]); Free_Disk(new_disk[j]); } if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; } /* printf("\nI Reject %f",tree->mmod->lbda); */ } else { /* printf("\nI Accept %f",tree->mmod->lbda); */ tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_disk]++; } Free(target_disk); Free(new_disk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Update time of disk */ #ifdef PHYREX void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL, hr; phydbl cur_alnL, new_alnL; phydbl *ori_time, new_time; phydbl max, min, log_lbda; t_dsk *disk,**target_disk,**all_disks; int i,block,n_all_disks,n_move_disks,*permut; disk = NULL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; block = 100; all_disks = NULL; log_lbda = tree->mmod->lbda; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; n_all_disks = 0; do { /* if(1) */ if(disk->ldsk && disk->ldsk->n_next > 1) /* Moving disks other than coalescent is pointless */ { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; } disk = disk->prev; } while(disk); if(!n_all_disks) return; n_move_disks = Rand_Int(1,(int)(n_all_disks)); target_disk = (t_dsk **)mCalloc(n_all_disks,sizeof(t_dsk *)); ori_time = (phydbl *)mCalloc(n_all_disks,sizeof(phydbl)); permut = Permutate(n_all_disks); For(i,n_move_disks) { target_disk[i] = all_disks[permut[i]]; ori_time[i] = target_disk[i]->time; if(target_disk[i]->prev) { max = target_disk[i]->next->time; min = target_disk[i]->prev->time; new_time = Uni()*(max - min) + min; } else { phydbl new_plusmin, cur_plusmin; max = target_disk[i]->next->time; cur_plusmin = FABS(ori_time[i] - max); new_plusmin = Rexp(1./cur_plusmin); new_time = max - new_plusmin; hr += LOG(Dexp(cur_plusmin,1./new_plusmin)); hr -= LOG(Dexp(new_plusmin,1./cur_plusmin)); new_glnL -= (log_lbda - FABS(ori_time[i]-max)*tree->mmod->lbda); new_glnL += (log_lbda - FABS(new_time -max)*tree->mmod->lbda); } target_disk[i]->time = new_time; } tree->mmod->c_lnL = new_glnL; if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Move disk new_glnL: %f [%f] hr: %f u:%f alpha: %f",new_alnL,cur_alnL,hr,u,alpha); */ if(u > alpha) /* Reject */ { /* printf("- Reject"); */ For(i,n_move_disks) target_disk[i]->time = ori_time[i]; if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; tree->c_lnL = cur_alnL; } } else { /* printf("- Accept"); */ } Free(target_disk); Free(all_disks); Free(ori_time); Free(permut); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Scale_Times(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL, hr; phydbl cur_alnL, new_alnL; phydbl scale_fact_times; int n_disks; t_dsk *disk; phydbl K; phydbl cur_lbda, new_lbda; disk = NULL; cur_alnL = tree->c_lnL; new_alnL = tree->c_lnL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; K = tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_scale_times]; cur_lbda = tree->mmod->lbda; new_lbda = tree->mmod->lbda; u = Uni(); scale_fact_times = EXP(K*(u-.5)); if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); n_disks = 0; disk = tree->disk->prev; do { disk->time = disk->time * scale_fact_times; n_disks++; disk = disk->prev; } while(disk); /* The Hastings ratio involves (n_disk-2) when considering a uniform distrib for the multiplier, which is not the case here. */ hr += (n_disks)*LOG(scale_fact_times); /* Adjust the value of lambda */ new_lbda = cur_lbda * (1./scale_fact_times); hr += LOG(1./scale_fact_times); tree->mmod->lbda = new_lbda; new_glnL = PHYREX_Lk(tree); if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* PhyML_Printf("\n. Scale times hr: %f new_glnL: %f cur_glnL: %f ratio: %f", */ /* hr, */ /* new_glnL,cur_glnL, */ /* ratio) */ if(u > alpha) /* Reject */ { tree->mmod->lbda = cur_lbda; /* printf("- Reject"); */ disk = tree->disk->prev; do { disk->time /= scale_fact_times; disk = disk->prev; } while(disk); if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); /* Not necessary. Remove once tested */ if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f lbda: %f",new_alnL,cur_alnL,tree->mmod->lbda); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); /* Same here */ if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f lbda: %f",new_glnL,cur_glnL,tree->mmod->lbda); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; tree->c_lnL = cur_alnL; } } else { /* printf("- Accept -> %f",tree->c_lnL); */ tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_scale_times]++; } tree->mcmc->run_move[tree->mcmc->num_move_phyrex_scale_times]++; } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Swap_Disk(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL; phydbl cur_alnL, new_alnL; phydbl hr,t,t_min,t_max,ori_time; t_dsk *disk,*target_disk,*ori_disk_old,*ori_disk_young,**valid_disks; int i,j,block,n_valid_disks; /* For(j,1+(int)(tree->n_otu/5)) */ For(j,1+tree->n_otu) { disk = NULL; target_disk = NULL; ori_disk_old = NULL; ori_disk_young = NULL; valid_disks = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; hr = 0.0; ratio = 0.0; block = 100; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; if(!disk->prev) return; n_valid_disks = 0; do { /* Record disk with a lineage displacement or coalescent that is not the root disk */ if(disk && disk->prev && disk->ldsk && disk->ldsk->n_next >= 1) { if(!n_valid_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_valid_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); valid_disks[n_valid_disks] = disk; n_valid_disks++; } disk = disk->prev; } while(disk && disk->prev); if(n_valid_disks < 2) return; /* Uniform selection of a disk where either a coalescent or a 'hit/displacement' occurred */ i = Rand_Int(0,n_valid_disks-1); target_disk = valid_disks[i]; Free(valid_disks); ori_disk_old = target_disk->prev; ori_disk_young = target_disk->next; ori_time = target_disk->time; t_min = target_disk->ldsk->prev->disk->time; t_max = +INFINITY; For(i,target_disk->ldsk->n_next) if(target_disk->ldsk->next[i]->disk->time < t_max) t_max = target_disk->ldsk->next[i]->disk->time; t_max = t_max - 1.E-10; t_min = t_min + 1.E-10; if(t_max < t_min) return; t = Uni()*(t_max - t_min) + t_min; target_disk->time = t; PHYREX_Remove_Disk(target_disk); PHYREX_Insert_Disk(target_disk,tree); new_glnL = PHYREX_Lk(tree); if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Swap new_glnL: %f [%f] hr: %f u:%f alpha: %f",new_glnL,cur_glnL,hr,u,alpha); */ if(u > alpha) /* Reject */ { /* printf("\n- Reject %f %f",target_disk->time,ori_time); */ PHYREX_Remove_Disk(target_disk); target_disk->time = ori_time; target_disk->prev = ori_disk_old; target_disk->next = ori_disk_young; PHYREX_Insert_Disk(target_disk,tree); if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); /* Remove once checked */ if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); /* Same */ if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; tree->c_lnL = cur_alnL; } } else { /* printf("\n- Accept %f %f",target_disk->time,ori_time); */ } } } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Indel_Hit(t_tree *tree) { int n_disks_cur, n_disks_new; t_dsk *disk; phydbl hr; phydbl cur_rad, new_rad; phydbl cur_mu, new_mu; hr = 0.0; new_rad = tree->mmod->rad; cur_rad = tree->mmod->rad; new_mu = tree->mmod->mu; cur_mu = tree->mmod->mu; /* new_rad = cur_rad * EXP(0.5*(Uni()-.5)); */ /* hr += LOG(new_rad/cur_rad); */ /* new_mu = cur_mu * EXP(0.5*(Uni()-.5)); */ /* hr += LOG(new_mu/cur_mu); */ if(new_rad > tree->mmod->max_rad || new_rad < tree->mmod->min_rad) return; if(new_mu > tree->mmod->max_mu || new_mu < tree->mmod->min_mu) return; tree->mmod->rad = new_rad; tree->mmod->mu = new_mu; disk = tree->disk->prev; n_disks_cur = 0; do { if(disk->ldsk != NULL && disk->ldsk->n_next == 1) n_disks_cur++; disk = disk->prev; } while(disk && disk->prev); n_disks_new = (int)Rpois(n_disks_cur+1); hr += Dpois(n_disks_cur,n_disks_new+1,YES); hr -= Dpois(n_disks_new,n_disks_cur+1,YES); /* K = 0.2; */ /* n_disks_new = (int)Rgamma((phydbl)n_disks_cur/K,K); */ /* hr += LOG(Pgamma(n_disks_cur+1,(phydbl)n_disks_new/K,K) - Pgamma(n_disks_cur,(phydbl)n_disks_new/K,K)); */ /* hr -= LOG(Pgamma(n_disks_new+1,(phydbl)n_disks_cur/K,K) - Pgamma(n_disks_new,(phydbl)n_disks_cur/K,K)); */ if(n_disks_new < n_disks_cur) MCMC_PHYREX_Delete_Hit(hr, n_disks_cur - n_disks_new, cur_rad, cur_mu, tree); else MCMC_PHYREX_Insert_Hit(hr, n_disks_new - n_disks_cur, cur_rad, cur_mu, tree); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Insert a disk with a new lineage displacement */ #ifdef PHYREX void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydbl cur_mu, t_tree *tree) { t_dsk *disk,**new_disk,*young_disk; t_ldsk **young_ldsk, **old_ldsk, **new_ldsk; phydbl T,t; phydbl cur_glnL, new_glnL; phydbl u,alpha,ratio; int i,j,*dir_old_young,n_valid_disks,err; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_hit]++; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; disk = tree->disk->prev; n_valid_disks = 0; do { if(disk->ldsk != NULL && disk->ldsk->n_next == 1) n_valid_disks++; disk = disk->prev; } while(disk && disk->prev); if(n_insert_disks == 0) { tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } new_disk = (t_dsk **)mCalloc(n_insert_disks,sizeof(t_dsk *)); new_ldsk = (t_ldsk **)mCalloc(n_insert_disks,sizeof(t_ldsk *)); old_ldsk = (t_ldsk **)mCalloc(n_insert_disks,sizeof(t_ldsk *)); young_ldsk = (t_ldsk **)mCalloc(n_insert_disks,sizeof(t_ldsk *)); dir_old_young = (int *)mCalloc(n_insert_disks,sizeof(int)); T = PHYREX_Tree_Height(tree); For(j,n_insert_disks) { /* Time of insertion of new disk */ t = Uni()*T; disk = tree->disk; while(disk && disk->time > t) disk = disk->prev; /* Disks located just prior and after inserted disk */ young_disk = disk->next; /* Make and initialize new disk */ new_disk[j] = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu); PHYREX_Init_Disk_Event(new_disk[j],tree->mmod->n_dim,tree->mmod); /* Time of the new disk */ new_disk[j]->time = t; /* Insert it */ PHYREX_Insert_Disk(new_disk[j],tree); assert(young_disk->n_ldsk_a); /* Which lineage is going to be hit ? */ hr += LOG(young_disk->n_ldsk_a); young_ldsk[j] = young_disk->ldsk_a[Rand_Int(0,young_disk->n_ldsk_a-1)]; old_ldsk[j] = young_ldsk[j]->prev; if(old_ldsk[j]->disk->time > young_ldsk[j]->disk->time) { PhyML_Printf("\n== young_ldsk: %f",young_ldsk[j]->disk->time); PhyML_Printf("\n== old_ldsk: %f",old_ldsk[j]->disk->time); assert(FALSE); } /* Direction from old to young ldsk */ dir_old_young[j] = PHYREX_Get_Next_Direction(young_ldsk[j],old_ldsk[j]); assert(dir_old_young[j] != -1); /* Make and initialize new ldsk */ new_ldsk[j] = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim); PHYREX_Init_Lindisk_Node(new_ldsk[j],new_disk[j],tree->mmod->n_dim); PHYREX_Make_Lindisk_Next(new_ldsk[j]); new_disk[j]->ldsk = new_ldsk[j]; /* Connect it */ new_ldsk[j]->prev = old_ldsk[j]; new_ldsk[j]->next[0] = young_ldsk[j]; young_ldsk[j]->prev = new_ldsk[j]; old_ldsk[j]->next[dir_old_young[j]] = new_ldsk[j]; /* PHYREX_Update_Lindisk_List_Core(young_disk); */ /* PHYREX_Update_Lindisk_List_Core(new_disk[j]); */ /* PHYREX_Update_Lindisk_List_Core(old_disk); */ /* Really necessary given that lk function is called afterwards? */ PHYREX_Update_Lindisk_List(tree); /* Sample position of the displaced ldsk */ For(i,tree->mmod->n_dim) { new_ldsk[j]->coord->lonlat[i] = Rnorm_Trunc(0.5*(young_ldsk[j]->coord->lonlat[i]+old_ldsk[j]->coord->lonlat[i]), 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[i],&err); hr -= Log_Dnorm_Trunc(new_ldsk[j]->coord->lonlat[i], 0.5*(young_ldsk[j]->coord->lonlat[i]+old_ldsk[j]->coord->lonlat[i]), 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[i],&err); } /* Sample position of the center of new_disk */ For(i,tree->mmod->n_dim) { new_disk[j]->centr->lonlat[i] = Rnorm_Trunc(new_ldsk[j]->coord->lonlat[i], 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[i],&err); hr -= Log_Dnorm_Trunc(new_disk[j]->centr->lonlat[i], new_ldsk[j]->coord->lonlat[i], 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[i],&err); } } T = PHYREX_Tree_Height(tree); hr -= LnChoose(n_valid_disks+n_insert_disks,n_insert_disks); hr += n_insert_disks * LOG(-T); hr -= LnFact(n_insert_disks); new_glnL = PHYREX_Lk(tree); ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Insert hit %15f %15f %5d",new_glnL - cur_glnL, alpha, n_insert_disks); */ if(u > alpha) /* Reject */ { /* printf("+ Reject"); */ tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; for(j=n_insert_disks-1;j>=0;j--) { PHYREX_Remove_Disk(new_disk[j]); Free_Disk(new_disk[j]); Free_Ldisk(new_ldsk[j]); old_ldsk[j]->next[dir_old_young[j]] = young_ldsk[j]; young_ldsk[j]->prev = old_ldsk[j]; } if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; } } else { /* printf("+ Accept"); */ /* if(indel > 0) printf("\n. Accept"); */ tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit]++; } Free(new_disk); Free(new_ldsk); Free(old_ldsk); Free(young_ldsk); Free(dir_old_young); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Remove one or more disks with a lineage displacement */ #ifdef PHYREX void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydbl cur_mu, t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL,new_glnL,T; t_dsk *disk,**target_disk,**valid_disks; t_ldsk **target_ldsk,**old_ldsk,**young_ldsk; int i,j,block,n_valid_disks,*dir_old_young,*permut,err; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_hit]++; disk = NULL; valid_disks = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; ratio = 0.0; block = 100; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; if(!disk->prev) { tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } n_valid_disks = 0; do { /* Include only disks with displacement that are not coalescent events */ if(disk->ldsk != NULL && disk->ldsk->n_next == 1) { if(!n_valid_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_valid_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); valid_disks[n_valid_disks] = disk; n_valid_disks++; } disk = disk->prev; } while(disk && disk->prev); if(!n_valid_disks) { tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } if(n_valid_disks - n_delete_disks < 0) { tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; return; } target_disk = (t_dsk **)mCalloc(n_delete_disks,sizeof(t_dsk *)); target_ldsk = (t_ldsk **)mCalloc(n_delete_disks,sizeof(t_ldsk *)); old_ldsk = (t_ldsk **)mCalloc(n_delete_disks,sizeof(t_ldsk *)); young_ldsk = (t_ldsk **)mCalloc(n_delete_disks,sizeof(t_ldsk *)); dir_old_young = (int *)mCalloc(n_delete_disks,sizeof(int)); permut = Permutate(n_valid_disks); For(j,n_delete_disks) { target_disk[j] = valid_disks[permut[j]]; target_ldsk[j] = target_disk[j]->ldsk; assert(target_ldsk[j] != NULL); assert(target_ldsk[j]->n_next == 1); old_ldsk[j] = target_ldsk[j]->prev; young_ldsk[j] = target_ldsk[j]->next[0]; dir_old_young[j] = PHYREX_Get_Next_Direction(young_ldsk[j],old_ldsk[j]); assert(dir_old_young[j] != -1); /* Part of the Hastings ratio corresponding to the probability of selecting */ /* one of target_disk->n_ldsk_a to be hit */ hr -= LOG(target_disk[j]->next->n_ldsk_a); /* Density for position of the displaced ldsk */ For(i,tree->mmod->n_dim) { hr += Log_Dnorm_Trunc(target_ldsk[j]->coord->lonlat[i], 0.5*(young_ldsk[j]->coord->lonlat[i]+old_ldsk[j]->coord->lonlat[i]), 1.0*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[i],&err); } /* Density for position of the center of target_disk */ For(i,tree->mmod->n_dim) { hr += Log_Dnorm_Trunc(target_disk[j]->centr->lonlat[i], target_ldsk[j]->coord->lonlat[i], 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[i],&err); } /* New connections between old_ldsk and young_ldsk */ old_ldsk[j]->next[dir_old_young[j]] = young_ldsk[j]; young_ldsk[j]->prev = old_ldsk[j]; /* Remove target disk */ PHYREX_Remove_Disk(target_disk[j]); } T = PHYREX_Tree_Height(tree); hr += LnChoose(n_valid_disks,n_delete_disks); hr -= n_delete_disks * LOG(-T); hr += LnFact(n_delete_disks); Free(valid_disks); new_glnL = PHYREX_Lk(tree); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Delete hit %15f %15f %5d",new_glnL - cur_glnL, alpha, n_delete_disks); */ if(u > alpha) /* Reject */ { tree->mmod->rad = cur_rad; tree->mmod->mu = cur_mu; /* printf("- Reject"); */ for(j=n_delete_disks-1;j>=0;j--) { PHYREX_Insert_Disk(target_disk[j],tree); old_ldsk[j]->next[dir_old_young[j]] = target_ldsk[j]; young_ldsk[j]->prev = target_ldsk[j]; } if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; } } else { /* printf(" ***"); */ For(j,n_delete_disks) Free_Disk(target_disk[j]); For(j,n_delete_disks) Free_Ldisk(target_ldsk[j]); tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit]++; } Free(target_disk); Free(target_ldsk); Free(old_ldsk); Free(young_ldsk); Free(dir_old_young); Free(permut); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Prune_Regraft(t_tree *tree) { phydbl u,alpha,ratio,hr; phydbl cur_glnL, new_glnL; phydbl cur_alnL, new_alnL; t_dsk *disk,*prune_disk,*regraft_disk,**valid_disks,*dum_dum_disk; t_ldsk *prune_ldsk,*regraft_ldsk,*prune_daughter_ldsk,*cur_path,*new_path,*ldsk,*ldsk_dum; phydbl *prob_disks; int i,block,n_valid_disks,prune_next_num,num_prune_disk,n_prune_disks; phydbl rate,dt,sizeT,sum; phydbl max_dist, param_exp; int cur_path_len; int n_hits,n_iter; int cur_pos,new_pos; n_iter = MAX(1,(int)(tree->n_otu/5)); while(n_iter--) { tree->mcmc->run_move[tree->mcmc->num_move_phyrex_spr]++; valid_disks = NULL; disk = NULL; prob_disks = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; hr = 0.0; ratio = 0.0; block = 100; cur_pos = -1; new_pos = -1; num_prune_disk = -1; sizeT = PHYREX_Time_Tree_Length(tree); if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /* Get a ldsk from which you can prune a lineage */ disk = tree->disk->prev; n_prune_disks = 0; do { /* Include only disks with displacement that are coalescent events */ if(disk->ldsk != NULL && disk->ldsk->n_next > 1) { /* Root has degree 2: don't pull any lineage */ if(!(disk->prev == NULL && disk->ldsk->n_next == 2)) { if(!n_prune_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_prune_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_prune_disks+block,sizeof(t_dsk *)); valid_disks[n_prune_disks] = disk; n_prune_disks++; } } disk = disk->prev; } while(disk); if(!n_prune_disks) return; /* Uniform selection of a disk where a coalescent occurred */ i = Rand_Int(0,n_prune_disks-1); prune_disk = valid_disks[i]; Free(valid_disks); hr -= LOG(1./n_prune_disks); prune_ldsk = prune_disk->ldsk; /* Which daughter lineage are we pruning? */ prune_next_num = Rand_Int(0,prune_ldsk->n_next-1); prune_daughter_ldsk = prune_ldsk->next[prune_next_num]; while(prune_daughter_ldsk->n_next < 2 && /* prune_daughter is a coalescent node */ prune_daughter_ldsk->disk->next) prune_daughter_ldsk = prune_daughter_ldsk->next[0]; /* prune_daughter_ldsk has to be the next coalescent node under prune_ldsk for this move to work */ /* Proba of pruning this particular one */ hr -= LOG(1./prune_ldsk->n_next); /* Get a ldsk to reattach the pruned lineage to */ disk = tree->disk->prev; n_valid_disks = 0; do { /* Include only disks with displacement that are not younger than prune_daughter_ldsk */ if((disk->ldsk != NULL) && (disk->ldsk->n_next > 0) && (disk->time < prune_daughter_ldsk->disk->time) && (PHYREX_Is_On_Path(disk->ldsk,prune_daughter_ldsk,prune_ldsk) == NO)) { if(!n_valid_disks) { valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); prob_disks = (phydbl *)mCalloc(block,sizeof(phydbl)); } else if(!(n_valid_disks%block)) { valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); prob_disks = (phydbl *)mRealloc(prob_disks,n_valid_disks+block,sizeof(phydbl)); } valid_disks[n_valid_disks] = disk; prob_disks[n_valid_disks] = PHYREX_Dist_Between_Two_Ldsk(disk->ldsk, prune_daughter_ldsk, tree); if(disk == prune_disk) { num_prune_disk = n_valid_disks; } n_valid_disks++; } disk = disk->prev; } while(disk); if(!n_valid_disks) return; if(n_valid_disks > 1) { max_dist = -INFINITY; For(i,n_valid_disks) if(prob_disks[i] > max_dist) max_dist = prob_disks[i]; sum = 0.0; For(i,n_valid_disks) prob_disks[i] /= max_dist; param_exp = 1.0; For(i,n_valid_disks) prob_disks[i] = Dexp(prob_disks[i],param_exp); sum = 0.0; For(i,n_valid_disks) sum += prob_disks[i]; For(i,n_valid_disks) prob_disks[i] /= sum; i = Sample_i_With_Proba_pi(prob_disks,n_valid_disks); /* Prob of selecting this node as regraft site */ hr -= LOG(prob_disks[i]); assert(num_prune_disk > -1); /* Prob of selecting this node as regraft site (opposite move) */ hr += LOG(prob_disks[num_prune_disk]); } else { i = 0; } Free(prob_disks); /* Uniform selection of a disk among the list of valid ones */ /* i = Rand_Int(0,n_valid_disks-1); */ regraft_disk = valid_disks[i]; Free(valid_disks); regraft_ldsk = regraft_disk->ldsk; dum_dum_disk = (regraft_disk->time < prune_disk->time ? regraft_disk : prune_disk); new_glnL = cur_glnL; new_glnL -= PHYREX_Lk_Range(prune_daughter_ldsk->disk->prev,dum_dum_disk,tree); /* Proba of pruning that particular lineage in the opposite move */ hr += LOG(1./(phydbl)(regraft_ldsk->n_next+1)); /* Prob of selecting that prune ldsk in the opposite move. Number of prune sites increases by one in case actual regraft ldsk (i.e., regraft ldsk in the proposed move) has n_next = 1 */ if(regraft_ldsk->n_next == 1) n_prune_disks += 1; if(prune_ldsk->n_next == 2) n_prune_disks -= 1; hr += LOG(1./n_prune_disks); /* Prune and regraft */ n_hits = PHYREX_Total_Number_Of_Hit_Disks(tree) - PHYREX_Total_Number_Of_Coal_Disks(tree); dt = FABS(prune_daughter_ldsk->disk->time - prune_ldsk->disk->time); cur_path_len = PHYREX_Path_Len(prune_daughter_ldsk,prune_ldsk)-2; rate = (phydbl)(n_hits - cur_path_len)/(sizeT - dt); hr += PHYREX_Path_Logdensity(prune_daughter_ldsk,prune_ldsk,rate*dt,1.0*tree->mmod->rad,tree); dt = FABS(prune_daughter_ldsk->disk->time - regraft_ldsk->disk->time); new_path = PHYREX_Generate_Path(prune_daughter_ldsk,regraft_ldsk,rate*dt,1.0*tree->mmod->rad,tree); cur_path = PHYREX_Remove_Path(prune_daughter_ldsk,prune_ldsk,&cur_pos,tree); PHYREX_Insert_Path(prune_daughter_ldsk,regraft_ldsk,new_path,regraft_ldsk->n_next,tree); hr -= PHYREX_Path_Logdensity(prune_daughter_ldsk,regraft_ldsk,rate*dt,1.0*tree->mmod->rad,tree); /* prune_daughter_ldsk->prev = regraft_ldsk; */ /* PHYREX_Remove_Lindisk_Next(prune_ldsk,prune_daughter_ldsk); */ /* PHYREX_Random_Insert_Ldsk_In_Next_List(prune_daughter_ldsk,regraft_ldsk); */ PHYREX_Ldsk_To_Tree(tree); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); RATES_Fill_Lca_Table(tree); RATES_Update_Cur_Bl(tree); /* new_glnL = PHYREX_Lk(tree); */ new_glnL += PHYREX_Lk_Range(prune_daughter_ldsk->disk->prev,dum_dum_disk,tree); tree->mmod->c_lnL = new_glnL; if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; /* printf("\n. %3d %3d alpha:%12f %3d",prune_ldsk->n_next+1,regraft_ldsk->n_next-1,alpha,new_n_coal); */ u = Uni(); if(u > alpha) /* Reject */ { new_path = PHYREX_Remove_Path(prune_daughter_ldsk,regraft_ldsk,&new_pos,tree); ldsk = new_path; while(ldsk) { Free_Disk(ldsk->disk); ldsk_dum = ldsk; ldsk = ldsk->prev; Free_Ldisk(ldsk_dum); } PHYREX_Insert_Path(prune_daughter_ldsk,prune_ldsk,cur_path,cur_pos,tree); /* prune_daughter_ldsk->prev = prune_ldsk; */ /* PHYREX_Remove_Lindisk_Next(regraft_ldsk,prune_daughter_ldsk); */ /* PHYREX_Insert_Ldsk_In_Next_List(prune_daughter_ldsk,prune_next_num,prune_ldsk); */ PHYREX_Ldsk_To_Tree(tree); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); RATES_Fill_Lca_Table(tree); RATES_Update_Cur_Bl(tree); if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->c_lnL = cur_alnL; tree->mmod->c_lnL = cur_glnL; } } else { ldsk = cur_path; while(ldsk) { Free_Disk(ldsk->disk); ldsk_dum = ldsk; ldsk = ldsk->prev; Free_Ldisk(ldsk_dum); } tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_spr]++; } } } #endif /*////////////////////////////////////////////////////////////l ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Simulate_Backward(t_tree *tree) { phydbl u,alpha,ratio,hr,T,t; phydbl cur_alnL, new_alnL; phydbl cur_glnL, new_glnL; t_dsk *disk,*bkp_disk,*target_disk; t_ldsk **bkp_ldsk; int i; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_sim]++; disk = NULL; bkp_disk = NULL; target_disk = NULL; bkp_ldsk = NULL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; T = 0.0; t = 0.0; /* Chop off the tree at time t and simulate upwards from here */ T = PHYREX_Tree_Height(tree); t = Uni()*T; disk = tree->disk->prev; while(disk && disk->time > t) disk = disk->prev; target_disk = disk->next; hr -= LOG(FABS((target_disk->prev->time - target_disk->time)/T)); bkp_disk = target_disk->prev; bkp_ldsk = (t_ldsk **)mCalloc(target_disk->n_ldsk_a,sizeof(t_ldsk *)); For(i,target_disk->n_ldsk_a) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev; PHYREX_Simulate_Backward_Core(NO,target_disk,tree); T = PHYREX_Tree_Height(tree); hr += LOG(FABS((target_disk->prev->time - target_disk->time)/T)); if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { disk = target_disk->prev; while(disk->prev) { disk = disk->prev; if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk); Free_Disk(disk->next); } /* Root */ Free_Ldisk(disk->ldsk); Free_Disk(disk); target_disk->prev = bkp_disk; For(i,target_disk->n_ldsk_a) target_disk->ldsk_a[i]->prev = bkp_ldsk[i]; if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Lk(tree); tree->c_lnL = cur_alnL; tree->mmod->c_lnL = cur_glnL; } } else { /* Accept */ disk = bkp_disk; while(disk->prev) { disk = disk->prev; if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk); Free_Disk(disk->next); } /* Root */ Free_Ldisk(disk->ldsk); Free_Disk(disk); /* Likelihood needs to be updated */ PHYREX_Lk(tree); tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_sim]++; } Free(bkp_ldsk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree) { phydbl u,alpha,ratio,hr,T,t; phydbl cur_alnL, new_alnL; phydbl cur_glnL_do, new_glnL_do; phydbl cur_glnL, new_glnL; phydbl cur_lbda, new_lbda; phydbl cur_rad, new_rad; phydbl cur_mu, new_mu; t_dsk *disk,*bkp_disk,*target_disk; t_ldsk **bkp_ldsk; int i; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_sim_plus]++; disk = NULL; bkp_disk = NULL; target_disk = NULL; bkp_ldsk = NULL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; cur_glnL_do = UNLIKELY; new_glnL_do = UNLIKELY; hr = 0.0; ratio = 0.0; T = 0.0; t = 0.0; cur_lbda = tree->mmod->lbda; cur_rad = tree->mmod->rad; cur_mu = tree->mmod->mu; new_lbda = cur_lbda; new_rad = cur_rad; new_mu = cur_mu; new_lbda = cur_lbda * EXP(0.2*(Uni()-.5)); hr += LOG(new_lbda/cur_lbda); new_mu = cur_mu * EXP(0.2*(Uni()-.5)); hr += LOG(new_mu/cur_mu); new_rad = cur_rad * EXP(0.2*(Uni()-.5)); hr += LOG(new_rad/cur_rad); if(new_lbda < tree->mmod->min_lbda) return; if(new_lbda > tree->mmod->max_lbda) return; if(new_mu < tree->mmod->min_mu) return; if(new_mu > tree->mmod->max_mu) return; if(new_rad < tree->mmod->min_rad) return; if(new_rad > tree->mmod->max_rad) return; hr += PHYREX_LnPrior_Lbda(tree); hr += PHYREX_LnPrior_Mu(tree); hr += PHYREX_LnPrior_Radius(tree); /* Chop off the tree at time t and simulate upwards from here */ T = PHYREX_Tree_Height(tree); t = Uni()*T; disk = tree->disk->prev; while(disk && disk->time > t) disk = disk->prev; target_disk = disk->next; hr -= LOG(FABS((target_disk->prev->time - target_disk->time)/T)); bkp_disk = target_disk->prev; bkp_ldsk = (t_ldsk **)mCalloc(target_disk->n_ldsk_a,sizeof(t_ldsk *)); For(i,target_disk->n_ldsk_a) bkp_ldsk[i] = target_disk->ldsk_a[i]->prev; cur_glnL_do = PHYREX_Lk_Range(tree->disk->prev,target_disk,tree); tree->mmod->lbda = new_lbda; tree->mmod->mu = new_mu; tree->mmod->rad = new_rad; new_glnL_do = PHYREX_Lk_Range(tree->disk->prev,target_disk,tree); hr -= PHYREX_LnPrior_Lbda(tree); hr -= PHYREX_LnPrior_Mu(tree); hr -= PHYREX_LnPrior_Radius(tree); PHYREX_Simulate_Backward_Core(NO,target_disk,tree); T = PHYREX_Tree_Height(tree); hr += LOG(FABS((target_disk->prev->time - target_disk->time)/T)); if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_alnL - cur_alnL); ratio += (new_glnL_do - cur_glnL_do); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { tree->mmod->lbda = cur_lbda; tree->mmod->mu = cur_mu; tree->mmod->rad = cur_rad; disk = target_disk->prev; while(disk->prev) { disk = disk->prev; if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk); Free_Disk(disk->next); } /* Root */ Free_Ldisk(disk->ldsk); Free_Disk(disk); target_disk->prev = bkp_disk; For(i,target_disk->n_ldsk_a) target_disk->ldsk_a[i]->prev = bkp_ldsk[i]; if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Lk(tree); tree->c_lnL = cur_alnL; } } else { /* Accept */ disk = bkp_disk; while(disk->prev) { disk = disk->prev; if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk); Free_Disk(disk->next); } /* Root */ Free_Ldisk(disk->ldsk); Free_Disk(disk); /* Likelihood needs to be updated */ PHYREX_Lk(tree); tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_sim_plus]++; } Free(bkp_ldsk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Lineage_Traj(t_tree *tree) { phydbl u,alpha,ratio,hr; phydbl cur_glnL, new_glnL; t_dsk *disk,**valid_disks; t_ldsk *start_ldsk,*end_ldsk,*cur_path,*new_path,*ldsk,*ldsk_dum; int j,block,n_valid_disks; phydbl rate,dt,sizeT; int n_hits,n_iter,cur_path_len; int pos,*permut; n_iter = 0; valid_disks = NULL; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; block = 100; pos = -1; /* Get a ldsk from which you can prune a lineage */ disk = tree->disk->prev; n_valid_disks = 0; do { if(disk->ldsk && disk->ldsk->prev && disk->ldsk->n_next > 1) /* if(disk->ldsk) */ { if(!n_valid_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_valid_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); valid_disks[n_valid_disks] = disk; n_valid_disks++; } disk = disk->prev; } while(disk); if(!n_valid_disks) return; permut = Permutate(n_valid_disks); n_iter = Rand_Int(1,1+(int)(n_valid_disks/5)); For(j,n_iter) { tree->mcmc->run_move[tree->mcmc->num_move_phyrex_traj]++; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; start_ldsk = valid_disks[permut[j]]->ldsk; assert(start_ldsk != NULL); end_ldsk = start_ldsk->prev; while(end_ldsk->n_next < 2) end_ldsk = end_ldsk->prev; assert(end_ldsk != NULL); new_glnL = cur_glnL; new_glnL -= PHYREX_Lk_Range(start_ldsk->disk->prev,end_ldsk->disk,tree); n_hits = PHYREX_Total_Number_Of_Hit_Disks(tree) - PHYREX_Total_Number_Of_Coal_Disks(tree); sizeT = PHYREX_Time_Tree_Length(tree); dt = FABS(start_ldsk->disk->time - end_ldsk->disk->time); cur_path_len = PHYREX_Path_Len(start_ldsk,end_ldsk)-2; rate = (phydbl)(n_hits - cur_path_len)/(sizeT - dt); hr += PHYREX_Path_Logdensity(start_ldsk,end_ldsk,rate*dt,1.*tree->mmod->rad,tree); new_path = PHYREX_Generate_Path(start_ldsk,end_ldsk,rate*dt,1.*tree->mmod->rad,tree); cur_path = PHYREX_Remove_Path(start_ldsk,end_ldsk,&pos,tree); PHYREX_Insert_Path(start_ldsk,end_ldsk,new_path,pos,tree); hr -= PHYREX_Path_Logdensity(start_ldsk,end_ldsk,rate*dt,1.*tree->mmod->rad,tree); /* new_glnL = PHYREX_Lk(tree); */ new_glnL += PHYREX_Lk_Range(start_ldsk->disk->prev,end_ldsk->disk,tree); tree->mmod->c_lnL = new_glnL; ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; /* PhyML_Printf("\n= Traj. new_alnL:%12f cur_alnL:%12f hr:%12f alpha:%12f",new_alnL,cur_alnL,hr,alpha); */ u = Uni(); if(u > alpha) /* Reject */ { new_path = PHYREX_Remove_Path(start_ldsk,end_ldsk,&pos,tree); ldsk = new_path; while(ldsk) { Free_Disk(ldsk->disk); ldsk_dum = ldsk; ldsk = ldsk->prev; Free_Ldisk(ldsk_dum); } PHYREX_Insert_Path(start_ldsk,end_ldsk,cur_path,pos,tree); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Update_Lindisk_List(tree); tree->mmod->c_lnL = cur_glnL; } } else { ldsk = cur_path; while(ldsk) { Free_Disk(ldsk->disk); ldsk_dum = ldsk; ldsk = ldsk->prev; Free_Ldisk(ldsk_dum); } tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_traj]++; } } Free(valid_disks); Free(permut); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Lbda_Times(t_tree *tree) { phydbl u,alpha,ratio,hr; phydbl cur_glnL, new_glnL; phydbl cur_alnL, new_alnL; phydbl cur_lbda, new_lbda; phydbl *cur_times,dt; t_dsk *disk; int n_inter,i; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_lbda_times]++; dt = 0.0; hr = 0.0; ratio = 0.0; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; new_alnL = tree->c_lnL; cur_alnL = tree->c_lnL; cur_lbda = tree->mmod->lbda; new_lbda = cur_lbda; n_inter = PHYREX_Total_Number_Of_Intervals(tree); cur_times = (phydbl *)mCalloc(n_inter,sizeof(phydbl)); disk = tree->disk; while(disk->prev != NULL) disk = disk->prev; hr += (n_inter)*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time; new_glnL = cur_glnL; new_glnL -= (n_inter)*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time; new_lbda = cur_lbda * EXP(0.3*(Uni()-.5)); hr += LOG(new_lbda/cur_lbda); tree->mmod->lbda = new_lbda; i = 0; disk = tree->disk->prev; do { cur_times[i++] = disk->time; dt = Rexp(tree->mmod->lbda); disk->time = disk->next->time - dt; disk = disk->prev; } while(disk != NULL); disk = tree->disk; while(disk->prev != NULL) disk = disk->prev; hr -= n_inter*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time; new_glnL += n_inter*LOG(tree->mmod->lbda) + tree->mmod->lbda*disk->time;; tree->mmod->c_lnL = new_glnL; if(tree->mcmc->use_data == YES) new_alnL = Lk(NULL,tree); ratio += (new_glnL - cur_glnL); ratio += (new_alnL - cur_alnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { tree->mmod->lbda = cur_lbda; i = 0; disk = tree->disk->prev; do { disk->time = cur_times[i++]; disk = disk->prev; } while(disk != NULL); if(tree->mmod->safe_phyrex == YES) { if(tree->mcmc->use_data == YES) { new_alnL = Lk(NULL,tree); if(Are_Equal(new_alnL,cur_alnL,1.E-3) == NO) { PhyML_Printf("\n== new_alnL: %f cur_alnL: %f",new_alnL,cur_alnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->c_lnL = cur_alnL; tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_lbda_times]++; } Free(cur_times); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Disk_Multi(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL, hr; t_dsk *disk,**target_disk,**all_disks; int i,j,block,n_all_disks,n_move_disks,*permut; int err; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; block = 100; all_disks = NULL; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_disk_multi]++; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; n_all_disks = 0; do { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; disk = disk->prev; } while(disk); if(!n_all_disks) return; target_disk = (t_dsk **)mCalloc(n_all_disks,sizeof(t_dsk *)); n_move_disks = Rand_Int(1,1+(int)(n_all_disks/5)); /* n_move_disks = n_all_disks; */ permut = Permutate(n_all_disks); For(i,n_move_disks) { target_disk[i] = all_disks[permut[i]]; assert(target_disk[i]); PHYREX_Store_Geo_Coord(target_disk[i]->centr); if(target_disk[i]->ldsk != NULL) { For(j,tree->mmod->n_dim) { target_disk[i]->centr->lonlat[j] = Rnorm_Trunc(target_disk[i]->centr->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); hr -= Log_Dnorm_Trunc(target_disk[i]->centr->lonlat[j], target_disk[i]->centr->cpy->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); hr += Log_Dnorm_Trunc(target_disk[i]->centr->cpy->lonlat[j], target_disk[i]->centr->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); } } else { For(j,tree->mmod->n_dim) { target_disk[i]->centr->lonlat[j] = Rnorm_Trunc(target_disk[i]->centr->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); hr -= Log_Dnorm_Trunc(target_disk[i]->centr->lonlat[j], target_disk[i]->centr->cpy->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); hr += Log_Dnorm_Trunc(target_disk[i]->centr->cpy->lonlat[j], target_disk[i]->centr->lonlat[j], 1.*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); } } } Free(permut); new_glnL = PHYREX_Lk(tree); tree->mmod->c_lnL = new_glnL; ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Delete new_glnL: %f [%f] hr: %f u:%f alpha: %f",new_glnL,cur_glnL,hr,u,alpha); */ if(u > alpha) /* Reject */ { /* printf("- Reject"); */ For(i,n_move_disks) PHYREX_Restore_Geo_Coord(target_disk[i]->centr); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_disk_multi]++; } Free(all_disks); Free(target_disk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Move ldsk on landscape */ #ifdef PHYREX void MCMC_PHYREX_Ldsk_Multi(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL, hr, c, o, f; t_dsk *disk,**target_disk,**all_disks; int i,j,block,n_all_disks,n_move_ldsk,*permut; int err; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; block = 100; all_disks = NULL; o = -1.; c = -1.; f = -1.; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_ldsk_multi]++; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; n_all_disks = 0; do { if(disk->ldsk != NULL) { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; } disk = disk->prev; } while(disk); if(!n_all_disks) return; n_move_ldsk = Rand_Int(1,1+(int)(n_all_disks/5)); /* n_move_ldsk = n_all_disks; */ target_disk = (t_dsk **)mCalloc(n_all_disks,sizeof(t_dsk *)); permut = Permutate(n_all_disks); For(i,n_move_ldsk) { target_disk[i] = all_disks[permut[i]]; PHYREX_Store_Geo_Coord(target_disk[i]->ldsk->coord); For(j,tree->mmod->n_dim) { /* c: center; o: pos of direct ldsk ancestor */ c = target_disk[i]->centr->lonlat[j]; o = target_disk[i]->ldsk->prev ? target_disk[i]->ldsk->prev->coord->lonlat[j] : target_disk[i]->centr->lonlat[j]; f = target_disk[i]->ldsk->prev ? (2./3.) : (1.0); target_disk[i]->ldsk->coord->lonlat[j] = Rnorm_Trunc((o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); For(j,tree->mmod->n_dim) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j], (o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); For(j,tree->mmod->n_dim) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j], (o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); } } Free(permut); new_glnL = PHYREX_Lk(tree); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Move_ldsk %15f",new_glnL-cur_glnL); */ if(u > alpha) /* Reject */ { /* printf("- Reject"); */ For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_ldsk_multi]++; } Free(all_disks); Free(target_disk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree) { phydbl u,alpha,ratio; phydbl cur_glnL, new_glnL, hr; t_dsk *disk,**target_disk,**all_disks; int i,j,block,n_all_disks,n_move_ldsk,*permut; int err; phydbl cur_rad, new_rad; disk = NULL; new_glnL = tree->mmod->c_lnL; cur_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; block = 100; all_disks = NULL; cur_rad = tree->mmod->rad; new_rad = tree->mmod->rad; tree->mcmc->run_move[tree->mcmc->num_move_phyrex_ldsk_and_disk]++; new_rad = cur_rad * EXP(0.2*(Uni()-.5)); hr += LOG(new_rad/cur_rad); if(new_rad > tree->mmod->max_rad) return; if(new_rad < tree->mmod->min_rad) return; tree->mmod->rad = new_rad; if(tree->disk->next) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); disk = tree->disk->prev; n_all_disks = 0; do { if(disk->ldsk != NULL && disk->ldsk->n_next >= 1) { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; } disk = disk->prev; } while(disk); if(!n_all_disks) return; n_move_ldsk = Rand_Int(1,1+(int)(n_all_disks/5)); /* n_move_ldsk = n_all_disks; */ target_disk = (t_dsk **)mCalloc(n_all_disks,sizeof(t_dsk *)); permut = Permutate(n_all_disks); For(i,n_move_ldsk) { target_disk[i] = all_disks[permut[i]]; PHYREX_Store_Geo_Coord(target_disk[i]->ldsk->coord); For(j,tree->mmod->n_dim) target_disk[i]->ldsk->coord->lonlat[j] = Rnorm_Trunc(target_disk[i]->centr->lonlat[j], 1.*new_rad, 0.0, tree->mmod->lim->lonlat[j],&err); For(j,tree->mmod->n_dim) hr -= Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->lonlat[j], target_disk[i]->centr->lonlat[j], 1.*new_rad, 0.0, tree->mmod->lim->lonlat[j],&err); For(j,tree->mmod->n_dim) hr += Log_Dnorm_Trunc(target_disk[i]->ldsk->coord->cpy->lonlat[j], target_disk[i]->centr->lonlat[j], 1.*cur_rad, 0.0, tree->mmod->lim->lonlat[j],&err); } Free(permut); new_glnL = PHYREX_Lk(tree); ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); /* printf("\n- Move_ldsk %15f",new_glnL-cur_glnL); */ if(u > alpha) /* Reject */ { /* printf("- Reject"); */ tree->mmod->rad = cur_rad; For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->ldsk->coord); /* For(i,n_move_ldsk) PHYREX_Restore_Geo_Coord(target_disk[i]->centr); */ if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_ldsk_and_disk]++; } Free(all_disks); Free(target_disk); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree) { phydbl u,alpha,ratio,hr,o,c,f; phydbl cur_glnL, new_glnL; t_dsk *disk,**all_disks; int i,j,err,n_all_disks,block,n_move_ldsk,*permut; block = 100; all_disks = NULL; n_all_disks = 0; o = -1.; c = -1.; f = -1.; disk = tree->disk->prev; do { if(disk->ldsk != NULL) { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; } disk = disk->prev; } while(disk); if(!n_all_disks) return; /* n_move_ldsk = Rand_Int(1,1+(int)(n_all_disks/5)); */ n_move_ldsk = n_all_disks; permut = Permutate(n_all_disks); For(i,n_move_ldsk) { tree->mcmc->run_move[tree->mcmc->num_move_phyrex_ldsk_given_disk]++; disk = all_disks[permut[i]]; hr = 0.0; ratio = 0.0; cur_glnL = tree->mmod->c_lnL; new_glnL = cur_glnL; new_glnL -= PHYREX_Lk_Range(disk,disk->ldsk->prev ? disk->ldsk->prev->disk : NULL,tree); PHYREX_Store_Geo_Coord(disk->ldsk->coord); For(j,tree->mmod->n_dim) { /* c: center; o: pos of direct ldsk ancestor */ c = disk->centr->lonlat[j]; o = disk->ldsk->prev ? disk->ldsk->prev->coord->lonlat[j] : disk->centr->lonlat[j]; f = disk->ldsk->prev ? (2./3.) : (1.0); disk->ldsk->coord->lonlat[j] = Rnorm_Trunc((o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); hr -= Log_Dnorm_Trunc(disk->ldsk->coord->lonlat[j], (o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); hr += Log_Dnorm_Trunc(disk->ldsk->coord->cpy->lonlat[j], (o+2.*c)/3., 1.*SQRT(f*tree->mmod->rad*tree->mmod->rad), 0.0, tree->mmod->lim->lonlat[j],&err); } new_glnL += PHYREX_Lk_Range(disk,disk->ldsk->prev ? disk->ldsk->prev->disk : NULL,tree); tree->mmod->c_lnL = new_glnL; ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Restore_Geo_Coord(disk->ldsk->coord); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n. disk->ldsk->prev: %p",disk->ldsk->prev); PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_ldsk_given_disk]++; } } Free(permut); Free(all_disks); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree) { phydbl u,alpha,ratio,hr; phydbl cur_glnL, new_glnL; t_dsk *disk,**all_disks; int i,j,n_all_disks,block,n_move_ldsk,*permut; block = 100; all_disks = NULL; n_all_disks = 0; disk = tree->disk->prev; do { if(TRUE) { if(!n_all_disks) all_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_all_disks%block)) all_disks = (t_dsk **)mRealloc(all_disks,n_all_disks+block,sizeof(t_dsk *)); all_disks[n_all_disks] = disk; n_all_disks++; } disk = disk->prev; } while(disk); if(!n_all_disks) return; /* n_move_ldsk = Rand_Int(1,1+(int)(n_all_disks/10)); */ n_move_ldsk = n_all_disks; permut = Permutate(n_all_disks); For(i,n_move_ldsk) { tree->mcmc->run_move[tree->mcmc->num_move_phyrex_disk_given_ldsk]++; disk = all_disks[permut[i]]; hr = 0.0; ratio = 0.0; cur_glnL = tree->mmod->c_lnL; new_glnL = cur_glnL; if(disk->ldsk != NULL) new_glnL -= PHYREX_Lk_Range(disk,disk->ldsk->prev ? disk->ldsk->prev->disk : NULL,tree); else new_glnL -= PHYREX_Lk_Range(disk,disk->prev,tree); PHYREX_Store_Geo_Coord(disk->centr); For(j,tree->mmod->n_dim) disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j]; if(disk->ldsk != NULL) new_glnL += PHYREX_Lk_Range(disk,disk->ldsk->prev ? disk->ldsk->prev->disk : NULL,tree); else new_glnL += PHYREX_Lk_Range(disk,disk->prev,tree); tree->mmod->c_lnL = new_glnL; ratio += (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Restore_Geo_Coord(disk->centr); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== disk->ldsk->prev: %p",disk->ldsk->prev); PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_disk_given_ldsk]++; } } Free(permut); Free(all_disks); } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree) { t_dsk *disk,*new_disk,*target_disk,*young_disk; t_ldsk *young_ldsk, *old_ldsk, *new_ldsk; int i,j,n_trials,dir_old_young,err; phydbl ratio, u, alpha, hr, type; phydbl cur_glnL, new_glnL; phydbl log_one_on_T; phydbl T,t,pindel; cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; type = -1.0; n_trials = (int)(PHYREX_Total_Number_Of_Hit_Disks(tree)/10); T = PHYREX_Tree_Height(tree); log_one_on_T = -LOG(FABS(T)); pindel = 0.5; disk = tree->disk->prev; For(i,n_trials) { tree->mcmc->run_move[tree->mcmc->num_move_phyrex_indel_hit_serial]++; t = Uni()*T; disk = tree->disk->prev; while(disk && disk->time > t) disk = disk->prev; assert(disk->next); cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; type = Uni(); if(type < pindel) /* Insert */ { hr += LOG(FABS((t - disk->next->time)/T)); hr -= log_one_on_T; young_disk = disk->next; assert(young_disk->n_ldsk_a); /* Which lineage is going to be hit ? */ hr -= LOG(1./young_disk->n_ldsk_a); new_disk = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu); PHYREX_Init_Disk_Event(new_disk,tree->mmod->n_dim,tree->mmod); new_disk->time = t; young_ldsk = young_disk->ldsk_a[Rand_Int(0,young_disk->n_ldsk_a-1)]; old_ldsk = young_ldsk->prev; if(old_ldsk->disk->time > young_ldsk->disk->time) { PhyML_Printf("\n== young_ldsk: %f",young_ldsk->disk->time); PhyML_Printf("\n== old_ldsk: %f",old_ldsk->disk->time); assert(FALSE); } new_glnL -= PHYREX_Lk_Range(young_disk->prev,old_ldsk->disk,tree); /* new_glnL -= PHYREX_Lk_Range(tree->disk->prev,NULL,tree); */ /* Direction from old to young ldsk */ dir_old_young = PHYREX_Get_Next_Direction(young_ldsk,old_ldsk); assert(dir_old_young != -1); /* Make and initialize new ldsk */ new_ldsk = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim); PHYREX_Init_Lindisk_Node(new_ldsk,new_disk,tree->mmod->n_dim); PHYREX_Make_Lindisk_Next(new_ldsk); new_disk->ldsk = new_ldsk; /* Connect it */ new_ldsk->prev = old_ldsk; new_ldsk->next[0] = young_ldsk; young_ldsk->prev = new_ldsk; old_ldsk->next[dir_old_young] = new_ldsk; /* Insert disk */ PHYREX_Insert_Disk(new_disk,tree); For(j,tree->mmod->n_dim) { new_ldsk->coord->lonlat[j] = Rnorm_Trunc(0.5*(young_ldsk->coord->lonlat[j]+old_ldsk->coord->lonlat[j]), 1.*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[j],&err); hr -= Log_Dnorm_Trunc(new_ldsk->coord->lonlat[j], 0.5*(young_ldsk->coord->lonlat[j]+old_ldsk->coord->lonlat[j]), 1.*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[j],&err); } /* Sample position of the center of new_disk */ For(j,tree->mmod->n_dim) { new_disk->centr->lonlat[j] = Rnorm_Trunc(new_ldsk->coord->lonlat[j], 1.*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[j],&err); hr -= Log_Dnorm_Trunc(new_disk->centr->lonlat[j], new_ldsk->coord->lonlat[j], 1.*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[j],&err); } new_glnL += PHYREX_Lk_Range(young_disk->prev,old_ldsk->disk,tree); tree->mmod->c_lnL = new_glnL; ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Remove_Disk(new_disk); Free_Disk(new_disk); Free_Ldisk(new_ldsk); old_ldsk->next[dir_old_young] = young_ldsk; young_ldsk->prev = old_ldsk; if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Lk_Range(young_disk->prev,old_ldsk->disk,tree); tree->mmod->c_lnL = cur_glnL; } } else { tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit_serial]++; } } else /* Remove disk */ { if(disk->ldsk == NULL || (disk->ldsk != NULL && disk->ldsk->n_next > 1)) continue; target_disk = disk; old_ldsk = target_disk->ldsk->prev; young_ldsk = target_disk->ldsk->next[0]; dir_old_young = PHYREX_Get_Next_Direction(young_ldsk,old_ldsk); assert(dir_old_young != -1); /* Part of the Hastings ratio corresponding to the probability of selecting */ /* one of disk->n_ldsk_a to be hit */ hr += LOG(1./target_disk->next->n_ldsk_a); /* Density for position of the displaced ldsk */ For(j,tree->mmod->n_dim) { hr += Log_Dnorm_Trunc(target_disk->ldsk->coord->lonlat[j], 0.5*(young_ldsk->coord->lonlat[j]+old_ldsk->coord->lonlat[j]), 1.0*tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); } /* Density for position of the center of target_disk */ For(j,tree->mmod->n_dim) { hr += Log_Dnorm_Trunc(target_disk->centr->lonlat[j], target_disk->ldsk->coord->lonlat[j], 1.0*tree->mmod->rad, 0.0,tree->mmod->lim->lonlat[j],&err); } new_glnL -= PHYREX_Lk_Range(target_disk,target_disk->ldsk->prev->disk,tree); /* new_glnL -= PHYREX_Lk_Range(tree->disk->prev,NULL,tree); */ /* New connections between old_ldsk and young_ldsk */ old_ldsk->next[dir_old_young] = young_ldsk; young_ldsk->prev = old_ldsk; hr -= LOG(FABS((target_disk->time - target_disk->next->time)/T)); hr += log_one_on_T; PHYREX_Remove_Disk(target_disk); new_glnL += PHYREX_Lk_Range(target_disk->prev,target_disk->ldsk->prev->disk,tree); tree->mmod->c_lnL = new_glnL; ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Insert_Disk(target_disk,tree); old_ldsk->next[dir_old_young] = target_disk->ldsk; young_ldsk->prev = target_disk->ldsk; if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { PHYREX_Lk_Range(target_disk->prev,target_disk->ldsk->prev->disk,tree); tree->mmod->c_lnL = cur_glnL; } } else { Free_Disk(disk); Free_Ldisk(disk->ldsk); tree->mcmc->acc_move[tree->mcmc->num_move_phyrex_indel_hit_serial]++; } } } } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ #ifdef PHYREX void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree) { t_dsk *disk,*new_disk; int i,j,n_trials; phydbl ratio, u, alpha, hr, type; phydbl cur_glnL, new_glnL; phydbl log_lk_centr,log_one_on_T; phydbl T,t,pindel; cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; type = -1.0; n_trials = (int)(PHYREX_Total_Number_Of_Intervals(tree)/2); T = PHYREX_Tree_Height(tree); log_one_on_T = -LOG(FABS(T)); pindel = 0.5; log_lk_centr = 0.0; For(j,tree->mmod->n_dim) log_lk_centr += LOG(1./tree->mmod->lim->lonlat[j]); disk = tree->disk->prev; For(i,n_trials) /* do */ { t = Uni()*T; disk = tree->disk->prev; while(disk && disk->time > t) disk = disk->prev; assert(disk->next); /* prev_disk = disk->prev; */ cur_glnL = tree->mmod->c_lnL; new_glnL = tree->mmod->c_lnL; hr = 0.0; ratio = 0.0; type = Uni(); if(type < pindel) /* Insert */ { hr += LOG(FABS((t - disk->next->time)/T)); hr -= log_one_on_T; hr -= log_lk_centr; new_glnL -= PHYREX_Lk_Range(disk,disk,tree); new_disk = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu); PHYREX_Init_Disk_Event(new_disk,tree->mmod->n_dim,tree->mmod); new_disk->time = t; PHYREX_Insert_Disk(new_disk,tree); For(j,tree->mmod->n_dim) new_disk->centr->lonlat[j] = Uni()*tree->mmod->lim->lonlat[j]; new_glnL += PHYREX_Lk_Range(new_disk,disk,tree); tree->mmod->c_lnL = new_glnL; /* new_glnL = PHYREX_Lk(tree); */ ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Remove_Disk(new_disk); Free_Disk(new_disk); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } } else /* Remove disk */ { if(disk->ldsk != NULL) continue; /* Reject */ hr -= LOG(FABS((disk->time - disk->next->time)/T)); hr += log_one_on_T; hr += log_lk_centr; new_glnL -= PHYREX_Lk_Range(disk,disk->prev,tree); PHYREX_Remove_Disk(disk); new_glnL += PHYREX_Lk_Range(disk->prev,disk->prev,tree); tree->mmod->c_lnL = new_glnL; ratio = (new_glnL - cur_glnL); ratio += hr; ratio = EXP(ratio); alpha = MIN(1.,ratio); /* Always accept move */ if(tree->mcmc->always_yes == YES && new_glnL > UNLIKELY) alpha = 1.0; u = Uni(); if(u > alpha) /* Reject */ { PHYREX_Insert_Disk(disk,tree); if(tree->mmod->safe_phyrex == YES) { new_glnL = PHYREX_Lk(tree); if(Are_Equal(new_glnL,cur_glnL,1.E-3) == NO) { PhyML_Printf("\n== new_glnL: %f cur_glnL: %f",new_glnL,cur_glnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else { tree->mmod->c_lnL = cur_glnL; } } else { Free_Disk(disk); } } /* disk = prev_disk; */ } /* while(disk->prev); */ } #endif /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phyml-3.2.0/src/mcmc.h000066400000000000000000000170241263450375500145420ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef MCMC_H #define MCMC_H #include "spr.h" #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "times.h" #include "m4.h" #include "draw.h" #include "rates.h" #include "stats.h" #include "phyrex.h" #include #include #include #include void MCMC_Lexp(t_tree *tree); void MCMC_Print_Param(t_mcmc *mcmc, t_tree *tree); t_mcmc *MCMC_Make_MCMC_Struct(); void MCMC_Free_MCMC(t_mcmc *mcmc); void MCMC(t_tree *tree); void MCMC_Alpha(t_tree *tree); void MCMC_Randomize_Branch_Lengths(t_tree *tree); void MCMC_Randomize_Node_Times(t_tree *tree); void MCMC_Randomize_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree); void MCMC_Randomize_Lexp(t_tree *tree); void MCMC_Randomize_Jumps(t_tree *tree); void MCMC_Randomize_Alpha(t_tree *tree); void MCMC_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree); void MCMC_No_Change(t_tree *tree); void MCMC_Nu(t_tree *tree); void MCMC_Randomize_Nu(t_tree *tree); t_node *MCMC_Select_Random_Node_Pair(phydbl t_sup, t_tree *tree); void MCMC_Modify_Rates(t_tree *tree); void MCMC_Modify_Subtree_Rate(t_node *a, t_node *d, phydbl new_rate, t_tree *tree); void MCMC_Randomize_Rates(t_tree *tree); void MCMC_Stick_Rates(t_tree *tree); void MCMC_Stick_Rates_Pre(t_node *a, t_node *d, t_tree *tree); void MCMC_Times_Global(t_tree *tree); void MCMC_Times_Local(t_tree *tree); void MCMC_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree); void MCMC_Rates_Global(t_tree *tree); void MCMC_Rates_Local(t_tree *tree); void MCMC_Rates_Pre(t_node *a, t_node *d, t_tree *tree); void MCMC_Mixing_Step(t_tree *tree); void MCMC_Jumps_Local(t_tree *tree); void MCMC_Jumps_Pre(t_node *a, t_node *d, int local, t_tree *tree); void MCMC_Randomize_Clock_Rate(t_tree *tree); void MCMC_Clock_Rate(t_tree *tree); void MCMC_Time_Root(t_tree *tree); void MCMC_Randomize_Node_Times_Bottom_Up(t_node *a, t_node *d, t_tree *tree); void MCMC_Randomize_Node_Times_Top_Down(t_node *a, t_node *d, t_tree *tree); void MCMC_Randomize_Rates_Pre(t_node *a, t_node *d, t_tree *tree); void MCMC_Print_Means(t_mcmc *mcmc, t_tree *tree); void MCMC_Print_Last(t_mcmc *mcmc, t_tree *tree); void MCMC_Close_MCMC(t_mcmc *mcmc); void MCMC_Rates_Global(t_tree *tree); void MCMC_Omega(t_tree *tree); void MCMC_Adjust_Tuning_Parameter(int move, t_mcmc *mcmc); void MCMC_Copy_MCMC_Struct(t_mcmc *ori, t_mcmc *cpy, char *filename); void MCMC_Randomize_Node_Times_Bottom_Up(t_node *a, t_node *d, t_tree *tree); void MCMC_One_Length(t_edge *b, t_tree *tree); void MCMC_Br_Lens(t_tree *tree); void MCMC_Br_Lens_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void MCMC_Tree_Height(t_tree *tree); void MCMC_Subtree_Height(t_tree *tree); void MCMC_Swing(t_tree *tree); void MCMC_Single_Param_Generic(phydbl *val, phydbl lim_inf, phydbl lim_sup, int move_num, phydbl *lnPrior, phydbl *lnLike, phydbl (*prior_func)(t_edge *,t_tree *,supert_tree *), phydbl (*like_func)(t_edge *,t_tree *,supert_tree *), int move_type, int _log, t_edge *branch, t_tree *tree, supert_tree *stree); void MCMC_Scale_Br_Lens(t_tree *tree); void MCMC_Update_Mean_Br_Len(t_tree *tree); void MCMC_Update_Cov_Br_Len(t_tree *tree); void MCMC_Sim_Rate(t_node *a, t_node *d, t_tree *tree); void Fill_All_Param(t_mcmc *mcmc, t_rate *rate, t_tree *tree); int Get_Param_Num(t_mcmc *mcmc, phydbl *param); void MCMC_Complete_MCMC(t_mcmc *mcmc, t_tree *tree); void MCMC_Sample_Joint_Rates_Prior(t_tree *tree); void MCMC_Sample_Joint_Rates_Posterior(t_tree *tree); void MCMC_Pair_Rates_Constraint(t_node *a, t_node *d, int random, int traversal, t_tree *tree); void MCMC_Times_And_Rates(t_node *a, t_node *d, int random, int traversal, t_tree *tree); void MCMC_Tree_Rates(t_tree *tree); void MCMC_Pause(t_mcmc *mcmc); void MCMC_Print_Param_Stdin(t_mcmc *mcmc, t_tree *tree); void MCMC_Subtree_Rates(t_tree *tree); void MCMC_Get_Acc_Rates(t_mcmc *mcmc); void MCMC_Update_Effective_Sample_Size(int move_num, t_mcmc *mcmc, t_tree *tree); void MCMC_Initialize_Param_Val(t_mcmc *mcmc, t_tree *tree); void MCMC_Terminate(); void MCMC_Copy_To_New_Param_Val(t_mcmc *mcmc, t_tree *tree); void MCMC_Randomize_Node_Rates(t_tree *tree); void MCMC_One_Node_Rate(t_node *a, t_node *d, int traversal, t_tree *tree); void MCMC_Tree_Rates_Bis(t_tree *tree); void MCMC_Slice_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree); void MCMC_Updown_Nu_Cr(t_tree *tree); void MCMC_All_Rates(t_tree *tree); void MCMC_Alpha(t_tree *tree); void MCMC_Kappa(t_tree *tree); void MCMC_Rate_Across_Sites(t_tree *tree); void MCMC_Free_Mixt_Rate(t_tree *tree); void MCMC_Make_Move(phydbl *cur, phydbl *new, phydbl inf, phydbl sup, phydbl *loghr, phydbl tune, int move_type); void MCMC_Randomize_Rate_Across_Sites(t_tree *tree); void MCMC_Randomize_Kappa(t_tree *tree); void MCMC_Updown_T_Cr(t_tree *tree); void MCMC_Linreg_Par(t_tree *tree); void MCMC_Covarion_Rates(t_tree *tree); void MCMC_Covarion_Switch(t_tree *tree); void MCMC_Randomize_Covarion_Rates(t_tree *tree); void MCMC_Randomize_Covarion_Switch(t_tree *tree); void MCMC_Read_Param_Vals(t_tree *tree); void MCMC_Birth_Rate(t_tree *tree); void MCMC_Randomize_Birth(t_tree *tree); void MCMC_Clock_R(t_tree *mixt_tree); void MCMC_Free_MCMC(t_mcmc *mcmc); void MCMC_Updown_T_Br(t_tree *tree); void MCMC_Root_Time(t_tree *tree); void MCMC_Jump_Calibration(t_tree *tree); void MCMC_GEO_Lbda(t_tree *mixt_tree); void MCMC_GEO_Sigma(t_tree *mixt_tree); void MCMC_GEO_Tau(t_tree *mixt_tree); void MCMC_GEO_Loc(t_tree *tree); void MCMC_GEO_Dum(t_tree *mixt_tree); void MCMC_PHYREX_Lbda(t_tree *mixt_tree); void MCMC_PHYREX_Mu(t_tree *mixt_tree); void MCMC_PHYREX_Radius(t_tree *mixt_tree); void MCMC_PHYREX_Triplet(t_tree *tree); void MCMC_PHYREX_Move_Disk_Updown(t_tree *tree); void MCMC_PHYREX_Swap_Disk(t_tree *tree); void MCMC_PHYREX_Prune_Regraft(t_tree *tree); void MCMC_PHYREX_Scale_Times(t_tree *tree); void MCMC_PHYREX_Ldscape_Limits(t_tree *tree); void MCMC_PHYREX_Indel_Disk(t_tree *tree); void MCMC_PHYREX_Delete_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phydbl cur_mu, phydbl cur_rad, t_tree *tree); void MCMC_PHYREX_Insert_Disk(phydbl hr, int n_delete_disks, phydbl cur_lbda, phydbl cur_mu, phydbl cur_rad, t_tree *tree); void MCMC_PHYREX_Indel_Hit(t_tree *tree); void MCMC_PHYREX_Insert_Hit(phydbl hr, int n_insert_disks, phydbl cur_rad, phydbl cur_mu, t_tree *tree); void MCMC_PHYREX_Delete_Hit(phydbl hr, int n_delete_disks, phydbl cur_rad, phydbl cur_mu, t_tree *tree); void MCMC_PHYREX_Simulate_Backward(t_tree *tree); void MCMC_Update_Mode(int move_num, t_mcmc *mcmc, t_tree *tree); void MCMC_PHYREX_Lineage_Traj(t_tree *tree); void MCMC_PHYREX_Lbda_Times(t_tree *tree); void MCMC_PHYREX_Delete_Disk_Serial(t_tree *tree); void MCMC_PHYREX_Insert_Disk_Serial(t_tree *tree); void MCMC_PHYREX_Indel_Disk_Serial(t_tree *tree); void MCMC_PHYREX_Simulate_Backward_Plus(t_tree *tree); void MCMC_PHYREX_Indel_Hit_Serial(t_tree *tree); void MCMC_PHYREX_Disk_Multi(t_tree *tree); void MCMC_PHYREX_Ldsk_Multi(t_tree *tree); void MCMC_PHYREX_Ldsk_Given_Disk(t_tree *tree); void MCMC_PHYREX_Disk_Given_Ldsk(t_tree *tree); void MCMC_PHYREX_Ldsk_And_Disk(t_tree *tree); #endif phyml-3.2.0/src/mg.c000066400000000000000000002341721263450375500142260ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #include "mg.h" #include "free.h" #include "help.h" #include "utilities.h" #include "optimiz.h" #include "models.h" #include "simu.h" #include "lk.h" #include "pars.h" #include "interface.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_main(int argc, char **argv) { option *io; char *s_tree; FILE *fp_phyml_tree,*fp_phyml_stats,*fp_phyml_lk; int part; time_t t_beg,t_end; div_t hour,min; int r_seed; int i; fflush(NULL); io = (option *)Get_Input(argc,argv); r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed); srand(r_seed); fp_phyml_stats = Openfile(io->out_stats_file,io->out_stats_file_open_mode); PhyML_Fprintf(fp_phyml_stats,"\n- PHYML %s -\n\n", VERSION); fp_phyml_tree = Openfile(io->out_tree_file,io->out_tree_file_open_mode); fp_phyml_lk = fopen(io->out_lk_file,"w"); time(&t_beg); if(io->multigene) { align ***data; calign **cdata; t_mod **mod; matrix **mat; t_treelist *treelist; supert_tree *st; data = (align ***) mCalloc(io->n_part,sizeof(align **)); cdata = (calign **)mCalloc(io->n_part,sizeof(calign *)); mod = (t_mod **) mCalloc(io->n_part,sizeof(t_mod *)); mat = (matrix **)mCalloc(io->n_part,sizeof(matrix *)); /* Read the sequences (for each partition) */ For(part,io->n_part) { Make_Model_Complete(io->st->optionlist[part]->mod); /* Complete model for each data part */ data[part] = Get_Seq(io->st->optionlist[part]); Make_Model_Complete(io->st->optionlist[part]->mod); Set_Model_Name(io->st->optionlist[part]->mod); mod[part] = io->st->optionlist[part]->mod; PhyML_Printf("\n. Data part [#%d]\n",part+1); PhyML_Printf("\n. Compressing sequences...\n"); cdata[part] = Compact_Data(data[part],io->st->optionlist[part]); fclose(io->st->optionlist[part]->fp_in_align); Free_Seq(data[part],cdata[part]->n_otu); Init_Model(cdata[part],mod[part],io->st->optionlist[part]); Check_Ambiguities(cdata[part], io->st->optionlist[part]->mod->io->datatype, io->st->optionlist[part]->mod->io->state_len); } PART_Make_Supert_tree_Full(io->st,io,cdata); st = io->st; treelist = st->treelist; Fill_Dir_Table(st->tree); Update_Dirs(st->tree); For(part,io->n_part) { st->curr_cdata = cdata[part]; if(!PART_Get_Species_Found_In_St(st,cdata[part])) break; treelist->tree[part] = Make_Tree_From_Scratch(st->tree->n_otu,NULL); Copy_Tree_Topology_With_Labels(st->tree,treelist->tree[part]); treelist->tree[part]->num_curr_branch_available = 0; Connect_Edges_To_Nodes_Recur(treelist->tree[part]->a_nodes[0], treelist->tree[part]->a_nodes[0]->v[0], treelist->tree[part]); PART_Prune_St_Topo(treelist->tree[part],cdata[part],st); if(treelist->tree[part]->n_otu != cdata[part]->n_otu) { PhyML_Printf("\n. Problem with sequence file '%s'\n",io->st->optionlist[part]->in_align_file); PhyML_Printf("\n. # taxa found in supertree restricted to '%s' taxa = %d\n", io->st->optionlist[part]->in_align_file, treelist->tree[part]->n_otu); PhyML_Printf("\n. # sequences in '%s' = %d\n", io->st->optionlist[part]->in_align_file, cdata[part]->n_otu); Exit("\n"); } treelist->tree[part]->dp = part; treelist->tree[part]->n_otu = cdata[part]->n_otu; treelist->tree[part]->mod = mod[part]; treelist->tree[part]->io = io->st->optionlist[part]; treelist->tree[part]->data = cdata[part]; treelist->tree[part]->n_pattern = treelist->tree[part]->data->crunch_len/ treelist->tree[part]->io->state_len; Set_Both_Sides(YES,treelist->tree[part]); Connect_CSeqs_To_Nodes(cdata[part],io->st->optionlist[part],treelist->tree[part]); Fill_Dir_Table(treelist->tree[part]); Update_Dirs(treelist->tree[part]); Make_Tree_4_Lk(treelist->tree[part],cdata[part],cdata[part]->init_len); Make_Tree_4_Pars(treelist->tree[part],cdata[part],cdata[part]->init_len); treelist->tree[part]->triplet_struct = Make_Triplet_Struct(treelist->tree[part]->mod); Init_Triplet_Struct(treelist->tree[part]->triplet_struct); } if(part != io->n_part) { PhyML_Printf("\n. Sequence data part found in '%s' has one or more taxa not found in the '%s' tree file\n", io->st->optionlist[part]->in_align_file, io->in_tree_file); Exit("\n"); } PART_Check_Extra_Taxa(st); st->tree->c_lnL = .0; For(part,io->n_part) { Lk(NULL,treelist->tree[part]); /* Get_List_Of_Reachable_Tips(treelist->tree[part]); */ PART_Match_St_Nodes_In_Gt(treelist->tree[part],st); PART_Match_St_Edges_In_Gt(treelist->tree[part],st); PART_Map_St_Nodes_In_Gt(treelist->tree[part],st); PART_Map_St_Edges_In_Gt(treelist->tree[part],st); PART_Map_Gt_Edges_In_St(treelist->tree[part],st); st->tree->c_lnL += treelist->tree[part]->c_lnL; } PART_Initialise_Bl_Partition(st); PART_Set_Bl(st->bl,st); time(&(st->tree->t_beg)); time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [00] [%10.2f] [%5d]\n", (int)(st->tree->t_current-st->tree->t_beg), PART_Lk(st), PART_Pars(st)); int n_iter=0; do { PART_Optimize_Br_Len_Serie(st->tree->a_nodes[0], st->tree->a_nodes[0]->v[0], st->tree->a_nodes[0]->b[0], st); Set_Both_Sides(YES,st->tree); PART_Lk(st); PhyML_Printf("\n. %f",st->tree->c_lnL); /* For(part,st->n_part) PhyML_Printf("\n. %s",Write_Tree(st->treelist->tree[part],NO)); */ n_iter++; }while(n_iter < 5); /* Exit("\n"); */ /* PART_Lk(st); */ /* PhyML_Printf("\n> %f",st->tree->c_lnL); */ /* For(i,2*st->tree->n_otu-3) */ /* { */ /* if((!st->tree->a_edges[i]->left->tax) && (!st->tree->a_edges[i]->rght->tax)) */ /* { */ /* PART_NNI(st->tree->a_edges[i],st); */ /* } */ /* } */ /* if(io->mod->s_opt->topo_search == NNI_MOVE) */ PART_Simu(st); /* else */ /* PART_Speed_Spr(st); */ time(&t_end); hour = div(t_end-t_beg,3600); min = div(t_end-t_beg,60 ); min.quot -= hour.quot*60; PhyML_Fprintf(fp_phyml_stats,"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n"); PhyML_Fprintf(fp_phyml_stats,"\n. Number of partitions = %d\n\n",st->n_part); PhyML_Fprintf(fp_phyml_stats,"\n. Full data set -- lnL = %f\n\n",st->tree->c_lnL); PhyML_Fprintf(fp_phyml_stats,"\n. Tree search algorithm : %s\n\n",(io->mod->s_opt->topo_search == NNI_MOVE)?("NNIs"):("SPRs")); PhyML_Fprintf(fp_phyml_stats,"\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n\n"); For(part,io->n_part) { Print_Fp_Out(fp_phyml_stats,t_beg,t_end,st->treelist->tree[part], io->st->optionlist[part],1,1,YES); } PhyML_Printf("\n\n. Time used %dh%dm%ds\n", hour.quot,min.quot,(int)(t_end-t_beg)%60); PhyML_Printf("\n%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n\n"); For(i,2*st->tree->n_otu-3) st->tree->a_edges[i]->l->v = 0.1; s_tree = Write_Tree(st->tree,NO); PhyML_Fprintf(fp_phyml_tree,"Supertree\n"); PhyML_Fprintf(fp_phyml_tree,"%s\n",s_tree); Free(s_tree); For(part,st->n_part) { PhyML_Fprintf(fp_phyml_tree,"Gene tree number %d\n",part+1); s_tree = Write_Tree(st->treelist->tree[part],NO); PhyML_Fprintf(fp_phyml_tree,"%s\n",s_tree); Free(s_tree); } For(part,st->n_part) { if(io->mod->s_opt->topo_search == SPR_MOVE) Free_Spr_List(treelist->tree[part]); Free_Tree_Lk(treelist->tree[part]); Free_Tree_Pars(treelist->tree[part]); Free_Triplet(treelist->tree[part]->triplet_struct); Free_Tree(treelist->tree[part]); Free_Cseq(cdata[part]); Free_Model(mod[part]); Free_Input(io->st->optionlist[part]); } if(io->mod->s_opt->topo_search == SPR_MOVE) Free_Spr_List(st->tree); Free(mat); Free(mod); Free(data); Free(cdata); Free(treelist->tree); Free(treelist); Free_St(st); } if(io->fp_in_align ) fclose(io->fp_in_align); if(io->fp_in_tree) fclose(io->fp_in_tree); Free_Model(io->mod); Free_Input(io); fclose(fp_phyml_lk); fclose(fp_phyml_tree); fclose(fp_phyml_stats); return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Print_Nodes(t_node *a, t_node *d, supert_tree *st) { int i; PhyML_Printf(">>>>>>>>>>>>>>>>>>>>\n"); PhyML_Printf("num t_node = %d\n",d->num); if(d->tax) PhyML_Printf("name='%s'\n",d->name); else { PhyML_Printf("n_of_reachable_tips : \n"); For(i,3) { /* PhyML_Printf("dir%d=%d; ",i,st->n_of_reachable_tips[st->num_data_of_interest][d->num][i]); */ /* For(j,st->n_of_reachable_tips[st->num_data_of_interest][d->num][i]) */ /* { */ /* PhyML_Printf("%s ", */ /* st->list_of_reachable_tips[st->num_data_of_interest][d->num][i][j]->name); */ /* } */ PhyML_Printf("\n"); } } PhyML_Printf("<<<<<<<<<<<<<<<<<<<\n\n"); if(d->tax) return; else { For(i,3) if(d->v[i] != a) PART_Print_Nodes(d,d->v[i],st); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// supert_tree *PART_Make_Supert_tree_Light(option *input) { supert_tree *st; st = (supert_tree *)mCalloc(1,sizeof(supert_tree)); st->optionlist = (option **)mCalloc(input->n_part,sizeof(option *)); st->bl_partition = (int *)mCalloc(input->n_part,sizeof(int )); return st; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Make_Supert_tree_Full(supert_tree *st, option *io, calign **data) { int i,j,k; if(io->in_tree == 2) { PhyML_Printf("\n. Reading user tree...\n"); rewind(io->fp_in_tree); st->tree = Read_Tree_File_Phylip(io->fp_in_tree); if(!st->tree->has_branch_lengths) { PhyML_Printf("\n. Branch lengths are all set to 0.1...\n"); For(i,2*st->tree->n_otu-3) st->tree->a_edges[i]->l->v = 0.1; } } else { Warn_And_Exit("\n. A user-defined input tree is needed\n"); } st->tree->io = io; st->treelist = (t_treelist *)Make_Treelist(io->n_part); st->n_part = io->n_part; st->tree->mod = io->mod; st->lock_br_len = 0; st->map_st_node_in_gt = (t_node *****)mCalloc(st->n_part,sizeof(t_node ****)); For(i,st->n_part) { st->map_st_node_in_gt[i] = (t_node ****)mCalloc(2*st->tree->n_otu-2,sizeof(t_node ***)); For(j,2*st->tree->n_otu-2) { st->map_st_node_in_gt[i][j] = (t_node ***)mCalloc(3,sizeof(t_node **)); For(k,3) st->map_st_node_in_gt[i][j][k] = (t_node **)mCalloc(2,sizeof(t_node *)); } } st->map_st_edge_in_gt = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **)); For(i,st->n_part) st->map_st_edge_in_gt[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *)); st->map_gt_edge_in_st = (t_edge ****)mCalloc(st->n_part,sizeof(t_edge ***)); For(i,st->n_part) { st->map_gt_edge_in_st[i] = (t_edge ***)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge **)); For(j,2*st->tree->n_otu-3) st->map_gt_edge_in_st[i][j] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *)); } st->size_map_gt_edge_in_st = (int **)mCalloc(st->n_part,sizeof(int *)); For(i,st->n_part) st->size_map_gt_edge_in_st[i] = (int *)mCalloc(2*st->tree->n_otu-3,sizeof(int)); st->match_st_edge_in_gt = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **)); For(i,st->n_part) st->match_st_edge_in_gt[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *)); st->match_gt_edge_in_st = (t_edge ***)mCalloc(st->n_part,sizeof(t_edge **)); For(i,st->n_part) st->match_gt_edge_in_st[i] = (t_edge **)mCalloc(2*st->tree->n_otu-3,sizeof(t_edge *)); st->bl = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) st->bl[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl)); st->bl_cpy = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) st->bl_cpy[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl)); st->bl0 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) st->bl0[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl)); st->bl1 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) st->bl1[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl)); st->bl2 = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) st->bl2[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl)); st->s_mod = (t_mod **)mCalloc(st->n_part,sizeof(t_mod *)); For(i,2*st->tree->n_otu-3) Make_Edge_NNI(st->tree->a_edges[i]); st->match_st_node_in_gt = (t_node ***)mCalloc(io->n_part,sizeof(t_node **)); For(i,io->n_part) st->match_st_node_in_gt[i] = (t_node **)mCalloc(2*st->tree->n_otu-2,sizeof(t_node *)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Prune_St_Topo(t_tree *tree, calign *data, supert_tree *st) { int i,j,not_found; int curr_ext_node, curr_int_node, curr_br, n_pruned_nodes;; t_node **pruned_nodes; t_edge **residual_edges; pruned_nodes = (t_node **)mCalloc(st->tree->n_otu,sizeof(t_node *)); residual_edges = (t_edge **)mCalloc(st->tree->n_otu,sizeof(t_edge *)); n_pruned_nodes = 0; For(i,st->tree->n_otu) { For(j,data->n_otu) { if(!strcmp(data->c_seq[j]->name,st->tree->a_nodes[i]->name)) break; } not_found = 1; if(j == data->n_otu) { For(j,tree->n_otu) { if(!strcmp(tree->a_nodes[j]->name,st->tree->a_nodes[i]->name)) { Prune_Subtree(tree->a_nodes[j]->v[0], tree->a_nodes[j], NULL,&(residual_edges[n_pruned_nodes]), tree); pruned_nodes[n_pruned_nodes] = tree->a_nodes[j]; n_pruned_nodes++; not_found = 0; break; } } if(not_found) { PhyML_Printf("\n. Taxon '%s'",st->tree->a_nodes[i]->name); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } Free(tree->t_dir); tree->n_otu -= n_pruned_nodes; curr_ext_node = 0; curr_int_node = tree->n_otu; curr_br = 0; For(i,st->tree->n_otu) { For(j,n_pruned_nodes) { if(!strcmp(pruned_nodes[j]->name,st->tree->a_nodes[i]->name)) break; } if(j == n_pruned_nodes) /* That t_node still belongs to the tree */ { Reassign_Node_Nums(tree->a_nodes[i],tree->a_nodes[i]->v[0], &curr_ext_node, &curr_int_node,tree); break; } } Reassign_Edge_Nums(tree->a_nodes[0],tree->a_nodes[0]->v[0],&curr_br,tree); tree->t_dir = (short int *)mCalloc((2*tree->n_otu-2)*(2*tree->n_otu-2),sizeof(short int)); For(i,n_pruned_nodes) { Free_Edge(residual_edges[i]); Free_Edge(pruned_nodes[i]->b[0]); Free_Node(pruned_nodes[i]->v[0]); Free_Node(pruned_nodes[i]); } Free(pruned_nodes); Free(residual_edges); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Match_St_Nodes_In_Gt(t_tree *gt, supert_tree *st) { int i,j; For(i,2*st->tree->n_otu-2) st->match_st_node_in_gt[gt->dp][i] = NULL; /* don't forget that step ! */ /* Map tips */ For(i,st->tree->n_otu) { For(j,gt->n_otu) { if(!strcmp(st->tree->a_nodes[i]->name,gt->a_nodes[j]->name)) { st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num] = gt->a_nodes[j]; break; } } } #ifdef DEBUG /* Checking that the results are correct so far */ int n_matches; n_matches = 0; For(i,2*st->tree->n_otu-2) if(st->match_st_node_in_gt[gt->dp][i]) n_matches++; if(n_matches != gt->n_otu) { PhyML_Printf("\n"); PhyML_Printf("\n. n_matches = %d 2*gt->n_otu-2 = %d\n",n_matches,2*gt->n_otu-2); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif /* Map internal nodes */ For(i,st->tree->n_otu) { if(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num]) { PART_Match_St_Nodes_In_Gt_Recurr(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num], st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num]->v[0], st->tree->a_nodes[i], st->tree->a_nodes[i]->v[0], gt, st); break; } } #ifdef DEBUG /* Checking that the results are correct */ n_matches = 0; For(i,2*st->tree->n_otu-2) if(st->match_st_node_in_gt[gt->dp][st->tree->a_nodes[i]->num]) n_matches++; if(n_matches != 2*gt->n_otu-2) { int j; PhyML_Printf("\n"); PhyML_Printf("\n. n_matches = %d 2*gt->n_otu-2 = %d\n",n_matches,2*gt->n_otu-2); For(j,2*gt->n_otu-2) { For(i,2*st->tree->n_otu-2) if(st->match_st_node_in_gt[gt->dp][i] == gt->a_nodes[j]) break; if(i == 2*st->tree->n_otu-2) { PhyML_Printf("\n. Gt %3d t_node %3d (%3d %3d %3d) (%s %s %s) (%f %f %f) does not match\n", gt->dp, gt->a_nodes[j]->num, gt->a_nodes[j]->v[0] ? gt->a_nodes[j]->v[0]->num : -1, gt->a_nodes[j]->v[1] ? gt->a_nodes[j]->v[1]->num : -1, gt->a_nodes[j]->v[2] ? gt->a_nodes[j]->v[2]->num : -1, gt->a_nodes[j]->v[0]->tax ? gt->a_nodes[j]->v[0]->name : NULL, gt->a_nodes[j]->v[1]->tax ? gt->a_nodes[j]->v[1]->name : NULL, gt->a_nodes[j]->v[2]->tax ? gt->a_nodes[j]->v[2]->name : NULL, gt->a_nodes[j]->v[0] ? gt->a_nodes[j]->b[0]->l->v : -1., gt->a_nodes[j]->v[1] ? gt->a_nodes[j]->b[1]->l->v : -1., gt->a_nodes[j]->v[2] ? gt->a_nodes[j]->b[2]->l->v : -1.); } } PhyML_Printf("oooooooo\n"); Print_Node(st->tree->a_nodes[0], st->tree->a_nodes[0]->v[0], st->tree); PhyML_Printf(">>>>>>>\n"); For(i,st->n_part) { Print_Node(st->treelist->tree[i]->a_nodes[0], st->treelist->tree[i]->a_nodes[0]->v[0], st->treelist->tree[i]); PhyML_Printf("<<<<<<<\n"); } PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Match_St_Nodes_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st) { int i,j,k; int *score_d_st; if((d_gt->tax) || (d_st->tax)) return; else { score_d_st = (int *)mCalloc(3,sizeof(int)); /* Might be wrong. Check function Match_Nodes_In_Small_Tree */ For(i,3) { For(j,3) { For(k,d_st->bip_size[j]) { if(!strcmp(d_gt->bip_node[i][0]->name,d_st->bip_node[j][k]->name)) { score_d_st[j] += 1; break; } } } } if((score_d_st[0] == 2) && (score_d_st[1] == 2) && (score_d_st[2] == 2)) { st->match_st_node_in_gt[gt->dp][d_st->num] = d_gt; For(i,3) { if(d_gt->v[i] != a_gt) { For(j,3) { if(score_d_st[j] != 3) { PART_Match_St_Nodes_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st); break; } /* For(k,d_st->n_of_reachable_tips[j]) */ /* if(!strcmp(d_gt->list_of_reachable_tips[i][0]->name, */ /* d_st->list_of_reachable_tips[j][k]->name)) */ /* { */ /* PART_Match_St_Nodes_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st); */ /* break; */ /* } */ /* if(k != d_st->n_of_reachable_tips[j]) break; */ } } } } else { For(i,3) if(d_st->v[i] != a_st) PART_Match_St_Nodes_In_Gt_Recurr(a_gt,d_gt,d_st,d_st->v[i],gt,st); } Free(score_d_st); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Match_St_Edges_In_Gt(t_tree *gt, supert_tree *st) { int i; For(i,2*st->tree->n_otu-3) { st->match_st_edge_in_gt[gt->dp][i] = NULL; st->match_gt_edge_in_st[gt->dp][i] = NULL; } For(i,st->tree->n_otu) if(st->match_st_node_in_gt[gt->dp][i]) { PART_Match_St_Edges_In_Gt_Recurr(st->match_st_node_in_gt[gt->dp][i], st->match_st_node_in_gt[gt->dp][i]->v[0], st->tree->a_nodes[i], st->tree->a_nodes[i]->v[0], gt,st); break; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Match_St_Edges_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st) { t_edge *b_gt, *b_st; int i,j; b_gt = b_st = NULL; if((st->match_st_node_in_gt[gt->dp][a_st->num] == a_gt) && (st->match_st_node_in_gt[gt->dp][d_st->num] == d_gt)) { For(i,3) if((a_st->v[i]) && (a_st->v[i] == d_st)) {b_st = a_st->b[i]; break;} For(i,3) if((a_gt->v[i]) && (a_gt->v[i] == d_gt)) {b_gt = a_gt->b[i]; break;} st->match_st_edge_in_gt[gt->dp][b_st->num] = b_gt; st->match_gt_edge_in_st[gt->dp][b_gt->num] = b_st; } if(!d_gt) { PhyML_Printf("\n"); PhyML_Printf("\n. a_gt->num = %d\n",a_gt->num); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(d_gt->tax || d_st->tax) return; else { if(st->match_st_node_in_gt[gt->dp][d_st->num] == d_gt) { For(i,3) { if(d_gt->v[i] != a_gt) { For(j,3) { /* For(k,d_st->n_of_reachable_tips[j]) */ /* if(!strcmp(d_gt->list_of_reachable_tips[i][0]->name,d_st->list_of_reachable_tips[j][k]->name)) */ { PART_Match_St_Edges_In_Gt_Recurr(d_gt,d_gt->v[i],d_st,d_st->v[j],gt,st); break; } /* if(k != d_st->n_of_reachable_tips[j]) break; */ } } } } else { For(i,3) if(d_st->v[i] != a_st) PART_Match_St_Edges_In_Gt_Recurr(a_gt,d_gt,d_st,d_st->v[i],gt,st); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Simu(supert_tree *st) { int i,j,step,n_without_swap,it_lim_without_swap; t_edge **sorted_b,*st_b,**tested_b; int n_neg,n_tested,each; phydbl lambda,old_loglk; sorted_b = (t_edge **)mCalloc(st->tree->n_otu-3,sizeof(t_edge *)); tested_b = (t_edge **)mCalloc(st->tree->n_otu-3,sizeof(t_edge *)); For(i,st->n_part) Update_Dirs(st->treelist->tree[i]); Update_Dirs(st->tree); each = 4; step = 0; lambda = .75; n_tested = 0; n_without_swap = 0; old_loglk = UNLIKELY; it_lim_without_swap = 2; st_b = NULL; do { For(i,st->n_part) Check_Dirs(st->treelist->tree[i]); ++step; each--; /* PART_Print_Bl(st); */ /* Compute the likelihood of the supertreee */ st->tree->c_lnL = PART_Lk(st); st->tree->c_pars = PART_Pars(st); /* For(i,st->n_part) PhyML_Printf("\n. %s",Write_Tree(st->treelist->tree[i],NO)); */ /* PhyML_Printf("\n"); */ time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [tot lnL=%15.5f] [# swaps=%3d]", (int)(st->tree->t_current-st->tree->t_beg), st->tree->c_lnL,n_tested); /* For(i,st->n_part) PhyML_Printf("\n[gt %3d lnL=%15.5f]",i,st->treelist->tree[i]->c_lnL); */ if((FABS(old_loglk-st->tree->c_lnL) < st->tree->mod->s_opt->min_diff_lk_global) || (n_without_swap > it_lim_without_swap)) break; if(st->tree->c_lnL < old_loglk) { PhyML_Printf("\n. Moving backward (topology + branch lengths) \n"); if(!PART_Mov_Backward_Topo_Bl(st,old_loglk,tested_b,n_tested)) Warn_And_Exit("\n. Err: mov_back failed\n"); if(!st->tree->n_swap) n_neg = 0; PART_Record_Br_Len(st); For(i,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[i],0); } else { if(!each) { each = 4; /* Markov model parameters are free to vary across data partitions */ For(i,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[i],0); For(i,st->n_part) Set_Both_Sides(YES,st->treelist->tree[i]); st->tree->c_lnL = PART_Lk(st); st->tree->c_pars = PART_Pars(st); } old_loglk = st->tree->c_lnL; For(i,2*st->tree->n_otu-3) Init_NNI(st->tree->a_edges[i]->nni); /* Test NNIs */ For(i,2*st->tree->n_otu-3) { st_b = st->tree->a_edges[i]; if((!st_b->left->tax) && (!st_b->rght->tax)) PART_NNI(st_b,st); } /* Optimise external branch lengths */ For(i,2*st->tree->n_otu-3) { st_b = st->tree->a_edges[i]; if((st_b->left->tax) || (st_b->rght->tax)) { PART_Record_Br_Len(st); PART_Br_Len_Brent(st_b,0,st); For(j,st->n_part) st->bl0[st->bl_partition[j]][st_b->num] = st->bl[st->bl_partition[j]][st_b->num]; st_b->nni->score = .0; st_b->nni->best_conf = 0; PART_Restore_Br_Len(st); PART_Lk_At_Given_Edge(st_b,st); } } /* Select and sort swaps */ n_neg = 0; Select_Edges_To_Swap(st->tree,sorted_b,&n_neg); Sort_Edges_NNI_Score(st->tree,sorted_b,n_neg); n_tested = 0; For(i,(int)CEIL((phydbl)n_neg*(lambda))) tested_b[n_tested++] = sorted_b[i]; if(n_tested > 0) n_without_swap = 0; else n_without_swap++; PART_Record_Br_Len(st); /* Apply swaps */ PART_Make_N_Swap(tested_b,0,n_tested,st); /* Update branch lengths (all edges first and then swaped edges) */ PART_Update_Bl(lambda,st); PART_Update_Bl_Swaped(tested_b,n_tested,st); } } while(1); PhyML_Printf("\n\n. End of PART_Simu \n"); Free(sorted_b); Free(tested_b); if((n_without_swap > it_lim_without_swap)) { PhyML_Printf("\n. Last optimization step...\n"); For(i,st->n_part) Round_Optimize(st->treelist->tree[i],st->treelist->tree[i]->data,ROUND_MAX); st->tree->c_lnL = PART_Lk(st); PART_Simu(st); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Mov_Backward_Topo_Bl(supert_tree *st, phydbl lk_old, t_edge **tested_b, int n_tested) { int i,j,step,beg,end; t_edge *st_b; phydbl **l_init; int dim; l_init = (phydbl **)mCalloc(st->n_part,sizeof(phydbl *)); For(i,st->n_part) l_init[i] = (phydbl *)mCalloc(2*st->tree->n_otu-3,sizeof(phydbl )); For(i,2*st->tree->n_otu-3) For(j,st->n_part) l_init[st->bl_partition[j]][i] = st->bl[st->bl_partition[j]][i]; step = 2; do { For(i,2*st->tree->n_otu-3) { For(j,st->n_part) { st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i] + (1./step) * (l_init[st->bl_partition[j]][i] - st->bl_cpy[st->bl_partition[j]][i]); /* st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i]; */ } } beg = (int)FLOOR((phydbl)n_tested/(step-1)); end = 0; st_b = NULL; dim = 2*st->tree->n_otu-2; for(i=beg-1;i>=end;i--) { st_b = tested_b[i]; PART_Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]], st_b->nni->swap_node_v2, st_b->nni->swap_node_v3, st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]], st); Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]], st_b->nni->swap_node_v2, st_b->nni->swap_node_v3, st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]], st->tree); PART_Do_Mapping(st); } beg = 0; end = (int)FLOOR((phydbl)n_tested/step); st_b = NULL; dim = 2*st->tree->n_otu-2; for(i=beg;inni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]], st_b->nni->swap_node_v2, st_b->nni->swap_node_v3, st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]], st); Swap(st_b->nni->swap_node_v2->v[st->tree->t_dir[st_b->nni->swap_node_v2->num*dim+st_b->nni->swap_node_v1->num]], st_b->nni->swap_node_v2, st_b->nni->swap_node_v3, st_b->nni->swap_node_v3->v[st->tree->t_dir[st_b->nni->swap_node_v3->num*dim+st_b->nni->swap_node_v4->num]], st->tree); PART_Do_Mapping(st); } if(!end) st->tree->n_swap = 0; PART_Lk(st); PhyML_Printf("\n. lnL = %15.5f",st->tree->c_lnL); step++; } while((st->tree->c_lnL < lk_old) && (step < 100)); if(step == 100) { For(i,2*st->tree->n_otu-3) For(j,st->n_part) st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i]; } st->tree->n_swap = 0; For(i,2*st->tree->n_otu-3) { if(st->tree->a_edges[i]->nni->score < 0.0) st->tree->n_swap++; st->tree->a_edges[i]->nni->score = +1.0; } PART_Lk(st); if(st->tree->c_lnL > lk_old) return 1; else if(FABS(st->tree->c_lnL-lk_old) < st->tree->mod->s_opt->min_diff_lk_local) return -1; else return 0; For(i,st->n_part) Free(l_init[i]); Free(l_init); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Check_Extra_Taxa(supert_tree *st) { int i,j,k; int sum; int *st_taxa; st_taxa = (int *)mCalloc(st->tree->n_otu,sizeof(int)); For(i,st->tree->n_otu) { For(j,st->n_part) { For(k,st->treelist->tree[j]->n_otu) if(!strcmp(st->treelist->tree[j]->a_nodes[k]->name,st->tree->a_nodes[i]->name)) break; if(k != st->treelist->tree[j]->n_otu) { st_taxa[i] = 1; break; } } } sum = 0; For(i,st->tree->n_otu) if(st_taxa[i]) sum++; if(sum != st->tree->n_otu) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } Free(st_taxa); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Get_Species_Found_In_St(supert_tree *st, calign *data) { int i,j; For(i,data->n_otu) { For(j,st->tree->n_otu) { if(!strcmp(data->c_seq[i]->name,st->tree->a_nodes[j]->name)) { break; } } if(j == st->tree->n_otu) return 0; } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_St_Nodes_In_Gt(t_tree *gt, supert_tree *st) { int i; For(i,2*st->tree->n_otu-2) { st->map_st_node_in_gt[gt->dp][i][0][0] = NULL; st->map_st_node_in_gt[gt->dp][i][1][0] = NULL; st->map_st_node_in_gt[gt->dp][i][2][0] = NULL; st->map_st_node_in_gt[gt->dp][i][0][1] = NULL; st->map_st_node_in_gt[gt->dp][i][1][1] = NULL; st->map_st_node_in_gt[gt->dp][i][2][1] = NULL; } /* Root */ PART_Map_St_Nodes_In_Gt_One_Edge(st->tree->a_nodes[0]->v[0], st->tree->a_nodes[0], st->tree->a_nodes[0]->b[0], gt,st); /* Internal nodes */ PART_Map_St_Nodes_In_Gt_Post(st->tree->a_nodes[0],st->tree->a_nodes[0]->v[0],gt,st); PART_Map_St_Nodes_In_Gt_Pre (st->tree->a_nodes[0],st->tree->a_nodes[0]->v[0],gt,st); /* Root */ PART_Map_St_Nodes_In_Gt_One_Edge(st->tree->a_nodes[0], st->tree->a_nodes[0]->v[0], st->tree->a_nodes[0]->b[0], gt,st); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_St_Nodes_In_Gt_Post(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st) { int i; if(d_st->tax) return; else { For(i,3) if(d_st->v[i] != a_st) PART_Map_St_Nodes_In_Gt_Post(d_st,d_st->v[i],gt,st); For(i,3) if(d_st->v[i] != a_st) { PART_Map_St_Nodes_In_Gt_One_Edge(d_st,d_st->v[i],d_st->b[i],gt,st); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_St_Nodes_In_Gt_Pre(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st) { int i; if(d_st->tax) return; else { For(i,3) { if(d_st->v[i] != a_st) { PART_Map_St_Nodes_In_Gt_One_Edge(d_st->v[i],d_st,d_st->b[i],gt,st); PART_Map_St_Nodes_In_Gt_Pre(d_st,d_st->v[i],gt,st); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_St_Nodes_In_Gt_One_Edge(t_node *a_st, t_node *d_st, t_edge *b_st, t_tree *gt, supert_tree *st) { if(d_st->tax) { #ifdef DEBUG if(b_st->rght != d_st) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif st->map_st_node_in_gt[gt->dp][d_st->num][0][0] = st->match_st_node_in_gt[gt->dp][d_st->num]; } else { t_node **list_of_nodes_d, **list_of_nodes_v1, **list_of_nodes_v2; int dir1, dir2; int i; list_of_nodes_d = NULL; list_of_nodes_v1 = NULL; list_of_nodes_v2 = NULL; dir1 = dir2 = -1; For(i,3) { if(d_st->v[i] != a_st) (dir1 < 0)?(dir1 = i):(dir2 = i); else list_of_nodes_d = st->map_st_node_in_gt[gt->dp][d_st->num][i]; } For(i,3) if((d_st->v[dir1]->v[i]) && (d_st->v[dir1]->v[i] == d_st)) { list_of_nodes_v1 = st->map_st_node_in_gt[gt->dp][d_st->v[dir1]->num][i]; break; } For(i,3) if((d_st->v[dir2]->v[i]) && (d_st->v[dir2]->v[i] == d_st)) { list_of_nodes_v2 = st->map_st_node_in_gt[gt->dp][d_st->v[dir2]->num][i]; break; } /* d_st matches one t_node in gt */ if(st->match_st_node_in_gt[gt->dp][d_st->num]) { list_of_nodes_d[0] = st->match_st_node_in_gt[gt->dp][d_st->num]; list_of_nodes_d[1] = NULL; } else { /* list_of_nodes = union of list_of_nodes_v1 & list_of_nodes_v2 */ if(!list_of_nodes_v1[0]) { list_of_nodes_d[0] = list_of_nodes_v2[0]; list_of_nodes_d[1] = list_of_nodes_v2[1]; } else if(!list_of_nodes_v2[0]) { list_of_nodes_d[0] = list_of_nodes_v1[0]; list_of_nodes_d[1] = list_of_nodes_v1[1]; } else { list_of_nodes_d[0] = list_of_nodes_v1[0]; list_of_nodes_d[1] = list_of_nodes_v2[0]; if(list_of_nodes_v1[1] || list_of_nodes_v2[1]) { Print_Node(st->tree->a_nodes[0], st->tree->a_nodes[0]->v[0], st->tree); PhyML_Printf("\n\n--------------------------\n\n"); Print_Node(gt->a_nodes[0], gt->a_nodes[0]->v[0], gt); PhyML_Printf("\n\n--------------------------\n\n"); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_St_Edges_In_Gt(t_tree *gt, supert_tree *st) { int i,j; t_edge *st_b; t_node *gt_a, *gt_d; gt_a = NULL; gt_d = NULL; For(i,2*st->tree->n_otu-3) st->map_st_edge_in_gt[gt->dp][i] = NULL; For(i,2*st->tree->n_otu-3) { st_b = st->tree->a_edges[i]; if(!st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0]) { gt_a = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0]; gt_d = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][1]; For(j,3) { if((gt_a->v[j]) && (gt_a->v[j] == gt_d)) { st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j]; break; } } } else if(!st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0]) { gt_a = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0]; gt_d = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][1]; For(j,3) { if((gt_a->v[j]) && (gt_a->v[j] == gt_d)) { st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j]; break; } } } else { gt_a = st->map_st_node_in_gt[gt->dp][st_b->left->num][st_b->l_r][0]; gt_d = st->map_st_node_in_gt[gt->dp][st_b->rght->num][st_b->r_l][0]; #ifdef DEBUG if((!gt_a) || (!gt_d)) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif For(j,3) { if((gt_a->v[j]) && (gt_a->v[j] == gt_d)) { st->map_st_edge_in_gt[gt->dp][st_b->num] = gt_a->b[j]; break; } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Map_Gt_Edges_In_St(t_tree *gt, supert_tree *st) { int i; t_edge *st_b, *gt_b; For(i,2*st->tree->n_otu-3) st->size_map_gt_edge_in_st[gt->dp][i] = 0; st_b = NULL; gt_b = NULL; For(i,2*st->tree->n_otu-3) { st_b = st->tree->a_edges[i]; gt_b = st->map_st_edge_in_gt[gt->dp][st_b->num]; if(gt_b) { st->map_gt_edge_in_st[gt->dp][gt_b->num][st->size_map_gt_edge_in_st[gt->dp][gt_b->num]] = st_b; st->size_map_gt_edge_in_st[gt->dp][gt_b->num]++; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Pars(supert_tree *st) { int i; st->tree->c_pars = 0; For(i,st->n_part) { Set_Both_Sides(YES,st->treelist->tree[i]); Pars(NULL,st->treelist->tree[i]); st->tree->c_pars += st->treelist->tree[i]->c_pars; } return st->tree->c_pars; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Spr(phydbl init_lnL, supert_tree *st) { int gt; int i; t_edge *pruned; int best_move; t_node *gt_a, *gt_d; st->tree->n_root = st->tree->a_nodes[0]; pruned = NULL; gt_a = NULL; gt_d = NULL; Set_Both_Sides(YES,st->tree); For(i,2*st->tree->n_otu-3) { pruned = st->tree->a_edges[i]; st->tree->n_moves = 0; Reset_Spr_List(st->tree); For(gt,st->n_part) Reset_Spr_List(st->treelist->tree[gt]); if(!pruned->rght->tax) { For(gt,st->n_part) { /* Check constraints at prune site on gt tree */ gt_a = st->map_st_node_in_gt[gt][pruned->rght->num][pruned->r_l][0]; gt_d = st->map_st_node_in_gt[gt][pruned->left->num][pruned->l_r][0]; if((gt_a) && (gt_d) && (!st->map_st_edge_in_gt[gt][pruned->num]->rght->tax)) { Test_All_Spr_Targets(st->map_st_edge_in_gt[gt][pruned->num], st->map_st_edge_in_gt[gt][pruned->num]->rght, st->treelist->tree[gt]); } } } if(!pruned->left->tax) { For(gt,st->n_part) { /* Check constraints at prune site on gt tree */ gt_a = st->map_st_node_in_gt[gt][pruned->rght->num][pruned->r_l][0]; gt_d = st->map_st_node_in_gt[gt][pruned->left->num][pruned->l_r][0]; if((gt_a) && (gt_d) && (!st->map_st_edge_in_gt[gt][pruned->num]->left->tax)) { Test_All_Spr_Targets(st->map_st_edge_in_gt[gt][pruned->num], st->map_st_edge_in_gt[gt][pruned->num]->left, st->treelist->tree[gt]); } } } if(!pruned->left->tax) { PART_Test_All_Spr_Targets(st->tree->a_edges[i], st->tree->a_edges[i]->left, st); } if(!pruned->rght->tax) { PART_Test_All_Spr_Targets(st->tree->a_edges[i], st->tree->a_edges[i]->rght, st); } if(st->tree->n_moves) { best_move = PART_Test_List_Of_Regraft_Pos(st->tree->spr_list, (int)CEIL(0.1*(st->tree->n_moves)), st); if(st->tree->spr_list[best_move]->lnL > init_lnL) { PART_Try_One_Spr_Move(st->tree->spr_list[best_move],st); } else { Set_Both_Sides(YES,st->tree); st->tree->c_lnL = PART_Lk(st); st->tree->c_pars = PART_Pars(st); } } } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Speed_Spr(supert_tree *st) { int step; int gt; phydbl old_lnL; Make_Spr_List(st->tree); For(gt,st->n_part) Make_Spr_List(st->treelist->tree[gt]); Set_Both_Sides(YES,st->tree); For(gt,st->n_part) { Set_Both_Sides(YES,st->treelist->tree[gt]); Record_Br_Len(st->treelist->tree[gt]); } st->tree->c_pars = PART_Pars(st); st->tree->c_lnL = PART_Lk(st); st->tree->best_lnL = st->tree->c_lnL; old_lnL = st->tree->c_lnL; step = 0; do { ++step; PhyML_Printf("\n. Starting a SPR cycle... \n"); old_lnL = st->tree->c_lnL; st->tree->n_improvements = 0; st->tree->perform_spr_right_away = 1; PART_Spr(UNLIKELY,st); time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [00] [%10.2f] [%5d]\n", (int)(st->tree->t_current-st->tree->t_beg), PART_Lk(st),PART_Pars(st)); /* Optimise parameters of the Markov t_mod */ For(gt,st->n_part) Optimiz_All_Free_Param(st->treelist->tree[gt], st->treelist->tree[gt]->mod->s_opt->print); time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [ 0] [%10.2f] [%5d]\n", (int)(st->tree->t_current-st->tree->t_beg), PART_Lk(st),PART_Pars(st)); /* Optimise branch lengths */ For(gt,st->n_part) { Optimize_Br_Len_Serie(st->treelist->tree[gt]); } /* Update partial likelihoods & parsimony */ Set_Both_Sides(YES,st->tree); st->tree->c_pars = PART_Pars(st); st->tree->c_lnL = PART_Lk(st); time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [**] [%10.2f] [%5d]\n", (int)(st->tree->t_current-st->tree->t_beg), st->tree->c_lnL,st->tree->c_pars); /* Record the current best log-likleihood */ st->tree->best_lnL = st->tree->c_lnL; if(st->tree->c_lnL < old_lnL) { PhyML_Printf("\n. old_lnL = %f c_lnL = %f\n",old_lnL,st->tree->c_lnL); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* Record the current best branch lengths */ For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]); /* Exit if no improvements after complete optimization */ if((!st->tree->n_improvements) || (FABS(old_lnL-st->tree->c_lnL) < st->tree->mod->s_opt->min_diff_lk_global)) break; }while(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Test_All_Spr_Targets(t_edge *pruned, t_node *n_link, supert_tree *st) { int i,j; For(i,3) { if(n_link->b[i] != pruned) { For(j,3) { if((n_link->v[i]->v[j]) && (n_link->v[i]->v[j] != n_link)) { PART_Test_One_Spr_Target_Recur(n_link->v[i],n_link->v[i]->v[j],n_link->v[i]->b[j],pruned,n_link,st); } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *target, t_edge *pruned, t_node *n_link, supert_tree *st) { PART_Test_One_Spr_Target(pruned,target,n_link,st); if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) { PART_Test_One_Spr_Target_Recur(d,d->v[i],d->b[i],pruned,n_link,st); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Test_One_Spr_Target(t_edge *st_p, t_edge *st_t, t_node *n_link, supert_tree *st) { int gt, move; st->tree->n_moves++; st->tree->spr_list[st->tree->size_spr_list]->b_target = st_t; st->tree->spr_list[st->tree->size_spr_list]->n_link = n_link; st->tree->spr_list[st->tree->size_spr_list]->n_opp_to_link = (n_link == st_p->left)?(st_p->rght):(st_p->left); st->tree->spr_list[st->tree->size_spr_list]->b_opp_to_link = st_p; st->tree->spr_list[st->tree->size_spr_list]->pars = 0; For(gt,st->n_part) { move = Map_Spr_Move(st_p,st_t,n_link,st->treelist->tree[gt],st); if(move > -1) st->tree->spr_list[st->tree->size_spr_list]->pars += st->treelist->tree[gt]->spr_list[move]->pars; else if(move == -1 || move == -2) st->tree->spr_list[st->tree->size_spr_list]->pars += st->treelist->tree[gt]->c_pars; } Include_One_Spr_To_List_Of_Spr(st->tree->spr_list[st->tree->size_spr_list],st->tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Map_Spr_Move(t_edge *st_pruned, t_edge *st_target, t_node *st_link, t_tree *gt, supert_tree *st) { int i; t_edge *gt_pruned, *gt_target; t_node *gt_link, *gt_a, *gt_d; gt_pruned = NULL; gt_target = NULL; gt_link = NULL; gt_a = NULL; gt_d = NULL; /* Check contraints at prune and regraft sites on the gt tree */ /* st_pruned is not on a path that matches a branch in gt */ gt_a = st->map_st_node_in_gt[gt->dp][st_pruned->left->num][st_pruned->l_r][0]; gt_d = st->map_st_node_in_gt[gt->dp][st_pruned->rght->num][st_pruned->r_l][0]; if((!gt_a) || (!gt_d)) return -1; else { /* which gt nodes matches st_link ? */ gt_link = (st_pruned->left == st_link)?(gt_a):(gt_d); if(gt_link->tax) return -1; else { gt_pruned = st->map_st_edge_in_gt[gt->dp][st_pruned->num]; gt_target = st->map_st_edge_in_gt[gt->dp][st_target->num]; if((gt_pruned->left == gt_target->left) || (gt_pruned->left == gt_target->rght) || (gt_pruned->rght == gt_target->left) || (gt_pruned->rght == gt_target->rght)) return -1; else { For(i,gt->size_spr_list) { if((gt_pruned == gt->spr_list[i]->b_opp_to_link) && (gt_target == gt->spr_list[i]->b_target)) return i; } } } } return -2; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Test_List_Of_Regraft_Pos(t_spr **st_spr_list, int list_size, supert_tree *st) { int i,j,best_move; t_spr *move; t_edge *init_target, *b_residual; phydbl best_lnL, init_lnL; int dir_v0, dir_v1, dir_v2; int gt; int move_num; best_lnL = UNLIKELY; init_target = b_residual = NULL; best_move = -1; #ifdef DEBUG if(!list_size) { PhyML_Printf("\n\n. List size is 0 !"); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif init_lnL = UNLIKELY; For(i,list_size) { st->tree->spr_list[i]->lnL = .0; For(gt,st->n_part) { move_num = Map_Spr_Move(st->tree->spr_list[i]->b_opp_to_link, st->tree->spr_list[i]->b_target, st->tree->spr_list[i]->n_link, st->treelist->tree[gt],st); if(move_num > -1) { move = st->treelist->tree[gt]->spr_list[move_num]; if(move->b_target) { init_lnL = st->treelist->tree[gt]->c_lnL; /* Record t_edge lengths */ Record_Br_Len(st->treelist->tree[gt]); /* Prune subtree */ Prune_Subtree(move->n_link, move->n_opp_to_link, &init_target, &b_residual, st->treelist->tree[gt]); /* Rough optimisation of the branch length */ Fast_Br_Len(init_target,st->treelist->tree[gt],0); /* Update the change proba matrix at prune position */ Update_PMat_At_Given_Edge(init_target,st->treelist->tree[gt]); /* Update partial likelihood along the path from the prune to the regraft position */ Update_P_Lk_Along_A_Path(move->path,move->depth_path,st->treelist->tree[gt]); /* Regraft subtree */ Graft_Subtree(move->b_target,move->n_link,b_residual,st->treelist->tree[gt]); /* Estimate the three t_edge lengths at the regraft site */ Triple_Dist(move->n_link,st->treelist->tree[gt],-1); /* Update the transition proba matrices along edges defining the regraft site */ For(j,3) if(move->n_link->v[j] != move->n_opp_to_link) Update_PMat_At_Given_Edge(move->n_link->b[j],st->treelist->tree[gt]); /* Compute the likelihood */ Update_P_Lk(st->treelist->tree[gt], move->b_opp_to_link, move->n_link); move->lnL = Lk(move->b_opp_to_link,st->treelist->tree[gt]); st->tree->spr_list[i]->lnL += move->lnL; /* Record branch lengths */ dir_v1 = dir_v2 = dir_v0 = -1; For(j,3) { if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j; else if(dir_v1 < 0) dir_v1 = j; else dir_v2 = j; } move->l0 = move->n_link->b[dir_v0]->l->v; if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num) { move->l1 = move->n_link->b[dir_v2]->l->v; move->l2 = move->n_link->b[dir_v1]->l->v; } else { move->l1 = move->n_link->b[dir_v1]->l->v; move->l2 = move->n_link->b[dir_v2]->l->v; } /* Regraft the subtree at its original position */ Prune_Subtree(move->n_link, move->n_opp_to_link, &move->b_target, &b_residual, st->treelist->tree[gt]); Graft_Subtree(init_target, move->n_link, b_residual, st->treelist->tree[gt]); /* Restore branch lengths */ Restore_Br_Len(st->treelist->tree[gt]); /* Update relevant change proba matrices */ Update_PMat_At_Given_Edge(move->b_target,st->treelist->tree[gt]); For(j,3) Update_PMat_At_Given_Edge(move->n_link->b[j],st->treelist->tree[gt]); /* Update relevant partial likelihoods */ For(j,3) Update_P_Lk(st->treelist->tree[gt],move->n_link->b[j],move->n_link); st->treelist->tree[gt]->c_lnL = init_lnL; } } else { st->tree->spr_list[i]->lnL += st->treelist->tree[gt]->c_lnL; } } if(st->tree->spr_list[i]->lnL > best_lnL) { best_lnL = st->tree->spr_list[i]->lnL; best_move = i; } } return best_move; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PART_Try_One_Spr_Move(t_spr *st_move, supert_tree *st) { int j; t_spr **gt_move; t_edge **init_target, **b_residual; int dir_v0, dir_v1, dir_v2; int gt; int gt_move_num; int n_moves; init_target = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *)); b_residual = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *)); gt_move = (t_spr **)mCalloc(st->n_part,sizeof(t_spr *)); n_moves = 0; For(gt,st->n_part) { gt_move_num = Map_Spr_Move(st_move->b_opp_to_link, st_move->b_target, st_move->n_link, st->treelist->tree[gt],st); if(gt_move_num > -1) { n_moves++; gt_move[gt] = st->treelist->tree[gt]->spr_list[gt_move_num]; if(gt_move[gt]->b_target) { /* Record t_edge lengths */ Record_Br_Len(st->treelist->tree[gt]); /* Prune subtree */ Prune_Subtree(gt_move[gt]->n_link, gt_move[gt]->n_opp_to_link, &(init_target[gt]), &(b_residual[gt]), st->treelist->tree[gt]); /* Rough optimisation of the branch length */ Fast_Br_Len(init_target[gt],st->treelist->tree[gt],0); /* Update the change proba matrix at prune position */ Update_PMat_At_Given_Edge(init_target[gt],st->treelist->tree[gt]); /* TO DO : NECESSARY ?? */ /* Update partial likelihood along the path from the prune to the regraft position */ Update_P_Lk_Along_A_Path(gt_move[gt]->path,gt_move[gt]->depth_path,st->treelist->tree[gt]); /* TO DO : NECESSARY ?? */ /* Regraft subtree */ Graft_Subtree(gt_move[gt]->b_target,gt_move[gt]->n_link,b_residual[gt],st->treelist->tree[gt]); dir_v1 = dir_v2 = dir_v0 = -1; For(j,3) { if(gt_move[gt]->n_link->v[j] == gt_move[gt]->n_opp_to_link) dir_v0 = j; else if(dir_v1 < 0) dir_v1 = j; else dir_v2 = j; } gt_move[gt]->n_link->b[dir_v0]->l->v = gt_move[gt]->l0; if(gt_move[gt]->n_link->v[dir_v1]->num > gt_move[gt]->n_link->v[dir_v2]->num) { gt_move[gt]->n_link->b[dir_v2]->l->v = gt_move[gt]->l1; gt_move[gt]->n_link->b[dir_v1]->l->v = gt_move[gt]->l2; } else { gt_move[gt]->n_link->b[dir_v1]->l->v = gt_move[gt]->l1; gt_move[gt]->n_link->b[dir_v2]->l->v = gt_move[gt]->l2; } } } } if(n_moves) { if(st_move->lnL > st->tree->best_lnL) { t_edge *st_target, *st_residual; /* Apply the move on the super-tree */ Prune_Subtree(st_move->n_link, st_move->n_opp_to_link, &st_target, &st_residual, st->tree); Graft_Subtree(st_move->b_target, st_move->n_link, st_residual, st->tree); /* Map gt and st nodes and edges */ PART_Do_Mapping(st); time(&(st->tree->t_current)); Set_Both_Sides(YES,st->tree); st->tree->c_lnL = PART_Lk(st); st->tree->c_pars = PART_Pars(st); if(FABS(st->tree->c_lnL - st_move->lnL) > st->tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n. st->tree->c_lnL = %f st_move->lnL = %f\n", st->tree->c_lnL,st_move->lnL); For(gt,st->n_part) { PhyML_Printf("\n. truth -> %f ; move -> %f", Lk(NULL,st->treelist->tree[gt]), gt_move[gt] ? gt_move[gt]->lnL : -1.); } } PhyML_Printf("\n. (%5d sec) [+ ] [%10.2f] [%5d] -- ", (int)(st->tree->t_current - st->tree->t_beg), st->tree->c_lnL,st->tree->c_pars); For(gt,st->n_part) PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL); st->tree->n_improvements++; st->tree->best_lnL = st->tree->c_lnL; For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]); Free(init_target); Free(b_residual); Free(gt_move); return 1; } /* else */ /* { */ /* For(gt,st->n_part) */ /* { */ /* if(gt_move[gt]) */ /* { */ /* Lk(st->treelist->tree[gt]); */ /* Fast_Br_Len_Recur(st->treelist->tree[gt]->a_nodes[0], */ /* st->treelist->tree[gt]->a_nodes[0]->v[0], */ /* st->treelist->tree[gt]->a_nodes[0]->b[0], */ /* st->treelist->tree[gt]); */ /* } */ /* } */ /* time(&(st->tree->t_current)); */ /* st->tree->both_sides = 1; */ /* st->tree->c_lnL = PART_Lk(st); */ /* if(st->tree->c_lnL > st->tree->best_lnL) */ /* { */ /* t_edge *st_target, *st_residual; */ /* /\* Apply the move on the super-tree *\/ */ /* Prune_Subtree(st_move->n_link, */ /* st_move->n_opp_to_link, */ /* &st_target, */ /* &st_residual, */ /* st->tree); */ /* Graft_Subtree(st_move->b_target, */ /* st_move->n_link, */ /* st_residual, */ /* st->tree); */ /* /\* Map gt and st nodes and edges *\/ */ /* PART_Do_Mapping(st); */ /* st->tree->c_pars = PART_Pars(st); */ /* PhyML_Printf("\n. (%5d sec) [++] [%10.2f] [%5d] -- ", */ /* (int)(st->tree->t_current-st->tree->t_beg), */ /* st->tree->c_lnL, */ /* st->tree->c_pars); */ /* For(gt,st->n_part) */ /* PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL); */ /* st->tree->n_improvements++; */ /* st->tree->best_lnL = st->tree->c_lnL; */ /* For(gt,st->n_part) Record_Br_Len(st->treelist->tree[gt]); */ /* Free(init_target); */ /* Free(b_residual); */ /* Free(gt_move); */ /* return 1; */ /* } */ /* } */ } For(gt,st->n_part) { if(gt_move[gt]) { /* Regraft the subtree at its original position */ Prune_Subtree(gt_move[gt]->n_link, gt_move[gt]->n_opp_to_link, &(gt_move[gt]->b_target), &(b_residual[gt]), st->treelist->tree[gt]); Graft_Subtree(init_target[gt], gt_move[gt]->n_link, b_residual[gt], st->treelist->tree[gt]); /* Restore branch lengths */ Restore_Br_Len(st->treelist->tree[gt]); } } Set_Both_Sides(YES,st->tree); st->tree->c_lnL = PART_Lk(st); st->tree->c_pars = PART_Pars(st); time(&(st->tree->t_current)); PhyML_Printf("\n. (%5d sec) [--] [%10.2f] [%5d] -- ", (int)(st->tree->t_current - st->tree->t_beg), st->tree->c_lnL,st->tree->c_pars); For(gt,st->n_part) PhyML_Printf("[%10.2f] ",st->treelist->tree[gt]->c_lnL); Free(init_target); Free(b_residual); Free(gt_move); return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_NNI(t_edge *st_b, supert_tree *st) { t_node *v1, *v2, *v3, *v4; phydbl lk0_opt, lk1_opt, lk2_opt; int i,j; phydbl *init_bl; t_edge **map_edge_bef_swap, **map_edge_aft_swap; init_bl = (phydbl *)mCalloc(st->n_bl_part,sizeof(phydbl)); map_edge_bef_swap = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *)); map_edge_aft_swap = (t_edge **)mCalloc(st->n_part,sizeof(t_edge *)); v1 = st_b->left->v[st_b->l_v1]; v2 = st_b->left->v[st_b->l_v2]; v3 = st_b->rght->v[st_b->r_v1]; v4 = st_b->rght->v[st_b->r_v2]; lk0_opt = lk1_opt = lk2_opt = UNLIKELY; if(v1->num < v2->num) { Check_Dirs(st->tree); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(v3->num < v4->num) { Check_Dirs(st->tree); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* PhyML_Printf("oooooooo\n"); */ /* Print_Node(st->tree->a_nodes[0], */ /* st->tree->a_nodes[0]->v[0], */ /* st->tree); */ /* PhyML_Printf(">>>>>>>\n"); */ /* For(i,st->n_part) */ /* { */ /* Print_Node(st->treelist->tree[i]->a_nodes[0], */ /* st->treelist->tree[i]->a_nodes[0]->v[0], */ /* st->treelist->tree[i]); */ /* PhyML_Printf("<<<<<<<\n"); */ /* } */ PART_Record_Br_Len(st); For(i,st->n_part) map_edge_bef_swap[i] = NULL; For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_bef_swap[i] = st->map_st_edge_in_gt[i][st_b->num]; /* First alternative topological configuration */ /* Swap */ PART_Swap(v2,st_b->left,st_b->rght,v3,st); Swap(v2,st_b->left,st_b->rght,v3,st->tree); PART_Do_Mapping(st); PART_Set_Bl(st->bl,st); For(i,st->n_part) map_edge_aft_swap[i] = NULL; For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num]; For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) { For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->left); For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->rght); } PART_Update_Lk_At_Given_Edge(st_b,st); lk1_opt = PART_Br_Len_Brent(st_b,0,st); For(i,st->n_part) st->bl1[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num]; /* Unswap */ PART_Swap(v3,st_b->left,st_b->rght,v2,st); Swap(v3,st_b->left,st_b->rght,v2,st->tree); PART_Do_Mapping(st); PART_Restore_Br_Len(st); PART_Set_Bl(st->bl,st); For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) { For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->left); For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->rght); } /* Second alternative topological configuration */ /* Swap */ PART_Swap(v2,st_b->left,st_b->rght,v4,st); Swap(v2,st_b->left,st_b->rght,v4,st->tree); PART_Do_Mapping(st); PART_Set_Bl(st->bl,st); For(i,st->n_part) map_edge_aft_swap[i] = NULL; For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num]; For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) { For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->left); For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->rght); } PART_Update_Lk_At_Given_Edge(st_b,st); lk2_opt = PART_Br_Len_Brent(st_b,0,st); For(i,st->n_part) st->bl2[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num]; /* PhyML_Printf("\n. lk2_init = %f lk2_opt = %f",lk2_init,lk2_opt); */ /* Unswap */ PART_Swap(v4,st_b->left,st_b->rght,v2,st); Swap(v4,st_b->left,st_b->rght,v2,st->tree); PART_Do_Mapping(st); PART_Restore_Br_Len(st); PART_Set_Bl(st->bl,st); For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_bef_swap[i] && map_edge_aft_swap[i]) { For(j,3) if((map_edge_aft_swap[i]->left->v[j]) && (map_edge_aft_swap[i]->left->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->left); For(j,3) if((map_edge_aft_swap[i]->rght->v[j]) && (map_edge_aft_swap[i]->rght->b[j] == map_edge_bef_swap[i]) && (map_edge_aft_swap[i] != map_edge_bef_swap[i])) Update_P_Lk(st->treelist->tree[i], map_edge_aft_swap[i], map_edge_aft_swap[i]->rght); } /* Back to the initial topological configuration * and branch lengths. */ PART_Do_Mapping(st); PART_Set_Bl(st->bl,st); PART_Restore_Br_Len(st); For(i,st->n_part) map_edge_aft_swap[i] = NULL; For(i,st->n_part) if(st->map_st_edge_in_gt[i][st_b->num]) map_edge_aft_swap[i] = st->map_st_edge_in_gt[i][st_b->num]; For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); PART_Update_Lk_At_Given_Edge(st_b,st); lk0_opt = PART_Br_Len_Brent(st_b,0,st); For(i,st->n_part) st->bl0[st->bl_partition[i]][st_b->num] = st->bl[st->bl_partition[i]][st_b->num]; PART_Restore_Br_Len(st); PART_Set_Bl(st->bl,st); For(i,st->n_part) if(map_edge_bef_swap[i]) Update_PMat_At_Given_Edge(map_edge_bef_swap[i],st->treelist->tree[i]); For(i,st->n_part) if(map_edge_aft_swap[i]) Update_PMat_At_Given_Edge(map_edge_aft_swap[i],st->treelist->tree[i]); PART_Update_Lk_At_Given_Edge(st_b,st); /* For(i,2*st->tree->n_otu-3) */ /* PhyML_Printf("\n. 3 Edge %3d --> lnL=%f",i,PART_Lk_At_Given_Edge(st->tree->a_edges[i],st)); */ st_b->nni->lk0 = lk0_opt; st_b->nni->lk1 = lk1_opt; st_b->nni->lk2 = lk2_opt; st_b->nni->score = lk0_opt - MAX(lk1_opt,lk2_opt); if((st_b->nni->score < st->tree->mod->s_opt->min_diff_lk_local) && (st_b->nni->score > -st->tree->mod->s_opt->min_diff_lk_local)) { st_b->nni->score = .0; st_b->nni->lk1 = st_b->nni->lk0; st_b->nni->lk2 = st_b->nni->lk0; } PART_Restore_Br_Len(st); PART_Update_Lk_At_Given_Edge(st_b,st); /* to replace by PART_Update_PMat_At_Given_Edge(st_b,st); */ /* PhyML_Printf("\n. lk_end = %f",st->tree->c_lnL); */ /* For(i,2*st->tree->n_otu-3) PhyML_Printf("\n. %f",PART_Lk_At_Given_Edge(st->tree->a_edges[i],st)); */ /* PhyML_Printf("\n. lk_end = %f",PART_Lk(st)); */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n. Edge %3d, score = %20f",st_b->num,st_b->nni->score); */ if(st_b->num == 90) PhyML_Printf("\n. v1=%d v2=%d v3=%d v4=%d left-%d right-%d", v1->num, v2->num, v3->num, v4->num, st_b->left->num, st_b->rght->num); if(lk0_opt > MAX(lk1_opt,lk2_opt)) { st_b->nni->best_conf = 0; st_b->nni->swap_node_v1 = NULL; st_b->nni->swap_node_v2 = NULL; st_b->nni->swap_node_v3 = NULL; st_b->nni->swap_node_v4 = NULL; } else if(lk1_opt > MAX(lk0_opt,lk2_opt)) { st_b->nni->best_conf = 1; st_b->nni->swap_node_v1 = v2; st_b->nni->swap_node_v2 = st_b->left; st_b->nni->swap_node_v3 = st_b->rght; st_b->nni->swap_node_v4 = v3; } else if(lk2_opt > MAX(lk0_opt,lk1_opt)) { st_b->nni->best_conf = 2; st_b->nni->swap_node_v1 = v2; st_b->nni->swap_node_v2 = st_b->left; st_b->nni->swap_node_v3 = st_b->rght; st_b->nni->swap_node_v4 = v4; } else { st_b->nni->score = +1.0; st_b->nni->best_conf = 0; st_b->nni->swap_node_v1 = NULL; st_b->nni->swap_node_v2 = NULL; st_b->nni->swap_node_v3 = NULL; st_b->nni->swap_node_v4 = NULL; } Free(init_bl); Free(map_edge_aft_swap); Free(map_edge_bef_swap); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Swap(t_node *st_a, t_node *st_b, t_node *st_c, t_node *st_d, supert_tree *st) { int i,j; t_node *gt_a, *gt_b, *gt_c, *gt_d; int ab, ba, cd, dc, bc; ab = ba = cd = dc = bc = -1; For(i,3) if(st_a->v[i] == st_b) { ab = i; break; } For(i,3) if(st_b->v[i] == st_a) { ba = i; break; } For(i,3) if(st_c->v[i] == st_d) { cd = i; break; } For(i,3) if(st_d->v[i] == st_c) { dc = i; break; } For(i,3) if(st_b->v[i] == st_c) { bc = i; break; } if(ab < 0 || ba < 0 || cd < 0 || dc < 0) { PhyML_Printf("\n. Nodes %d %d %d %d\n",st_a->num,st_b->num,st_c->num,st_d->num); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } gt_a = gt_b = gt_c = gt_d = NULL; For(i,st->n_part) { gt_b = st->match_st_node_in_gt[i][st_b->num]; gt_c = st->match_st_node_in_gt[i][st_c->num]; if(gt_b && gt_c) /* The st t_edge with st_b and st_c at its extremities * matches an t_edge in gt */ { #ifdef DEBUG For(j,3) if((gt_b->v[j]) && (gt_b->v[j] == gt_c)) break; if(j == 3) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif gt_a = st->map_st_node_in_gt[i][st_a->num][ab][0]; gt_d = st->map_st_node_in_gt[i][st_d->num][dc][0]; Swap(gt_a,gt_b,gt_c,gt_d,st->treelist->tree[i]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Set_Bl(phydbl **bl, supert_tree *st) { int i,j; t_edge *gt_b; gt_b = NULL; /* Set all the actual branch lengths to 0.0 */ For(i,st->n_part) { For(j,2*st->treelist->tree[i]->n_otu-3) { gt_b = st->treelist->tree[i]->a_edges[j]; gt_b->l->v = .0; } } /* Update every branch length */ For(i,2*st->tree->n_otu-3) { For(j,st->n_part) { gt_b = st->map_st_edge_in_gt[j][i]; /* Need to make sure that st->tree->a_edges[i] is on an existing path in gt */ if((st->map_st_node_in_gt[j][st->tree->a_edges[i]->left->num][st->tree->a_edges[i]->l_r][0]) && (st->map_st_node_in_gt[j][st->tree->a_edges[i]->rght->num][st->tree->a_edges[i]->r_l][0])) { gt_b->l->v += bl[st->bl_partition[j]][i]; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Record_Br_Len(supert_tree *st) { int i,j; For(i,st->n_part) For(j,2*st->tree->n_otu-3) st->bl_cpy[i][j] = st->bl[i][j]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Restore_Br_Len(supert_tree *st) { int i,j; For(i,st->n_part) For(j,2*st->tree->n_otu-3) st->bl[i][j] = st->bl_cpy[i][j]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PART_Lk(supert_tree *st) { int i; PART_Do_Mapping(st); PART_Set_Bl(st->bl,st); st->tree->c_lnL = .0; For(i,st->n_part) { Set_Both_Sides(YES,st->treelist->tree[i]); Lk(NULL,st->treelist->tree[i]); /* PhyML_Printf("\n. Tree %3d lnL = %f",i+1,st->treelist->tree[i]->c_lnL); */ st->tree->c_lnL += st->treelist->tree[i]->c_lnL; } return st->tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PART_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st) { int i; t_edge *gt_b; phydbl lnL; PART_Set_Bl(st->bl,st); gt_b = NULL; st->tree->c_lnL = .0; lnL = .0; For(i,st->n_part) { gt_b = st->map_st_edge_in_gt[i][st_b->num]; lnL = Lk(gt_b,st->treelist->tree[i]); st->tree->c_lnL += lnL; /* PhyML_Printf("\n. gt %d st t_edge %d gt t_edge %d lnL=%f l=%f ",i,st_b->num,gt_b->num,lnL,gt_b->l->v); */ } return st->tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PART_Update_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st) { int i; t_edge *gt_b; PART_Set_Bl(st->bl,st); gt_b = NULL; st->tree->c_lnL = .0; For(i,st->n_part) { gt_b = st->map_st_edge_in_gt[i][st_b->num]; if(gt_b) st->tree->c_lnL += Update_Lk_At_Given_Edge(gt_b,st->treelist->tree[i]); else st->tree->c_lnL += st->treelist->tree[i]->c_lnL; } return st->tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Fill_Model_Partitions_Table(supert_tree *st) { int i,j; char *c; char *abc; int lig, col; int n_groups; int *encountered_vals; c = (char *)mCalloc(10,sizeof(char)); abc = (char *)mCalloc(20,sizeof(char)); encountered_vals = (int *)mCalloc(st->n_part,sizeof(int)); strcpy(abc,"ABCDEFGHIJKLMNOP\0"); PhyML_Printf("\n\n\n"); lig = col = 0; while(1) { PhyML_Printf("\n\n"); For(i,st->n_part) PhyML_Printf(". Data set %3d : %s\n",i+1,st->optionlist[i]->in_align_file); PhyML_Printf("\n. Data set "); For(i,st->n_part) PhyML_Printf("%3d ",i+1); PhyML_Printf("\n. -A- t_edge lengths "); For(i,st->n_part) PhyML_Printf("%3d ",st->bl_partition[i]); if(lig == 1) break; PhyML_Printf("\n. (%c-%2d)> ",abc[lig],col+1); Getstring_Stdin(c); switch(lig) { case 0 : { st->bl_partition[col] = atoi(c); break; } default : { break; } } col++; if(col == st->n_part) { col = 0; lig++; } } n_groups = 0; For(i,st->n_part) { For(j,n_groups) if(encountered_vals[j] == st->bl_partition[i]) break; if(j == n_groups) { encountered_vals[n_groups] = st->bl_partition[i]; n_groups++; } st->bl_partition[i] = j; } st->n_bl_part = n_groups; Free(encountered_vals); Free(c); Free(abc); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PART_Br_Len_Brent(t_edge *st_b, int quickdirty, supert_tree *st) { phydbl ax, cx; int part; phydbl cur_l; For(part,st->n_bl_part) { cur_l = st->bl[part][st_b->num]; ax = 10.*cur_l; cx = st->tree->mod->l_min; Generic_Brent_Lk(&(st->bl[part][st_b->num]), ax,cx, st->tree->mod->s_opt->min_diff_lk_local, st->tree->mod->s_opt->brent_it_max, st->tree->mod->s_opt->quickdirty, Wrap_Part_Lk_At_Given_Edge,st_b,NULL,st,NO); } return st->tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Initialise_Bl_Partition(supert_tree *st) { int i,j; For(i,st->n_bl_part) { For(j,2*st->tree->n_otu-3) { st->bl[i][j] = .1; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Optimize_Br_Len_Serie(t_node *st_a, t_node *st_d, t_edge *st_b, supert_tree *st) { phydbl lk_init; int i; lk_init = st->tree->c_lnL; PART_Br_Len_Brent(st_b,0,st); if(st->tree->c_lnL < lk_init - st->tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f -- %f",lk_init,st->tree->c_lnL); PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(st_d->tax) return; else For(i,3) if(st_d->v[i] != st_a) { PART_Update_P_Lk(st_d->b[i],st_d,st); PART_Optimize_Br_Len_Serie(st_d,st_d->v[i],st_d->b[i],st); } For(i,3) if((st_d->v[i] == st_a) && (!st_d->v[i]->tax)) PART_Update_P_Lk(st_d->b[i],st_d,st); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Update_P_Lk(t_edge *st_b, t_node *st_n, supert_tree *st) { int i,dir; dir = -1; For(i,3) if((st_n->b[i]) && (st_n->b[i] == st_b)) {dir = i; break;} if(dir < 0) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } For(i,st->n_part) { if((st->map_st_node_in_gt[i][st_n->num][dir][0]) && (!st->map_st_node_in_gt[i][st_n->num][dir][0]->tax)) { Update_P_Lk(st->treelist->tree[i], st->map_st_edge_in_gt[i][st_b->num], st->map_st_node_in_gt[i][st_n->num][dir][0]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Make_N_Swap(t_edge **st_b, int beg, int end, supert_tree *st) { int i; int dim; dim = 2*st->tree->n_otu-2; st->tree->n_swap = 0; for(i=beg;ileft->tax || st_b[i]->rght->tax) { PhyML_Printf("\n. Edge %d is external.",st_b[i]->num); PhyML_Printf("\n. Err in file %s at line %d\n\n.",__FILE__,__LINE__); Warn_And_Exit(""); } PART_Swap(st_b[i]->nni->swap_node_v2->v[st->tree->t_dir[st_b[i]->nni->swap_node_v2->num*dim+st_b[i]->nni->swap_node_v1->num]], st_b[i]->nni->swap_node_v2, st_b[i]->nni->swap_node_v3, st_b[i]->nni->swap_node_v3->v[st->tree->t_dir[st_b[i]->nni->swap_node_v3->num*dim+st_b[i]->nni->swap_node_v4->num]], st); Swap(st_b[i]->nni->swap_node_v2->v[st->tree->t_dir[st_b[i]->nni->swap_node_v2->num*dim+st_b[i]->nni->swap_node_v1->num]], st_b[i]->nni->swap_node_v2, st_b[i]->nni->swap_node_v3, st_b[i]->nni->swap_node_v3->v[st->tree->t_dir[st_b[i]->nni->swap_node_v3->num*dim+st_b[i]->nni->swap_node_v4->num]], st->tree); PART_Do_Mapping(st); st->tree->n_swap++; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Update_Bl(phydbl fact, supert_tree *st) { int i,j; For(i,2*st->tree->n_otu-3) { For(j,st->n_part) st->bl[st->bl_partition[j]][i] = st->bl_cpy[st->bl_partition[j]][i] + (st->bl0[st->bl_partition[j]][i] - st->bl_cpy[st->bl_partition[j]][i]) * fact; } PART_Set_Bl(st->bl,st); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Update_Bl_Swaped(t_edge **st_b, int n, supert_tree *st) { int i,j; For(i,n) { For(j,st->n_part) { st->bl[st->bl_partition[j]][st_b[i]->num] = (st_b[i]->nni->best_conf == 1)? (st->bl1[st->bl_partition[j]][st_b[i]->num]): (st->bl2[st->bl_partition[j]][st_b[i]->num]); } } PART_Set_Bl(st->bl,st); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Do_Mapping(supert_tree *st) { int k; Fill_Dir_Table(st->tree); For(k,st->n_part) { Fill_Dir_Table(st->treelist->tree[k]); PART_Match_St_Nodes_In_Gt(st->treelist->tree[k],st); PART_Match_St_Edges_In_Gt(st->treelist->tree[k],st); PART_Map_St_Nodes_In_Gt(st->treelist->tree[k],st); PART_Map_St_Edges_In_Gt(st->treelist->tree[k],st); PART_Map_Gt_Edges_In_St(st->treelist->tree[k],st); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PART_Print_Bl(supert_tree *st) { int i,j; For(j,2*st->tree->n_otu-3) { PhyML_Printf("\n. t_edge %4d ",j); For(i,st->n_bl_part) { PhyML_Printf("%f ",st->bl[i][j]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/mg.h000066400000000000000000000066741263450375500142370ustar00rootroot00000000000000#include #ifndef PART_H #define PART_H #include "utilities.h" void Menu_Supertree(option *input); void PART_Print_Nodes(t_node *a, t_node *d, supert_tree *st); supert_tree *PART_Make_Supert_tree_Light(option *input); void PART_Make_Supert_tree_Full(supert_tree *st, option *input, calign **data); void PART_Get_List_Of_Reachable_Tips(t_node *a, t_node *d, calign **data, supert_tree *st); void PART_Get_List_Of_Reachable_Tips_Pre(t_node *a, t_node *d, supert_tree *st); void PART_Get_List_Of_Reachable_Tips_Post(t_node *a, t_node *d, supert_tree *st); void PART_Prune_St_Topo(t_tree *tree, calign *data, supert_tree *st); void PART_Match_St_Nodes_In_Gt_Recurr(t_node *a_gt, t_node *d_gt, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st); void PART_Match_St_Nodes_In_Gt(t_tree *tree, supert_tree *st); void PART_Match_St_Edges_In_Gt(t_tree *gt, supert_tree *st); void PART_Match_St_Edges_In_Gt_Recurr(t_node *a, t_node *d, t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st); void PART_Simu(supert_tree *tr); int PART_Mov_Backward_Topo_Bl(supert_tree *st, phydbl lk_old, t_edge **tested_b, int n_tested); int PART_Get_Species_Found_In_St(supert_tree *st, calign *data); void PART_Map_St_Nodes_In_Gt_Pre(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st); void PART_Map_St_Nodes_In_Gt_Post(t_node *a_st, t_node *d_st, t_tree *gt, supert_tree *st); void PART_Map_St_Nodes_In_Gt(t_tree *gt, supert_tree *st); void PART_Map_St_Nodes_In_Gt_One_Edge(t_node *a_st, t_node *d_st, t_edge *b_st, t_tree *gt, supert_tree *st); void PART_Map_St_Edges_In_Gt(t_tree *gt, supert_tree *st); phydbl PART_Lk(supert_tree *st); int PART_Pars(supert_tree *st); int PART_Spr(phydbl init_lnL, supert_tree *st); void PART_Speed_Spr(supert_tree *st); int Map_Spr_Move(t_edge *st_pruned, t_edge *st_target, t_node *st_link, t_tree *gt, supert_tree *st); void PART_Test_All_Spr_Targets(t_edge *pruned, t_node *n_link, supert_tree *st); void PART_Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *target, t_edge *pruned, t_node *n_link, supert_tree *st); void PART_Test_One_Spr_Target(t_edge *st_p, t_edge *st_t, t_node *n_link, supert_tree *st); int PART_Test_List_Of_Regraft_Pos(t_spr **st_spr_list, int list_size, supert_tree *st); int PART_Try_One_Spr_Move(t_spr *st_move, supert_tree *st); void PART_Map_Gt_Edges_In_St(t_tree *gt, supert_tree *st); void PART_NNI(t_edge *st_b, supert_tree *st); void PART_Swap(t_node *st_a, t_node *st_b, t_node *st_c, t_node *st_d, supert_tree *st); void PART_Set_Bl(phydbl **bl, supert_tree *st); void PART_Restore_Br_Len(supert_tree *st); void PART_Record_Br_Len(supert_tree *st); phydbl PART_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st); phydbl PART_Update_Lk_At_Given_Edge(t_edge *st_b, supert_tree *st); void PART_Fill_Model_Partitions_Table(supert_tree *st); phydbl PART_Br_Len_Brent(t_edge *st_b, int quickdirty, supert_tree *tree); void PART_Initialise_Bl_Partition(supert_tree *st); void PART_Update_P_Lk(t_edge *st_b, t_node *st_n, supert_tree *st); void PART_Optimize_Br_Len_Serie(t_node *st_a, t_node *st_d, t_edge *st_b, supert_tree *st); void PART_Update_Bl_Swaped(t_edge **st_b, int n, supert_tree *st); void PART_Update_Bl(phydbl fact, supert_tree *st); void PART_Make_N_Swap(t_edge **st_b, int beg, int end, supert_tree *st); void PART_Do_Mapping(supert_tree *st); void PART_Update_PMat(t_edge *st_b, supert_tree *st); void PART_Print_Bl(supert_tree *st); void PART_Check_Extra_Taxa(supert_tree *st); int PART_main(int argc, char **argv); #endif phyml-3.2.0/src/mixt.c000066400000000000000000001517331263450375500146050ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "mixt.h" int n_sec1 = 0; ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_All(t_tree *mixt_tree) { t_tree *curr, *next; int i; curr = mixt_tree; next = mixt_tree->next; do { MIXT_Chain_String(curr->mod->aa_rate_mat_file,next->mod->aa_rate_mat_file); MIXT_Chain_String(curr->mod->modelname,next->mod->modelname); MIXT_Chain_String(curr->mod->custom_mod_string,next->mod->custom_mod_string); MIXT_Chain_Scalar_Dbl(curr->mod->kappa,next->mod->kappa); MIXT_Chain_Scalar_Dbl(curr->mod->lambda,next->mod->lambda); MIXT_Chain_Scalar_Dbl(curr->mod->br_len_mult,next->mod->br_len_mult); MIXT_Chain_Scalar_Dbl(curr->mod->mr,next->mod->mr); MIXT_Chain_Vector_Dbl(curr->mod->Pij_rr,next->mod->Pij_rr); MIXT_Chain_Vector_Dbl(curr->mod->user_b_freq,next->mod->user_b_freq); For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l,next->a_edges[i]->l); For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_old,next->a_edges[i]->l_old); For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_var,next->a_edges[i]->l_var); For(i,2*mixt_tree->n_otu-1) MIXT_Chain_Scalar_Dbl(curr->a_edges[i]->l_var_old,next->a_edges[i]->l_var_old); MIXT_Chain_Rmat(curr->mod->r_mat,next->mod->r_mat); MIXT_Chain_RAS(curr->mod->ras,next->mod->ras); MIXT_Chain_Efrq(curr->mod->e_frq,next->mod->e_frq); MIXT_Chain_Eigen(curr->mod->eigen,next->mod->eigen); curr = next; next = next->next; } while(next); curr = mixt_tree; do { MIXT_Chain_Edges(curr); MIXT_Chain_Nodes(curr); MIXT_Chain_Sprs(curr); MIXT_Chain_Triplets(curr); curr = curr->next; } while(curr); Make_Rmat_Weight(mixt_tree); Make_Efrq_Weight(mixt_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Edges(t_tree *tree) { int i; t_edge *b; For(i,2*tree->n_otu-1) { b = tree->a_edges[i]; if(tree->next) b->next = tree->next->a_edges[i]; if(tree->prev) b->prev = tree->prev->a_edges[i]; if(tree->next_mixt) b->next_mixt = tree->next_mixt->a_edges[i]; if(tree->prev_mixt) b->prev_mixt = tree->prev_mixt->a_edges[i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Nodes(t_tree *tree) { int i; t_node *n; For(i,2*tree->n_otu-2) { n = tree->a_nodes[i]; if(tree->next) n->next = tree->next->a_nodes[i]; if(tree->prev) n->prev = tree->prev->a_nodes[i]; if(tree->next_mixt) n->next_mixt = tree->next_mixt->a_nodes[i]; if(tree->prev_mixt) n->prev_mixt = tree->prev_mixt->a_nodes[i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Sprs(t_tree *tree) { int i; if(tree->next) tree->best_spr->next = tree->next->best_spr; if(tree->prev) tree->best_spr->prev = tree->prev->best_spr; if(tree->next_mixt) tree->best_spr->next_mixt = tree->next_mixt->best_spr; if(tree->prev_mixt) tree->best_spr->prev_mixt = tree->prev_mixt->best_spr; For(i,2*tree->n_otu-2) { if(tree->next) tree->spr_list[i]->next = tree->next->spr_list[i]; if(tree->prev) tree->spr_list[i]->prev = tree->prev->spr_list[i]; if(tree->next_mixt) tree->spr_list[i]->next_mixt = tree->next_mixt->spr_list[i]; if(tree->prev_mixt) tree->spr_list[i]->prev_mixt = tree->prev_mixt->spr_list[i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Triplets(t_tree *tree) { if(tree->next) tree->triplet_struct->next = tree->next->triplet_struct; if(tree->prev) tree->triplet_struct->prev = tree->prev->triplet_struct; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_String(t_string *curr, t_string *next) { if(!next) { return; } else { t_string *buff,*last; last = NULL; /*! Search backward */ buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Vector_Dbl(vect_dbl *curr, vect_dbl *next) { if(!next) { return; } else { vect_dbl *buff,*last; last = NULL; buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Scalar_Dbl(scalar_dbl *curr, scalar_dbl *next) { if(!next) { return; } else { scalar_dbl *buff, *last; last = NULL; /*! Search backward */ buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } /*! Not chained yet. Add next at the end of chained list */ if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Rmat(t_rmat *curr, t_rmat *next) { if(!next) { return; } else { t_rmat *buff, *last; last = NULL; buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Efrq(t_efrq *curr, t_efrq *next) { if(!next) { return; } else { t_efrq *buff,*last; last = NULL; buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_Eigen(eigen *curr, eigen *next) { if(!next) { return; } else { eigen *buff,*last; last = NULL; buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Chain_RAS(t_ras *curr, t_ras *next) { if(!next) return; else { t_ras *buff,*last; last = NULL; buff = curr; while(buff) { if(buff == next) break; buff = buff->prev; } /*! Search forward */ if(!buff) { buff = curr; while(buff) { if(buff == next) break; buff = buff->next; } } if(!buff) { last = curr; while(last->next) { last = last->next; } last->next = next; next->prev = last; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Turn_Branches_OnOff(int onoff, t_tree *mixt_tree) { int i; t_tree *tree; if(mixt_tree->is_mixt_tree == NO) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } tree = mixt_tree; do { For(i,2*tree->n_otu-1) tree->a_edges[i]->l->onoff = onoff; tree = tree->next; } while(tree && tree->is_mixt_tree == NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *MIXT_Get_Lengths_Of_This_Edge(t_edge *mixt_b, t_tree *mixt_tree) { phydbl *lens; t_edge *b; t_tree *tree; int n_lens; lens = NULL; n_lens = 0; b = mixt_b; tree = mixt_tree; do { if(!lens) lens = (phydbl *)mCalloc(2,sizeof(phydbl)); else lens = (phydbl *)realloc(lens,(n_lens+2)*sizeof(phydbl)); lens[n_lens] = b->l->v; lens[n_lens+1] = b->l_var->v; n_lens+=2; b = b->next; tree = tree->next; } while(b); return(lens); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens, t_edge *mixt_b, t_tree *mixt_tree) { t_edge *b; int n_lens; t_tree *tree; n_lens = 0; tree = mixt_tree; b = mixt_b; do { b->l->v = lens[n_lens]; b->l_var->v = lens[n_lens+1]; n_lens+=2; b = b->next; tree = tree->next; } while(b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Post_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree) { t_tree *tree; t_node *a,*d; tree = mixt_tree; a = mixt_a; d = mixt_d; do { if(tree->is_mixt_tree) { tree = tree->next; a = a->next; d = d->next; } if(tree->mod->ras->invar == NO) Post_Order_Lk(a,d,tree); tree = tree->next; a = a->next; d = d->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Pre_Order_Lk(t_node *mixt_a, t_node *mixt_d, t_tree *mixt_tree) { t_tree *tree; t_node *a,*d; tree = mixt_tree; a = mixt_a; d = mixt_d; do { if(tree->is_mixt_tree) { tree = tree->next; a = a->next; d = d->next; } if(tree->mod->ras->invar == NO) Pre_Order_Lk(a,d,tree); tree = tree->next; a = a->next; d = d->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Lk(t_edge *mixt_b, t_tree *mixt_tree) { t_tree *tree,*cpy_mixt_tree; t_edge *b,*cpy_mixt_b; phydbl sum_lnL; int site, class, br; phydbl *sum_scale_left_cat,*sum_scale_rght_cat; phydbl sum,tmp; int exponent; phydbl site_lk_cat,site_lk,log_site_lk,inv_site_lk; int num_prec_issue,fact_sum_scale; phydbl max_sum_scale,min_sum_scale; int ambiguity_check,state; int k,l; int dim1,dim2; phydbl r_mat_weight_sum, e_frq_weight_sum, sum_probas; tree = NULL; b = NULL; cpy_mixt_tree = mixt_tree; cpy_mixt_b = mixt_b; MIXT_Update_Br_Len_Multipliers(mixt_tree->mod); do /*! Consider each element of the data partition */ { if(!cpy_mixt_b) Set_Model_Parameters(mixt_tree->mod); Set_Br_Len_Var(mixt_tree); if(!cpy_mixt_b) { For(br,2*mixt_tree->n_otu-3) Update_PMat_At_Given_Edge(mixt_tree->a_edges[br],mixt_tree); if(mixt_tree->n_root) { Update_PMat_At_Given_Edge(mixt_tree->n_root->b[1],tree); Update_PMat_At_Given_Edge(mixt_tree->n_root->b[2],tree); } } else { Update_PMat_At_Given_Edge(mixt_b,mixt_tree); } if(!cpy_mixt_b) { if(mixt_tree->n_root) { MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree); MIXT_Post_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree); MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[1],mixt_tree->n_root); MIXT_Update_P_Lk(mixt_tree,mixt_tree->n_root->b[2],mixt_tree->n_root); if(tree->both_sides == YES) { MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[1],mixt_tree); MIXT_Pre_Order_Lk(mixt_tree->n_root,mixt_tree->n_root->v[2],mixt_tree); } } else { MIXT_Post_Order_Lk(mixt_tree->a_nodes[0],mixt_tree->a_nodes[0]->v[0],mixt_tree); if(mixt_tree->both_sides == YES) MIXT_Pre_Order_Lk(mixt_tree->a_nodes[0], mixt_tree->a_nodes[0]->v[0], mixt_tree); } } if(!cpy_mixt_b) { if(mixt_tree->n_root) mixt_b = (mixt_tree->n_root->v[1]->tax == NO)?(mixt_tree->n_root->b[2]):(mixt_tree->n_root->b[1]); else mixt_b = mixt_tree->a_nodes[0]->b[0]; } sum_scale_left_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl)); sum_scale_rght_cat = (phydbl *)mCalloc(MAX(mixt_tree->mod->ras->n_catg,mixt_tree->mod->n_mixt_classes),sizeof(phydbl)); r_mat_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->r_mat_weight); e_frq_weight_sum = MIXT_Get_Sum_Chained_Scalar_Dbl(mixt_tree->next->mod->e_frq_weight); sum_probas = MIXT_Get_Sum_Of_Probas_Across_Mixtures(r_mat_weight_sum, e_frq_weight_sum, mixt_tree); mixt_tree->c_lnL = .0; dim1 = mixt_tree->mod->ns; dim2 = mixt_tree->mod->ns; For(site,mixt_tree->n_pattern) { b = mixt_b->next; tree = mixt_tree->next; /*! Skip calculations if model has zero rate */ while(tree->mod->ras->invar == YES) { tree = tree->next; b = b->next; if(!tree || tree->is_mixt_tree == YES) { PhyML_Printf("\n== %p",(void *)tree); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } } ambiguity_check = -1; state = -1; if((b->rght->tax) && (!mixt_tree->mod->s_opt->greedy) && (mixt_tree->data->wght[site] > SMALL)) { ambiguity_check = b->rght->c_seq->is_ambigu[site]; if(!ambiguity_check) state = b->rght->c_seq->d_state[site]; } /*! For all classes in the mixture */ do { if(tree->is_mixt_tree) { tree = tree->next; b = b->next; } tree->curr_site = site; tree->apply_lk_scaling = NO; if(!(tree->mod->ras->invar == YES && mixt_tree->is_mixt_tree == YES) && (tree->data->wght[tree->curr_site] > SMALL)) { site_lk_cat = .0; if((b->rght->tax) && (!tree->mod->s_opt->greedy)) { if(!ambiguity_check) { sum = .0; For(l,tree->mod->ns) { sum += b->Pij_rr[state*dim2+l] * b->p_lk_left[site*dim1+l]; } site_lk_cat += sum * tree->mod->e_frq->pi->v[state]; } else { For(k,tree->mod->ns) { sum = .0; if(b->p_lk_tip_r[site*dim2+k] > .0) { For(l,tree->mod->ns) { sum += b->Pij_rr[k*dim2+l] * b->p_lk_left[site*dim1+l]; } site_lk_cat += sum * tree->mod->e_frq->pi->v[k] * b->p_lk_tip_r[site*dim2+k]; } } } } else { For(k,tree->mod->ns) { sum = .0; if(b->p_lk_rght[site*dim1+k] > .0) { For(l,tree->mod->ns) { sum += b->Pij_rr[k*dim2+l] * b->p_lk_left[site*dim1+l]; } site_lk_cat += sum * tree->mod->e_frq->pi->v[k] * b->p_lk_rght[site*dim1+k]; } } } tree->site_lk_cat[0] = site_lk_cat; } tree = tree->next; b = b->next; } while(tree && tree->is_mixt_tree == NO); max_sum_scale = (phydbl)BIG; min_sum_scale = -(phydbl)BIG; tree = mixt_tree->next; b = mixt_b->next; class = 0; do { if(tree->mod->ras->invar == YES) { tree = tree->next; b = b->next; if(!(tree && tree->is_mixt_tree == NO)) break; } sum_scale_left_cat[class] = (b->sum_scale_left)? (b->sum_scale_left[site]): (0.0); sum_scale_rght_cat[class] = (b->sum_scale_rght)? (b->sum_scale_rght[site]): (0.0); sum = sum_scale_left_cat[class] + sum_scale_rght_cat[class]; if(sum < .0) { PhyML_Printf("\n== sum = %G",sum); PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } tmp = sum + ((phydbl)LOGBIG - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2; if(tmp < max_sum_scale) max_sum_scale = tmp; /* min of the maxs */ tmp = sum + ((phydbl)LOGSMALL - LOG(tree->site_lk_cat[0]))/(phydbl)LOG2; if(tmp > min_sum_scale) min_sum_scale = tmp; /* max of the mins */ class++; tree = tree->next; b = b->next; } while(tree && tree->is_mixt_tree == NO); tree = NULL; /*! For debugging purpose */ if(min_sum_scale > max_sum_scale) min_sum_scale = max_sum_scale; fact_sum_scale = (int)((max_sum_scale + min_sum_scale) / 2); /*! Populate the mixt_tree->site_lk_cat[class] table after scaling */ tree = mixt_tree->next; b = mixt_b->next; class = 0; do { if(tree->mod->ras->invar == YES) { tree = tree->next; b = b->next; if(!(tree && tree->is_mixt_tree == NO)) break; } exponent = -(sum_scale_left_cat[class]+sum_scale_rght_cat[class])+fact_sum_scale; site_lk_cat = tree->site_lk_cat[0]; Rate_Correction(exponent,&site_lk_cat,mixt_tree); mixt_tree->site_lk_cat[class] = site_lk_cat; tree->site_lk_cat[0] = site_lk_cat; class++; tree = tree->next; b = b->next; } while(tree && tree->is_mixt_tree == NO); tree = mixt_tree->next; b = mixt_b->next; class = 0; site_lk = .0; do { if(tree->mod->ras->invar == YES) { tree = tree->next; b = b->next; if(!(tree && tree->is_mixt_tree == NO)) break; } site_lk += mixt_tree->site_lk_cat[class] * mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] * tree->mod->r_mat_weight->v / r_mat_weight_sum * tree->mod->e_frq_weight->v / e_frq_weight_sum / sum_probas; /* mixt_tree->site_lk_cat[class] * */ /* mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number]; */ /* printf("\n. %f %f %f %f ", */ /* tree->mod->r_mat_weight->v,r_mat_weight_sum, */ /* tree->mod->e_frq_weight->v,e_frq_weight_sum); */ tree = tree->next; b = b->next; class++; } while(tree && tree->is_mixt_tree == NO); /* Scaling for invariants */ if(mixt_tree->mod->ras->invar == YES) { num_prec_issue = NO; tree = mixt_tree->next; while(tree->mod->ras->invar == NO) { tree = tree->next; if(!tree || tree->is_mixt_tree == YES) { PhyML_Printf("\n== tree: %p",tree); PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__); Exit("\n"); } } tree->apply_lk_scaling = YES; /*! 'tree' will give the correct state frequencies (as opposed to mixt_tree */ inv_site_lk = Invariant_Lk(fact_sum_scale,site,&num_prec_issue,tree); if(num_prec_issue == YES) // inv_site_lk >> site_lk { site_lk = inv_site_lk * mixt_tree->mod->ras->pinvar->v; } else { site_lk = site_lk * (1. - mixt_tree->mod->ras->pinvar->v) + inv_site_lk * mixt_tree->mod->ras->pinvar->v; } } log_site_lk = LOG(site_lk) - (phydbl)LOG2 * fact_sum_scale; int mixt_class = 0; int rate_class = 0; For(rate_class,mixt_tree->mod->ras->n_catg) { mixt_class = 0; tree = mixt_tree->next; do { if(tree->mod->ras->parent_class_number == rate_class) { mixt_tree->unscaled_site_lk_cat[rate_class*mixt_tree->n_pattern + site] += // TO DO: add correct weight here LOG(mixt_tree->site_lk_cat[mixt_class]) - (phydbl)LOG2 * fact_sum_scale; break; } mixt_class++; tree = tree->next; } while(tree && tree->is_mixt_tree == NO); } if(isinf(log_site_lk) || isnan(log_site_lk)) { PhyML_Printf("\n== Site = %d",site); PhyML_Printf("\n== Invar = %d",mixt_tree->data->invar[site]); PhyML_Printf("\n== Mixt = %d",mixt_tree->is_mixt_tree); PhyML_Printf("\n== Lk = %G LOG(Lk) = %f < %G",site_lk,log_site_lk,-BIG); For(class,mixt_tree->mod->ras->n_catg) PhyML_Printf("\n== rr=%f p=%f",mixt_tree->mod->ras->gamma_rr->v[class],mixt_tree->mod->ras->gamma_r_proba->v[class]); PhyML_Printf("\n== Pinv = %G",mixt_tree->mod->ras->pinvar->v); PhyML_Printf("\n== Bl mult = %G",mixt_tree->mod->br_len_mult->v); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } mixt_tree->cur_site_lk[site] = log_site_lk; /* Multiply log likelihood by the number of times this site pattern is found in the data */ mixt_tree->c_lnL_sorted[site] = mixt_tree->data->wght[site]*log_site_lk; mixt_tree->c_lnL += mixt_tree->data->wght[site]*log_site_lk; /* tree->sum_min_sum_scale += (int)tree->data->wght[site]*min_sum_scale; */ } Free(sum_scale_left_cat); Free(sum_scale_rght_cat); mixt_tree = mixt_tree->next_mixt; mixt_b = mixt_b->next_mixt; } while(mixt_tree); mixt_tree = cpy_mixt_tree; mixt_b = cpy_mixt_b; sum_lnL = .0; do { sum_lnL += mixt_tree->c_lnL; mixt_tree = mixt_tree->next_mixt; } while(mixt_tree); mixt_tree = cpy_mixt_tree; do { mixt_tree->c_lnL = sum_lnL; mixt_tree = mixt_tree->next_mixt; } while(mixt_tree); mixt_tree = cpy_mixt_tree; return mixt_tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Update_Eigen(t_mod *mixt_mod) { t_mod *mod; mod = mixt_mod; do { if(mod->is_mixt_mod) mod = mod->next; Update_Eigen(mod); mod = mod->next; } while(mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Update_P_Lk(t_tree *mixt_tree, t_edge *mixt_b, t_node *mixt_d) { t_tree *tree; t_edge *b; t_node *d; tree = mixt_tree; b = mixt_b; d = mixt_d; do { if(tree->is_mixt_tree) { tree = tree->next; b = b->next; d = d->next; } Update_P_Lk(tree,b,d); tree = tree->next; b = b->next; d = d->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b, t_tree *mixt_tree) { t_tree *tree; t_edge *b; tree = mixt_tree; b = mixt_b; do { if(tree->is_mixt_tree) { tree = tree->next; b = b->next; } if(tree->mod->ras->invar == NO) Update_PMat_At_Given_Edge(b,tree); tree = tree->next; b = b->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int *MIXT_Get_Number_Of_Classes_In_All_Mixtures(t_tree *mixt_tree) { int *n_catg; t_tree *tree; int class; if(mixt_tree->is_mixt_tree == YES) { n_catg = NULL; tree = mixt_tree; class = 0; do { if(!class) n_catg = (int *)mCalloc(1,sizeof(int)); else n_catg = (int *)realloc(n_catg,(class+1)*sizeof(int)); tree = tree->next; n_catg[class]=0; do { n_catg[class]++; tree = tree->next; } while(tree && tree->is_mixt_tree == NO); class++; } while(tree); } else { n_catg = (int *)mCalloc(1,sizeof(int)); n_catg[0] = mixt_tree->mod->ras->n_catg; if(mixt_tree->mod->ras->invar == YES) n_catg[0]++; } return(n_catg); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree **MIXT_Record_All_Mixtures(t_tree *mixt_tree) { t_tree **tree_list; int n_trees; t_tree *tree; tree_list = NULL; n_trees = 0; tree = mixt_tree; do { if(!tree_list) tree_list = (t_tree **)mCalloc(1,sizeof(t_tree *)); else tree_list = (t_tree **)realloc(tree_list,(n_trees+1)*sizeof(t_tree *)); tree_list[n_trees] = tree; n_trees++; tree = tree->next; } while(tree); tree_list = (t_tree **)realloc(tree_list,(n_trees+1)*sizeof(t_tree *)); tree_list[n_trees] = NULL; return(tree_list); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Break_All_Mixtures(int *c_max, t_tree *mixt_tree) { t_tree *tree; int c,i,n; if(mixt_tree->is_mixt_tree == NO) return; c = 0; n = -1; tree = mixt_tree; do { if(tree->is_mixt_tree == YES) { c = 0; n++; tree = tree->next; } if(c == (c_max[n]-1) && tree->next != NULL && tree->next->is_mixt_tree == NO) { if(tree->mixt_tree->next_mixt == NULL) { tree->next = NULL; For(i,2*tree->n_otu-1) tree->a_edges[i]->next = NULL; For(i,2*tree->n_otu-1) tree->a_nodes[i]->next = NULL; For(i,2*tree->n_otu-2) tree->spr_list[i]->next = NULL; } else { tree->next = tree->mixt_tree->next_mixt; For(i,2*tree->n_otu-1) tree->a_edges[i]->next = tree->mixt_tree->next_mixt->a_edges[i]; For(i,2*tree->n_otu-1) tree->a_nodes[i]->next = tree->mixt_tree->next_mixt->a_nodes[i]; For(i,2*tree->n_otu-2) tree->spr_list[i]->next = tree->mixt_tree->next_mixt->spr_list[i]; } } tree = tree->next; c++; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Reconnect_All_Mixtures(t_tree **tree_list, t_tree *mixt_tree) { t_tree *tree; int n_trees; if(mixt_tree->is_mixt_tree == NO) return; tree = mixt_tree; n_trees = 0; do { tree = tree_list[n_trees]; if(tree->is_mixt_tree == NO) tree->next = tree_list[n_trees+1]; n_trees++; tree = tree->next; } while(tree); MIXT_Chain_All(mixt_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int *MIXT_Record_Has_Invariants(t_tree *mixt_tree) { int *has_invariants; t_tree *tree; int n_trees; has_invariants = NULL; tree = mixt_tree; n_trees = 0; do { if(!n_trees) has_invariants = (int *)mCalloc(1,sizeof(int)); else has_invariants = (int *)realloc(has_invariants,(n_trees+1)*sizeof(int)); has_invariants[n_trees] = (tree->mod->ras->invar == YES)?1:0; n_trees++; tree = tree->next; } while(tree); return(has_invariants); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Reset_Has_Invariants(int *has_invariants, t_tree *mixt_tree) { t_tree *tree; int n_trees; tree = mixt_tree; n_trees = 0; do { tree->mod->ras->invar = has_invariants[n_trees]; n_trees++; tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Check_Invar_Struct_In_Each_Partition_Elem(t_tree *mixt_tree) { if(mixt_tree->is_mixt_tree == NO) return; else { t_tree *tree; int n_inv; n_inv = 0; tree = mixt_tree; do { if(tree->is_mixt_tree) { tree = tree->next; n_inv = 0; } if(tree->mod->ras->invar == YES) n_inv++; if(n_inv > 1) { PhyML_Printf("\n== Found %d classes of the mixture for file '%s' set to",n_inv,tree->mixt_tree->io->in_align_file); PhyML_Printf("\n== invariable. Only one such class per mixture is allowed."); PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } if(tree->mixt_tree->mod->ras->invar == NO && tree->mod->ras->invar == YES) { PhyML_Printf("\n== Unexpected settings for 'siterates' in a partition element (file '%s')",tree->mixt_tree->io->in_align_file); PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } tree = tree->next; } while(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Check_RAS_Struct_In_Each_Partition_Elem(t_tree *mixt_tree) { if(mixt_tree->is_mixt_tree == NO) return; else { t_tree *tree; int n_classes; n_classes = 0; tree = mixt_tree; do { if(tree->is_mixt_tree) { if(tree->mod->ras->invar == YES) { if(tree->next->mod->ras->invar == NO) { PhyML_Printf("\n== The invariant site class has to be the first element in"); PhyML_Printf("\n== each component. Please amend you XML"); PhyML_Printf("\n== file accordingly.\n"); Exit("\n."); } } tree = tree->next; n_classes = 0; } if(tree && tree->mod->ras->invar == NO) n_classes++; if((tree->next && tree->next->is_mixt_tree == YES) || (!tree->next)) /*! current tree is the last element of this mixture */ { if(n_classes < tree->mixt_tree->mod->ras->n_catg) { PhyML_Printf("\n== %d class%s found in 'partitionelem' for file '%s' while", n_classes, (n_classes>1)?"es\0":"\0", tree->mixt_tree->io->in_align_file); PhyML_Printf("\n== the corresponding 'siterates' element defined %d class%s.", tree->mixt_tree->mod->ras->n_catg, (tree->mixt_tree->mod->ras->n_catg>1)?"es\0":"\0"); PhyML_Printf("\n== Err. in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } tree = tree->next; } while(tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Prune_Subtree(t_node *mixt_a, t_node *mixt_d, t_edge **mixt_target, t_edge **mixt_residual, t_tree *mixt_tree) { t_node *a,*d; t_edge *target, *residual; t_tree *tree; MIXT_Turn_Branches_OnOff(OFF,mixt_tree); tree = mixt_tree; a = mixt_a; d = mixt_d; target = *mixt_target; residual = *mixt_residual; do { if(tree->is_mixt_tree) { tree = tree->next; a = a->next; d = d->next; target = target->next; residual = residual->next; } Prune_Subtree(a,d,&target,&residual,tree); tree = tree->next; a = a->next; d = d->next; target = target->next; residual = residual->next; } while(tree && tree->is_mixt_tree == NO); if(tree) Prune_Subtree(a,d,&target,&residual,tree); /*! Turn branches of this mixt_tree to ON after recursive call to Prune_Subtree such that, if branches of mixt_tree->next point to those of mixt_tree, they are set to OFF when calling Prune */ MIXT_Turn_Branches_OnOff(ON,mixt_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Graft_Subtree(t_edge *mixt_target, t_node *mixt_link, t_edge *mixt_residual, t_tree *mixt_tree) { t_edge *target,*residual; t_node *link; t_tree *tree; MIXT_Turn_Branches_OnOff(OFF,mixt_tree); tree = mixt_tree; target = mixt_target; residual = mixt_residual; link = mixt_link; do { if(tree->is_mixt_tree) { tree = tree->next; target = target->next; residual = residual->next; link = link->next; } Graft_Subtree(target,link,residual,tree); tree = tree->next; target = target->next; residual = residual->next; link = link->next; } while(tree && tree->is_mixt_tree == NO); if(tree) Graft_Subtree(target,link,residual,tree); /*! Turn branches of this mixt_tree to ON after recursive call to Graft_Subtree such that, if branches of mixt_tree->next point to those of mixt_tree, they are set to OFF when calling Graft */ MIXT_Turn_Branches_OnOff(ON,mixt_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Br_Len_Brent(phydbl prop_min, phydbl prop_max, t_edge *mixt_b, t_tree *mixt_tree) { t_tree *tree; t_edge *b; b = mixt_b; tree = mixt_tree; do { if(tree->is_mixt_tree) { tree = tree->next; b = b->next; } Br_Len_Brent(prop_min,prop_max,b,tree); b->l->onoff = OFF; tree = tree->next; b = b->next; } while(tree); tree = mixt_tree; do { MIXT_Turn_Branches_OnOff(ON,tree); tree = tree->next_mixt; } while(tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void MIXT_Prepare_Tree_For_Lk(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { if(tree->is_mixt_tree) tree = tree->next; Prepare_Tree_For_Lk(tree); tree = tree->next; } while(tree && tree->is_mixt_tree == NO); if(tree) Prepare_Tree_For_Lk(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Br_Len_Involving_Invar(t_tree *mixt_tree) { int i; scalar_dbl *l; For(i,2*mixt_tree->n_otu-1) { l = mixt_tree->a_edges[i]->l; do { l->v *= (1.-mixt_tree->mod->ras->pinvar->v); l = l->next; } while(l); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Br_Len_Not_Involving_Invar(t_tree *mixt_tree) { int i; scalar_dbl *l; For(i,2*mixt_tree->n_otu-1) { l = mixt_tree->a_edges[i]->l; do { l->v /= (1.-mixt_tree->mod->ras->pinvar->v); l = l->next; } while(l); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Unscale_Br_Len_Multiplier_Tree(t_tree *mixt_tree) { int i; scalar_dbl *l; For(i,2*mixt_tree->n_otu-1) { l = mixt_tree->a_edges[i]->l; do { l->v /= mixt_tree->mod->br_len_mult->v; l = l->next; } while(l); } return(-1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Rescale_Br_Len_Multiplier_Tree(t_tree *mixt_tree) { int i; scalar_dbl *l; For(i,2*mixt_tree->n_otu-1) { l = mixt_tree->a_edges[i]->l; do { l->v *= mixt_tree->mod->br_len_mult->v; l = l->next; } while(l); } return(-1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Rescale_Free_Rate_Tree(t_tree *mixt_tree) { int i,side_effect,at_boundary; t_edge *b; side_effect = NO; For(i,2*mixt_tree->n_otu-1) { b = mixt_tree->a_edges[i]->next; at_boundary = NO; if(b->l->v > mixt_tree->mod->l_max-1.E-100 && b->l->v < mixt_tree->mod->l_max+1.E-100) at_boundary = YES; if(b->l->v > mixt_tree->mod->l_min-1.E-100 && b->l->v < mixt_tree->mod->l_min+1.E-100) at_boundary = YES; b->l->v *= mixt_tree->mod->ras->free_rate_mr->v; if(b->l->v > mixt_tree->mod->l_max && at_boundary == NO) side_effect = YES; if(b->l->v < mixt_tree->mod->l_min && at_boundary == NO) side_effect = YES; } return side_effect; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Set_Alias_Subpatt(int onoff, t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { tree->update_alias_subpatt = onoff; tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Check_Single_Edge_Lens(t_tree *mixt_tree) { t_tree *tree; int i; tree = mixt_tree->next; do { if(tree->next && tree->next->is_mixt_tree == NO) { For(i,2*tree->n_otu-1) { if(tree->a_edges[i]->l != tree->next->a_edges[i]->l) { PhyML_Printf("\n== %p %p",tree->a_edges[i]->l,tree->next->a_edges[i]->l); PhyML_Printf("\n== Only one set of edge lengths is allowed "); PhyML_Printf("\n== in a 'partitionelem'. Please fix your XML file."); Exit("\n"); } } } tree = tree->next; } while(tree && tree->next && tree->next->is_mixt_tree == NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int MIXT_Pars(t_edge *mixt_b, t_tree *mixt_tree) { t_edge *b; t_tree *tree; b = mixt_b; tree = mixt_tree; do { b = b->next_mixt; tree = tree->next_mixt; if(tree) { Pars(b,tree); mixt_tree->c_pars += tree->c_pars; } } while(tree); tree = mixt_tree; do { tree->c_pars = mixt_tree->c_pars; tree = tree->next_mixt; } while(tree); return(mixt_tree->c_pars); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Bootstrap(char *best_tree, xml_node *root) { xml_node *n,*p_elem; char *bootstrap; n = XML_Search_Node_Name("phyml",NO,root); bootstrap = XML_Get_Attribute_Value(n,"bootstrap"); if(!bootstrap) return; else { int n_boot,i,j,k; xml_attr *boot_attr,*seqfile_attr,*out_attr,*boot_out_attr; char *orig_align,*boot_out_file_name,*xml_boot_file_name,*buff; FILE *boot_fp_in_align,*xml_boot_file_fp; option *io; align **boot_data,**orig_data; int position,elem; xml_node *boot_root; int pid; char *s; orig_align = (char *)mCalloc(T_MAX_NAME,sizeof(char)); xml_boot_file_name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(xml_boot_file_name,"phyml_boot_config."); pid = (int)getpid(); sprintf(xml_boot_file_name+strlen(xml_boot_file_name),"%d",pid); strcat(xml_boot_file_name,".xml"); out_attr = XML_Search_Attribute(root,"output.file"); assert(out_attr); boot_out_file_name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(boot_out_file_name,out_attr->value); s = XML_Get_Attribute_Value(root,"run.id"); if(s) { strcat(boot_out_file_name,"_"); strcat(boot_out_file_name,s); } n_boot = atoi(bootstrap); io = NULL; For(i,n_boot) { boot_root = XML_Copy_XML_Graph(root); /*! Set the number of bootstrap repeats to 0 in each generated XML file */ boot_attr = XML_Search_Attribute(boot_root,"bootstrap"); assert(boot_attr); strcpy(boot_attr->value,"0"); /*! Set the output file name for each bootstrap analysis */ boot_out_attr = XML_Search_Attribute(boot_root,"output.file"); assert(boot_out_attr); buff = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(buff,boot_out_attr->value); Free(boot_out_attr->value); boot_out_attr->value = buff; sprintf(boot_out_attr->value+strlen(boot_out_attr->value),"_boot.%d",pid); p_elem = boot_root; elem = 0; do { p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem); if(!p_elem) break; io = (option *)Make_Input(); Set_Defaults_Input(io); /*! Get the original sequence file name and the corresponding attribute in the XML graph */ seqfile_attr = NULL; seqfile_attr = XML_Search_Attribute(p_elem,"file.name"); assert(seqfile_attr); strcpy(orig_align,seqfile_attr->value); /*! Open the original sequence file */ io->fp_in_align = Openfile(orig_align,0); /*! Read in the original sequence file */ orig_data = Get_Seq(io); rewind(io->fp_in_align); /*! Read in the original sequence file and put it in 'boot_data' structure */ boot_data = Get_Seq(io); fclose(io->fp_in_align); /*! Bootstrap resampling: sample from original and put in boot */ For(j,boot_data[0]->len) { position = Rand_Int(0,(int)(boot_data[0]->len-1.0)); For(k,io->n_otu) { boot_data[k]->state[j] = orig_data[k]->state[position]; } } /*! Modify the sequence file attribute in the original XML graph */ buff = (char *)mCalloc(T_MAX_NAME,sizeof(char)); Free(seqfile_attr->value); seqfile_attr->value = buff; sprintf(seqfile_attr->value,"%s_%d_%d",orig_align,elem,i); /*! Open a new sequence file with the modified attribute name */ boot_fp_in_align = Openfile(seqfile_attr->value,1); /*! Print the bootstrap data set in it */ Print_Seq(boot_fp_in_align,boot_data,io->n_otu); fclose(boot_fp_in_align); Free_Seq(orig_data,io->n_otu); Free_Seq(boot_data,io->n_otu); Free_Input(io); elem++; } while(p_elem); /*! Open bootstrap XML file in writing mode */ xml_boot_file_fp = Openfile(xml_boot_file_name,1); /*! Write the bootstrap XML graph */ XML_Write_XML_Graph(xml_boot_file_fp,boot_root); fclose(xml_boot_file_fp); /*! Reconstruct the tree */ PhyML_XML(xml_boot_file_name); /*! Remove the bootstrap alignment files */ p_elem = boot_root; do { p_elem = XML_Search_Node_Name("partitionelem",YES,p_elem); if(!p_elem) break; seqfile_attr = XML_Search_Attribute(p_elem,"file.name"); /* unlink(seqfile_attr->value); */ } while(p_elem); XML_Free_XML_Tree(boot_root); } Free(xml_boot_file_name); Free(orig_align); Free(boot_out_file_name); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Set_Pars_Thresh(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { tree->mod->s_opt->pars_thresh = (tree->io->datatype == AA)?(15):(5); tree = tree->next_mixt; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *mixt_tree) { phydbl sum; int n; t_tree *tree; t_edge *b; b = mixt_b; tree = mixt_tree; sum = .0; n = 0 ; do { if(tree->is_mixt_tree == YES) { tree = tree->next; b = b->next; } sum += b->l->v * tree->mixt_tree->mod->br_len_mult->v; n++; b = b->next; tree = tree->next; } while(b); return(sum / (phydbl)n); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Get_Sum_Chained_Scalar_Dbl(scalar_dbl *s) { scalar_dbl *s_buff; phydbl sum; s_buff = s; sum = .0; do { sum += s_buff->v; s_buff = s_buff->next; } while(s_buff); return sum; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_frq_weight_sum, t_tree *mixt_tree) { t_tree *tree; phydbl sum; sum = .0; tree = mixt_tree->next; do { sum += mixt_tree->mod->ras->gamma_r_proba->v[tree->mod->ras->parent_class_number] * tree->mod->r_mat_weight->v / r_mat_weight_sum * tree->mod->e_frq_weight->v / e_frq_weight_sum; tree = tree->next; } while(tree && tree->is_mixt_tree == NO); return(sum); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Set_Br_Len_Var(t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree->next; do { Set_Br_Len_Var(tree); tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void MIXT_Update_Br_Len_Multipliers(t_mod *mod) { phydbl sum; t_mod *loc; int n_mixt; loc = mod; sum = 0.0; n_mixt = 0; do { /* if(loc->s_opt->opt_br_len_mult == YES) */ /* { */ sum += loc->br_len_mult_unscaled->v; n_mixt++; /* } */ loc = loc->next_mixt; } while(loc); loc = mod; do { if(loc->s_opt->opt_br_len_mult == YES) { loc->br_len_mult->v = loc->br_len_mult_unscaled->v / sum; loc->br_len_mult->v *= (phydbl)(n_mixt); /* printf("\n. HERE %f %f\n",loc->br_len_mult_unscaled->v,loc->br_len_mult->v); */ } loc = loc->next_mixt; } while(loc); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/mixt.h000066400000000000000000000072761263450375500146140ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef MIXT_H #define MIXT_H #include "utilities.h" void MIXT_Connect_Edges_To_Next_Prev_Child_Parent(t_tree *tree); void MIXT_Connect_Nodes_To_Next_Prev_Child_Parent(t_tree *tree); void MIXT_Connect_Sprs_To_Next_Prev_Child_Parent(t_tree *tree); void MIXT_Turn_Branches_OnOff(int onoff,t_tree *tree); phydbl *MIXT_Get_Lengths_Of_This_Edge(t_edge *mixt_b, t_tree *tree); void MIXT_Set_Lengths_Of_This_Edge(phydbl *lens,t_edge *mixt_b, t_tree *tree); void MIXT_Post_Order_Lk(t_node *mixt_a,t_node *mixt_d,t_tree *mixt_tree); void MIXT_Pre_Order_Lk(t_node *mixt_a,t_node *mixt_d,t_tree *mixt_tree); phydbl MIXT_Lk(t_edge *mixt_b,t_tree *mixt_tree); void MIXT_Update_P_Lk(t_tree *mixt_tree,t_edge *mixt_b,t_node *mixt_d); void MIXT_Update_PMat_At_Given_Edge(t_edge *mixt_b,t_tree *mixt_tree); int *MIXT_Get_Number_Of_Classes_In_All_Mixtures(t_tree *mixt_tree); t_tree **MIXT_Record_All_Mixtures(t_tree *mixt_tree); void MIXT_Break_All_Mixtures(int *c_max,t_tree *mixt_tree); void MIXT_Reconnect_All_Mixtures(t_tree **tree_list,t_tree *mixt_tree); int *MIXT_Record_Has_Invariants(t_tree *mixt_tree); void MIXT_Reset_Has_Invariants(int *has_invariants,t_tree *mixt_tree); void MIXT_Check_Invar_Setup(t_tree *mixt_tree); void MIXT_Prune_Subtree(t_node *mixt_a,t_node *mixt_d,t_edge **mixt_target,t_edge **mixt_residual,t_tree *mixt_tree); void MIXT_Graft_Subtree(t_edge *mixt_target,t_node *mixt_link,t_edge *mixt_residual,t_tree *mixt_tree); void MIXT_Br_Len_Brent(phydbl prop_min, phydbl prop_max,t_edge *mixt_b, t_tree *mixt_tree); void MIXT_Check_Number_Of_Invar_Classes(t_tree *mixt_tree); void MIXT_Prepare_Tree_For_Lk(t_tree *tree); void MIXT_Check_Invar_Struct_In_Each_Partition_Elem(t_tree *mixt_tree); void MIXT_Check_RAS_Struct_In_Each_Partition_Elem(t_tree *mixt_tree); void MIXT_Br_Len_Involving_Invar(t_tree *mixt_tree); void MIXT_Br_Len_Not_Involving_Invar(t_tree *mixt_tree); phydbl MIXT_Unscale_Br_Len_Multiplier_Tree(t_tree *mixt_tree); phydbl MIXT_Rescale_Br_Len_Multiplier_Tree(t_tree *mixt_tree); void MIXT_Set_Alias_Subpatt(int onoff, t_tree *mixt_tree); phydbl Lk_Core(int state, int ambiguity_check, t_edge *b, t_tree *tree); void MIXT_Check_Single_Edge_Lens(t_tree *mixt_tree); void MIXT_Update_Eigen(t_mod *mixt_mod); int MIXT_Pars(t_edge *mixt_b, t_tree *mixt_tree); void MIXT_Set_Pars_Thresh(t_tree *mixt_tree); void MIXT_Bootstrap(char *best_tree, xml_node *root); void MIXT_Chain_All(t_tree *mixt_tree); void MIXT_Chain_String(t_string *curr, t_string *next); void MIXT_Chain_Scalar_Dbl(scalar_dbl *curr, scalar_dbl *next); void MIXT_Chain_Rmat(t_rmat *curr, t_rmat *next); void MIXT_Chain_Rmat(t_rmat *curr, t_rmat *next); void MIXT_Chain_Efrq(t_efrq *curr, t_efrq *next); void MIXT_Chain_RAS(t_ras *curr, t_ras *next); void MIXT_Chain_Eigen(eigen *curr, eigen *next); void MIXT_Chain_Vector_Dbl(vect_dbl *curr, vect_dbl *next); void MIXT_Chain_Sprs(t_tree *tree); void MIXT_Chain_Nodes(t_tree *tree); void MIXT_Chain_Edges(t_tree *tree); void MIXT_Chain_Triplets(t_tree *tree); phydbl MIXT_Get_Mean_Edge_Len(t_edge *mixt_b, t_tree *tree); phydbl MIXT_Get_Sum_Chained_Scalar_Dbl(scalar_dbl *s); phydbl MIXT_Get_Sum_Of_Probas_Across_Mixtures(phydbl r_mat_weight_sum, phydbl e_frq_weight_sum, t_tree *mixt_tree); phydbl MIXT_Rescale_Free_Rate_Tree(t_tree *mixt_tree); void MIXT_Set_Br_Len_Var(t_tree *mixt_tree); void MIXT_Optimize_Br_Len_Multiplier(t_tree *mixt_tree); void MIXT_Update_Br_Len_Multipliers(t_mod *mod); #endif phyml-3.2.0/src/models.c000066400000000000000000001175261263450375500151110ustar00rootroot00000000000000/* PhyML : a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "models.h" #ifdef BEAGLE #include "beagle_utils.h" #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Handle any number of states (>1) */ void PMat_JC69(phydbl l, int pos, phydbl *Pij, t_mod *mod) { int ns; int i,j; ns = mod->ns; For(i,ns) Pij[pos+ ns*i+i] = 1. - ((ns - 1.)/ns)*(1. - EXP(-ns*l/(ns - 1.))); For(i,ns-1) for(j=i+1;j A*/ /*1 => C*/ /*2 => G*/ /*3 => T*/ /* Ts -> transition*/ /* Tv -> transversion*/ aux = -2*l/(kappa+2); e1 = (phydbl)EXP(aux *2); e2 = (phydbl)EXP(aux *(kappa+1)); Tv = .25*(1-e1); Ts = .25*(1+e1-2*e2); Pij[pos+ 4*0+0] = Pij[pos+ 4*1+1] = Pij[pos+ 4*2+2] = Pij[pos+ 4*3+3] = 1.-Ts-2.*Tv; Pij[pos+ 4*0+1] = Pij[pos+ 4*1+0] = Tv; Pij[pos+ 4*0+2] = Pij[pos+ 4*2+0] = Ts; Pij[pos+ 4*0+3] = Pij[pos+ 4*3+0] = Tv; Pij[pos+ 4*1+2] = Pij[pos+ 4*2+1] = Tv; Pij[pos+ 4*1+3] = Pij[pos+ 4*3+1] = Ts; Pij[pos+ 4*2+3] = Pij[pos+ 4*3+2] = Tv; For(i,4) For(j,4) if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij) { int i,j; phydbl e1,e2,e3; phydbl a1t,a2t,bt; phydbl A,C,G,T,R,Y; phydbl kappa1,kappa2; A = mod->e_frq->pi->v[0]; C = mod->e_frq->pi->v[1]; G = mod->e_frq->pi->v[2]; T = mod->e_frq->pi->v[3]; R = A+G; Y = T+C; if(mod->kappa->v < .0) mod->kappa->v = 1.0e-5; if((mod->whichmodel != F84) && (mod->whichmodel != TN93)) mod->lambda->v = 1.; else if(mod->whichmodel == F84) { mod->lambda->v = Get_Lambda_F84(mod->e_frq->pi->v,&mod->kappa->v); } kappa2 = mod->kappa->v*2./(1.+mod->lambda->v); kappa1 = kappa2 * mod->lambda->v; bt = l/(2.*(A*G*kappa1+C*T*kappa2+R*Y)); a1t = kappa1; a2t = kappa2; a1t*=bt; a2t*=bt; e1 = (phydbl)EXP(-a1t*R-bt*Y); e2 = (phydbl)EXP(-a2t*Y-bt*R); e3 = (phydbl)EXP(-bt); /*A->A*/Pij[pos + 4*0+0] = A+Y*A/R*e3+G/R*e1; /*A->C*/Pij[pos + 4*0+1] = C*(1-e3); /*A->G*/Pij[pos + 4*0+2] = G+Y*G/R*e3-G/R*e1; /*A->T*/Pij[pos + 4*0+3] = T*(1-e3); /*C->A*/Pij[pos + 4*1+0] = A*(1-e3); /*C->C*/Pij[pos + 4*1+1] = C+R*C/Y*e3+T/Y*e2; /*C->G*/Pij[pos + 4*1+2] = G*(1-e3); /*C->T*/Pij[pos + 4*1+3] = T+R*T/Y*e3-T/Y*e2; /*G->A*/Pij[pos + 4*2+0] = A+Y*A/R*e3-A/R*e1; /*G->C*/Pij[pos + 4*2+1] = C*(1-e3); /*G->G*/Pij[pos + 4*2+2] = G+Y*G/R*e3+A/R*e1; /*G->T*/Pij[pos + 4*2+3] = T*(1-e3); /*T->A*/Pij[pos + 4*3+0] = A*(1-e3); /*T->C*/Pij[pos + 4*3+1] = C+R*C/Y*e3-C/Y*e2; /*T->G*/Pij[pos + 4*3+2] = G*(1-e3); /*T->T*/Pij[pos + 4*3+3] = T+R*T/Y*e3+C/Y*e2; For(i,4) For(j,4) if(Pij[pos + 4*i+j] < SMALL_PIJ) Pij[pos + 4*i+j] = SMALL_PIJ; /* /\*A->A*\/(*Pij)[0][0] = A+Y*A/R*e3+G/R*e1; */ /* /\*A->C*\/(*Pij)[0][1] = C*(1-e3); */ /* /\*A->G*\/(*Pij)[0][2] = G+Y*G/R*e3-G/R*e1; */ /* /\*A->T*\/(*Pij)[0][3] = T*(1-e3); */ /* /\*C->A*\/(*Pij)[1][0] = A*(1-e3); */ /* /\*C->C*\/(*Pij)[1][1] = C+R*C/Y*e3+T/Y*e2; */ /* /\*C->G*\/(*Pij)[1][2] = G*(1-e3); */ /* /\*C->T*\/(*Pij)[1][3] = T+R*T/Y*e3-T/Y*e2; */ /* /\*G->A*\/(*Pij)[2][0] = A+Y*A/R*e3-A/R*e1; */ /* /\*G->C*\/(*Pij)[2][1] = C*(1-e3); */ /* /\*G->G*\/(*Pij)[2][2] = G+Y*G/R*e3+A/R*e1; */ /* /\*G->T*\/(*Pij)[2][3] = T*(1-e3); */ /* /\*T->A*\/(*Pij)[3][0] = A*(1-e3); */ /* /\*T->C*\/(*Pij)[3][1] = C+R*C/Y*e3-C/Y*e2; */ /* /\*T->G*\/(*Pij)[3][2] = G*(1-e3); */ /* /\*T->T*\/(*Pij)[3][3] = T+R*T/Y*e3+C/Y*e2; */ /* For(i,4) For(j,4) */ /* if((*Pij)[i][j] < SMALL) (*Pij)[i][j] = SMALL; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa) { phydbl A,C,G,T,R,Y,lambda; int kappa_has_changed; A = pi[0]; C = pi[1]; G = pi[2]; T = pi[3]; R = A+G; Y = T+C; if(*kappa < .0) *kappa = 1.0e-5; kappa_has_changed = NO; do { lambda = (Y+(R-Y)/(2.*(*kappa)))/(R-(R-Y)/(2.*(*kappa))); if(lambda < .0) { *kappa += *kappa/10.; kappa_has_changed = YES; } }while(lambda < .0); if(kappa_has_changed) { PhyML_Printf("\n. WARNING: This transition/transversion ratio\n"); PhyML_Printf(" is impossible with these base frequencies!\n"); PhyML_Printf(" The ratio is now set to %.3f\n",*kappa); } return lambda; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /********************************************************************/ /* void PMat_Empirical(phydbl l, t_mod *mod, phydbl ***Pij) */ /* */ /* Computes the substitution probability matrix */ /* from the initial substitution rate matrix and frequency vector */ /* and one specific branch length */ /* */ /* input : l , branch length */ /* input : mod , choosen model parameters, qmat and pi */ /* ouput : Pij , substitution probability matrix */ /* */ /* matrix P(l) is computed as follows : */ /* P(l) = EXP(Q*t) , where : */ /* */ /* Q = substitution rate matrix = Vr*D*inverse(Vr) , where : */ /* */ /* Vr = right eigenvector matrix for Q */ /* D = diagonal matrix of eigenvalues for Q */ /* */ /* t = time interval = l / mr , where : */ /* */ /* mr = mean rate = branch length/time interval */ /* = sum(i)(pi[i]*p(i->j)) , where : */ /* */ /* pi = state frequency vector */ /* p(i->j) = subst. probability from i to a different state */ /* = -Q[ii] , as sum(j)(Q[ij]) +Q[ii] =0 */ /* */ /* the Taylor development of EXP(Q*t) gives : */ /* P(l) = Vr*EXP(D*t) *inverse(Vr) */ /* = Vr*POW(EXP(D/mr),l)*inverse(Vr) */ /* */ /* for performance we compute only once the following matrixes : */ /* Vr, inverse(Vr), EXP(D/mr) */ /* thus each time we compute P(l) we only have to : */ /* make 20 times the operation POW() */ /* make 2 20x20 matrix multiplications , that is : */ /* 16000 = 2x20x20x20 times the operation * */ /* 16000 = 2x20x20x20 times the operation + */ /* which can be reduced to (the central matrix being diagonal) : */ /* 8400 = 20x20 + 20x20x20 times the operation * */ /* 8000 = 20x20x20 times the operation + */ /********************************************************************/ void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij) { int n = mod->ns; int i, j, k; phydbl *U,*V,*R; phydbl *expt; phydbl *uexpt; expt = mod->eigen->e_val_im; uexpt = mod->eigen->r_e_vect_im; U = mod->eigen->r_e_vect; V = mod->eigen->l_e_vect; R = mod->eigen->e_val; /* exponential of the eigen value matrix */ //Initialize a rate-specific N*N matrix For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0; /* compute POW(EXP(D/mr),l) into mat_eDmrl */ For(k,n) expt[k] = (phydbl)POW(R[k],l); /* multiply Vr*POW(EXP(D/mr),l)*Vi into Pij */ For (i,n) For (k,n) uexpt[i*n+k] = U[i*n+k] * expt[k]; For (i,n) { For (j,n) { For(k,n) { Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]); } /* if(Pij[pos+mod->ns*i+j] < SMALL) Pij[pos+mod->ns*i+j] = SMALL; */ if(Pij[pos+mod->ns*i+j] < SMALL_PIJ) Pij[pos+mod->ns*i+j] = SMALL_PIJ; } #ifndef PHYML phydbl sum; sum = .0; For (j,n) sum += Pij[pos+mod->ns*i+j]; if((sum > 1.+.0001) || (sum < 1.-.0001)) { PhyML_Printf("\n"); PhyML_Printf("\n. Q\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n. U\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n"); PhyML_Printf("\n. V\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n"); PhyML_Printf("\n. Eigen\n"); For(i,n) PhyML_Printf("%E ",expt[i]); PhyML_Printf("\n"); PhyML_Printf("\n. Pij\n"); For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); } PhyML_Printf("\n. sum = %f",sum); if(mod->m4mod) { int i; PhyML_Printf("\n. mod->m4mod->alpha = %f",mod->m4mod->alpha); PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta); For(i,mod->m4mod->n_h) { PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]); } } PhyML_Printf("\n. l=%f",l); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij) { int n; int i, j, k; phydbl *U,*V,*R; phydbl *expt; phydbl *uexpt; phydbl shape; n = mod->ns; expt = mod->eigen->e_val_im; uexpt = mod->eigen->r_e_vect_im; U = mod->eigen->r_e_vect; V = mod->eigen->l_e_vect; R = mod->eigen->e_val; /* exponential of the eigen value matrix */ if(mod->ras->n_catg == 1) shape = 1.E+4; else shape = mod->ras->alpha->v; For(i,n) For(k,n) Pij[pos+mod->ns*i+k] = .0; if(shape < 1.E-10) { PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* Formula 13.42, page 220 of Felsenstein's book ``Inferring Phylogenies'' */ For(k,n) expt[k] = POW(shape/(shape-LOG(R[k])*l),shape); /* multiply Vr*expt*Vi into Pij */ For(i,n) For(k,n) uexpt[i*n+k] = U[i*n+k] * expt[k]; For (i,n) { For (j,n) { For(k,n) { Pij[pos+mod->ns*i+j] += (uexpt[i*n+k] * V[k*n+j]); } if(Pij[pos+mod->ns*i+j] < SMALL_PIJ) Pij[pos+mod->ns*i+j] = SMALL_PIJ; } #ifdef DEBUG phydbl sum; sum = .0; For (j,n) sum += Pij[pos+mod->ns*i+j]; if((sum > 1.+.0001) || (sum < 1.-.0001)) { PhyML_Printf("\n"); PhyML_Printf("\n. Q\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n. U\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n"); PhyML_Printf("\n. V\n"); For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } PhyML_Printf("\n"); PhyML_Printf("\n. Eigen\n"); For(i,n) PhyML_Printf("%E ",expt[i]); PhyML_Printf("\n"); PhyML_Printf("\n. Pij\n"); For(i,n) { For (j,n) PhyML_Printf("%f ",Pij[pos+mod->ns*i+j]); PhyML_Printf("\n"); } PhyML_Printf("\n. sum = %f",sum); if(mod->m4mod) { int i; PhyML_Printf("\n. mod->m4mod->ras->alpha = %f",mod->m4mod->alpha); PhyML_Printf("\n. mod->m4mod->delta = %f",mod->m4mod->delta); For(i,mod->m4mod->n_h) { PhyML_Printf("\n. mod->m4mod->multipl[%d] = %f",i,mod->m4mod->multipl[i]); } } PhyML_Printf("\n. l=%f",l); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PMat_Zero_Br_Len(t_mod *mod, int pos, phydbl *Pij) { int n = mod->ns; int i, j; For (i,n) For (j,n) Pij[pos+mod->ns*i+j] = .0; For (i,n) Pij[pos+mod->ns*i+i] = 1.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* *Update a rate specific Transition Prob matrix for a given branch-length(already adjusted *with the rate prior to this function being called) * * Pij: the P-matrix that will be adjusted * l : branch length * rate * pos: offset into a specific rate-category * */ void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij) { /* Warning: l is never the log of branch length here */ if(l < 0.0) { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif PMat_Zero_Br_Len(mod,pos,Pij); } else { switch(mod->io->datatype) { case NT : { if(mod->use_m4mod) { PMat_Empirical(l,mod,pos,Pij); } else { if((mod->whichmodel == JC69) || (mod->whichmodel == K80)) { /* PMat_JC69(l,pos,Pij,mod); */ PMat_K80(l,mod->kappa->v,pos,Pij); } else { if( (mod->whichmodel == F81) || (mod->whichmodel == HKY85) || (mod->whichmodel == F84) || (mod->whichmodel == TN93)) { PMat_TN93(l,mod,pos,Pij); } else { #ifdef BEAGLE //when there is no active instance (i.e. when we are building the initial tree) if(UNINITIALIZED == mod->b_inst) { PMat_Empirical(l,mod,pos,Pij); } #else PMat_Empirical(l,mod,pos,Pij); #endif } } break; } case AA : { #ifdef BEAGLE //when there is no active instance (i.e. when we are building the initial tree) if(UNINITIALIZED == mod->b_inst) { PMat_Empirical(l,mod,pos,Pij); } #else PMat_Empirical(l,mod,pos,Pij); #endif break; } default: { PMat_JC69(l,pos,Pij,mod); break; /* PhyML_Printf("\n. Not implemented yet.\n"); */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* break; */ } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int GetDaa (phydbl *daa, phydbl *pi, char *file_name) { /* Get the amino acid distance (or substitution rate) matrix (grantham, dayhoff, jones, etc). */ FILE * fdaa; int i,j, naa; phydbl dmax,dmin; phydbl sum; double val; naa = 20; dmax = .0; dmin = 1.E+40; fdaa = (FILE *)Openfile(file_name,0); for(i=0; idaa[i*naa+j]) dmin=daa[i*naa+j]; } For(i,naa) { /* if(fscanf(fdaa,"%lf",&pi[i])!=1) Exit("\n. err aaRatefile"); */ if(fscanf(fdaa,"%lf",&val)!=1) Exit("\n. err aaRatefile"); pi[i] = (phydbl)val; } sum = 0.0; For(i, naa) sum += pi[i]; if (FABS(1-sum)>1e-4) { PhyML_Printf("\nSum of freq. = %.6f != 1 in aaRateFile\n",sum); exit(-1); } fclose (fdaa); return (0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Qmat_Generic(phydbl *rr, phydbl *pi, int ns, phydbl *qmat) { int i,j; phydbl sum,mr; For(i,ns*ns) qmat[i] = .0; if(rr[(int)(ns*(ns-1)/2)-1] < 0.00001) { PhyML_Printf("\n== rr[%d]=%f",(int)(ns*(ns-1)/2)-1,rr[(int)(ns*(ns-1)/2)-1]); PhyML_Printf("\n== Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* PhyML_Printf("\n"); */ /* For(i,(int)(ns*(ns-1)/2)) */ /* { */ /* PhyML_Printf("\n> rr %d = %f",i,rr[i]); */ /* } */ For(i,(int)(ns*(ns-1)/2)) { rr[i] /= rr[(int)(ns*(ns-1)/2)-1]; } /* Fill the non-diagonal parts */ For(i,ns) { for(j=i+1;j RR_MAX) rr[i] = RR_MAX; For(i,6) if(isnan(rr[i])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); qmat[0*4+1] = (rr[0]*pi[1]); qmat[0*4+2] = (rr[1]*pi[2]); qmat[0*4+3] = (rr[2]*pi[3]); qmat[1*4+0] = (rr[0]*pi[0]); qmat[1*4+2] = (rr[3]*pi[2]); qmat[1*4+3] = (rr[4]*pi[3]); qmat[2*4+0] = (rr[1]*pi[0]); qmat[2*4+1] = (rr[3]*pi[1]); qmat[2*4+3] = (rr[5]*pi[3]); qmat[3*4+0] = (rr[2]*pi[0]); qmat[3*4+1] = (rr[4]*pi[1]); qmat[3*4+2] = (rr[5]*pi[2]); qmat[0*4+0] = -(rr[0]*pi[1]+rr[1]*pi[2]+rr[2]*pi[3]); qmat[1*4+1] = -(rr[0]*pi[0]+rr[3]*pi[2]+rr[4]*pi[3]); qmat[2*4+2] = -(rr[1]*pi[0]+rr[3]*pi[1]+rr[5]*pi[3]); qmat[3*4+3] = -(rr[2]*pi[0]+rr[4]*pi[1]+rr[5]*pi[2]); /* compute diagonal terms of Q and mean rate mr = l/t */ mr = .0; For(i,4) mr += pi[i] * (-qmat[i*4+i]); For(i,16) qmat[i] /= mr; /* int j; */ /* printf("\n"); */ /* printf("\n. rr -- "); */ /* For(i,5) printf(" %15f ",rr[i]); */ /* printf("\n"); */ /* For(i,4) */ /* { */ /* printf("\n. [%15f] \t ",pi[i]); */ /* For(j,4) */ /* { */ /* printf(" %15f ",qmat[i*4+j]); */ /* } */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Qmat_HKY(phydbl kappa, phydbl *pi, phydbl *qmat) { int i; phydbl mr; /* A -> C */ qmat[0*4+1] = (phydbl)(pi[1]); /* A -> G */ qmat[0*4+2] = (phydbl)(kappa*pi[2]); /* A -> T */ qmat[0*4+3] = (phydbl)(pi[3]); /* C -> A */ qmat[1*4+0] = (phydbl)(pi[0]); /* C -> G */ qmat[1*4+2] = (phydbl)(pi[2]); /* C -> T */ qmat[1*4+3] = (phydbl)(kappa*pi[3]); /* G -> A */ qmat[2*4+0] = (phydbl)(kappa*pi[0]); /* G -> C */ qmat[2*4+1] = (phydbl)(pi[1]); /* G -> T */ qmat[2*4+3] = (phydbl)(pi[3]); /* T -> A */ qmat[3*4+0] = (phydbl)(pi[0]); /* T -> C */ qmat[3*4+1] = (phydbl)(kappa*pi[1]); /* T -> G */ qmat[3*4+2] = (phydbl)(pi[2]); qmat[0*4+0] = (phydbl)(-(qmat[0*4+1]+qmat[0*4+2]+qmat[0*4+3])); qmat[1*4+1] = (phydbl)(-(qmat[1*4+0]+qmat[1*4+2]+qmat[1*4+3])); qmat[2*4+2] = (phydbl)(-(qmat[2*4+0]+qmat[2*4+1]+qmat[2*4+3])); qmat[3*4+3] = (phydbl)(-(qmat[3*4+0]+qmat[3*4+1]+qmat[3*4+2])); /* compute diagonal terms of Q and mean rate mr = l/t */ mr = .0; For (i,4) mr += pi[i] * (-qmat[i*4+i]); For(i,16) qmat[i] /= mr; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Translate_Custom_Mod_String(t_mod *mod) { int i,j; For(i,6) mod->r_mat->n_rr_per_cat->v[i] = 0; mod->r_mat->n_diff_rr = 0; For(i,6) { For(j,i) { if(mod->custom_mod_string->s[i] == mod->custom_mod_string->s[j]) { break; } } if(i == j) { mod->r_mat->rr_num->v[i] = mod->r_mat->n_diff_rr; mod->r_mat->n_diff_rr++; } else { mod->r_mat->rr_num->v[i] = mod->r_mat->rr_num->v[j]; } mod->r_mat->n_rr_per_cat->v[mod->r_mat->rr_num->v[j]]++; } /* PhyML_Printf("\n"); */ /* For(i,6) PhyML_Printf("%d ",mod->r_mat->rr_num->v[i]); */ /* For(i,mod->r_mat->n_diff_rr) PhyML_Printf("\n. Class %d size %d",i+1,mod->r_mat->n_rr_per_cat->v[i]); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Update rate across sites distribution settings. void Update_RAS(t_mod *mod) { phydbl sum; int i; if(mod->ras->free_mixt_rates == NO) DiscreteGamma(mod->ras->gamma_r_proba->v, mod->ras->gamma_rr->v, mod->ras->alpha->v, mod->ras->alpha->v, mod->ras->n_catg, mod->ras->gamma_median); else { if(mod->ras->sort_rate_classes == YES) { Qksort(mod->ras->gamma_r_proba_unscaled->v,NULL,0,mod->ras->n_catg-1); // Unscaled class frequencies sorted in increasing order // Update class frequencies For(i,mod->ras->n_catg) { if(!i) mod->ras->gamma_r_proba->v[i] = mod->ras->gamma_r_proba_unscaled->v[i] / (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]) ; else mod->ras->gamma_r_proba->v[i] = (mod->ras->gamma_r_proba_unscaled->v[i] - mod->ras->gamma_r_proba_unscaled->v[i-1]) / (mod->ras->gamma_r_proba_unscaled->v[mod->ras->n_catg-1]) ; } } else { sum = 0.0; For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba_unscaled->v[i]; For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i] = mod->ras->gamma_r_proba_unscaled->v[i] / sum; } do { sum = .0; For(i,mod->ras->n_catg) { if(mod->ras->gamma_r_proba->v[i] < 0.01) mod->ras->gamma_r_proba->v[i]=0.01; if(mod->ras->gamma_r_proba->v[i] > 0.99) mod->ras->gamma_r_proba->v[i]=0.99; sum += mod->ras->gamma_r_proba->v[i]; } For(i,mod->ras->n_catg) mod->ras->gamma_r_proba->v[i]/=sum; } while((sum > 1.01) || (sum < 0.99)); // Update class rates sum = .0; For(i,mod->ras->n_catg) sum += mod->ras->gamma_r_proba->v[i] * mod->ras->gamma_rr_unscaled->v[i]; if(mod->ras->normalise_rr == YES) For(i,mod->ras->n_catg) mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i]/sum; else For(i,mod->ras->n_catg) mod->ras->gamma_rr->v[i] = mod->ras->gamma_rr_unscaled->v[i] * mod->ras->free_rate_mr->v; /* printf("\n"); */ /* For(i,mod->ras->n_catg) */ /* printf("\nx %3d %12f %12f xx %12f %12f", */ /* mod->ras->normalise_rr, */ /* mod->ras->gamma_r_proba->v[i], */ /* mod->ras->gamma_rr->v[i], */ /* mod->ras->gamma_r_proba_unscaled->v[i], */ /* mod->ras->gamma_rr_unscaled->v[i]); */ } #ifdef BEAGLE if(UNINITIALIZED != mod->b_inst) update_beagle_ras(mod); #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Efrq(t_mod *mod) { phydbl sum; int i; if((mod->io->datatype == NT) && (mod->s_opt->opt_state_freq)) { sum = .0; For(i,mod->ns) sum += FABS(mod->e_frq->pi_unscaled->v[i]); For(i,mod->ns) mod->e_frq->pi->v[i] = FABS(mod->e_frq->pi_unscaled->v[i])/sum; do { sum = .0; For(i,mod->ns) { if(mod->e_frq->pi->v[i] < 0.01) mod->e_frq->pi->v[i]=0.01; if(mod->e_frq->pi->v[i] > 0.99) mod->e_frq->pi->v[i]=0.99; sum += mod->e_frq->pi->v[i]; } For(i,mod->ns) { mod->e_frq->pi->v[i]/=sum; } } while((sum > 1.01) || (sum < 0.99)); #ifdef BEAGLE if(UNINITIALIZED != mod->b_inst) update_beagle_efrqs(mod); #endif } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Model_Parameters(t_mod *mod) { Update_RAS(mod); Update_Efrq(mod); Update_Eigen(mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Eigen(t_mod *mod) { int result, n_iter; phydbl scalar; int i; if(mod->is_mixt_mod) { MIXT_Update_Eigen(mod); return; } if(mod->update_eigen) { //Update the Q-matrix first before computing the Eigen(because the Eigen is computed based on the Q-matrix) if(mod->use_m4mod == NO) { if(mod->io->datatype == NT) { if(mod->whichmodel == GTR) Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); else if(mod->whichmodel == CUSTOM) Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); else if(mod->whichmodel == HKY85) Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); else /* Any other nucleotide-based t_mod */ Update_Qmat_HKY(mod->kappa->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); } } else { M4_Update_Qmat(mod->m4mod,mod); } //Now compute the Eigen scalar = 1.0; n_iter = 0; result = 0; For(i,mod->ns*mod->ns) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i]; /* compute eigenvectors/values */ /* if(!EigenRealGeneral(mod->eigen->size,mod->r_mat->qmat,mod->eigen->e_val, */ /* mod->eigen->e_val_im, mod->eigen->r_e_vect, */ /* mod->eigen->space_int,mod->eigen->space)) */ if(!Eigen(1,mod->r_mat->qmat_buff->v,mod->eigen->size,mod->eigen->e_val, mod->eigen->e_val_im,mod->eigen->r_e_vect, mod->eigen->r_e_vect_im,mod->eigen->space)) { /* compute inverse(Vr) into Vi */ For (i,mod->ns*mod->ns) mod->eigen->l_e_vect[i] = mod->eigen->r_e_vect[i]; while(!Matinv(mod->eigen->l_e_vect, mod->eigen->size, mod->eigen->size,YES)) { PhyML_Printf("\n== Trying Q<-Q*scalar and then Root<-Root/scalar to fix this...\n"); scalar += scalar / 3.; For(i,mod->eigen->size*mod->eigen->size) mod->r_mat->qmat_buff->v[i] = mod->r_mat->qmat->v[i]; For(i,mod->eigen->size*mod->eigen->size) mod->r_mat->qmat_buff->v[i] *= scalar; result = Eigen(1,mod->r_mat->qmat_buff->v,mod->eigen->size,mod->eigen->e_val, mod->eigen->e_val_im,mod->eigen->r_e_vect, mod->eigen->r_e_vect_im,mod->eigen->space); if (result == -1) { PhyML_Printf("\n== Eigenvalues/vectors computation did not converge: computation cancelled."); Exit("\n"); } else if (result == 1) { PhyML_Printf("\n== Complex eigenvalues/vectors: computation cancelled."); Exit("\n"); } For (i,mod->eigen->size*mod->eigen->size) mod->eigen->l_e_vect[i] = mod->eigen->r_e_vect[i]; n_iter++; if(n_iter > 100) { PhyML_Printf("\n== Cannot work out eigen vectors."); Exit("\n"); } }; For(i,mod->eigen->size) mod->eigen->e_val[i] /= scalar; /* compute the diagonal terms of EXP(D) */ For(i,mod->ns) mod->eigen->e_val[i] = (phydbl)EXP(mod->eigen->e_val[i]); /* int j; */ /* double *U,*V,*R; */ /* double *expt; */ /* double *uexpt; */ /* int n; */ /* expt = mod->eigen->e_val_im; */ /* uexpt = mod->eigen->r_e_vect_im; */ /* U = mod->eigen->r_e_vect; */ /* V = mod->eigen->l_e_vect; */ /* R = mod->eigen->e_val; /\* exponential of the eigen value matrix *\/ */ /* n = mod->ns; */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n. Q\n"); */ /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",mod->eigen->q[i*n+j]); PhyML_Printf("\n"); } */ /* PhyML_Printf("\n. U\n"); */ /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",U[i*n+j]); PhyML_Printf("\n"); } */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n. V\n"); */ /* For(i,n) { For(j,n) PhyML_Printf("%7.3f ",V[i*n+j]); PhyML_Printf("\n"); } */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n. Eigen\n"); */ /* For(i,n) PhyML_Printf("%E ",mod->eigen->e_val[i]); */ /* PhyML_Printf("\n"); */ /* Exit("\n"); */ #ifdef BEAGLE //Recall that BEAGLE is initialized *after* all the model parameters are set //IOW, this function may be called before BEAGLE is initialized ("chicken-egg") if(UNINITIALIZED != mod->b_inst) update_beagle_eigen(mod); #endif } else { PhyML_Printf("\n. Eigenvalues/vectors computation does not converge : computation cancelled"); Warn_And_Exit("\n"); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Switch_From_M4mod_To_Mod(t_mod *mod) { int i; mod->use_m4mod = 0; mod->ns = mod->m4mod->n_o; For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i]; mod->eigen->size = mod->ns; Switch_Eigen(YES,mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact, t_mod *mod) { int dim; int i,j,k; phydbl *uexpt,*imbd; dim = mod->eigen->size; uexpt = mod->eigen->r_e_vect_im; imbd = mod->eigen->e_val_im; /* Get the eigenvalues of Q (not the exponentials) */ For(i,dim) imbd[i] = LOG(mod->eigen->e_val[i]); /* Multiply them by the scaling factor */ For(i,dim) imbd[i] *= scaling_fact; For(i,dim) imbd[i] *= -scale; For(i,dim) imbd[i] += 1.0; For(i,dim) imbd[i] = POW(imbd[i],-shape); For(i,dim) For(k,dim) uexpt[i*dim+k] = mod->eigen->r_e_vect[i*dim+k] * imbd[k]; For(i,dim) For(k,dim) Pij[dim*i+k] = .0; For(i,dim) { For(j,dim) { For(k,dim) { Pij[dim*i+j] += (uexpt[i*dim+k] * mod->eigen->l_e_vect[k*dim+j]); } if(Pij[dim*i+j] < SMALL_PIJ) Pij[dim*i+j] = SMALL_PIJ; } } /* printf("\n. shape = %G scale = %G %f",shape,scale,Pij[1]); */ /* printf("\n. Pij: %f",Pij[1]); */ /* printf("\n. Pmat"); */ /* For(i,dim) */ /* { */ /* printf("\n"); */ /* For(j,dim) */ /* { */ /* printf("%12f ",Pij[i*dim+j]); */ /* } */ /* } */ /* Exit("\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Switch_From_Mod_To_M4mod(t_mod *mod) { int i; mod->use_m4mod = 1; mod->ns = mod->m4mod->n_o * mod->m4mod->n_h; For(i,mod->ns) mod->e_frq->pi->v[i] = mod->m4mod->o_fq[i%mod->m4mod->n_o] * mod->m4mod->h_fq[i/mod->m4mod->n_o]; mod->eigen->size = mod->ns; Switch_Eigen(YES,mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct) { phydbl *pi,*mod_pi; int i,j,k; phydbl dist; phydbl sum; phydbl sum_ev; phydbl *F_phydbl; /* TO DO : call eigen decomposition function for all nt models */ F_phydbl = (phydbl *)mCalloc(eigen_struct->size*eigen_struct->size,sizeof(phydbl)); pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); mod_pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); For(i,mod->ns) mod_pi[i] = mod->e_frq->pi->v[i]; sum = .0; For(i,eigen_struct->size) { For(j,eigen_struct->size) { pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.; sum += F[eigen_struct->size*i+j]; } } Make_Symmetric(&F,eigen_struct->size); Divide_Mat_By_Vect(&F,mod->e_frq->pi->v,eigen_struct->size); /* Eigen decomposition of pi^{-1} x F */ For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j]; if(Eigen(1,F_phydbl,mod->eigen->size,mod->eigen->e_val, mod->eigen->e_val_im,mod->eigen->r_e_vect, mod->eigen->r_e_vect_im,mod->eigen->space)) { For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); Free(pi); Free(mod_pi); return -1.; } /* Get the left eigen vector of pi^{-1} x F */ For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i]; if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0) { For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; Update_Qmat_GTR(mod->r_mat->rr->v, mod->r_mat->rr_val->v, mod->r_mat->rr_num->v, mod->e_frq->pi->v, mod->r_mat->qmat->v); Free(pi); Free(mod_pi); return -1.; } /* LOG of eigen values */ For(i,eigen_struct->size) { /* if(eigen_struct->e_val[i] < 0.0) eigen_struct->e_val[i] = 0.0001; */ eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]); } /* Matrix multiplications LOG(pi^{-1} x F) */ For(i,eigen_struct->size) For(j,eigen_struct->size) eigen_struct->r_e_vect[eigen_struct->size*i+j] = eigen_struct->r_e_vect[eigen_struct->size*i+j] * eigen_struct->e_val[j]; For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0; For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size) F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j]; /* Trace */ dist = .0; For(i,eigen_struct->size) dist+=F[eigen_struct->size*i+i]; sum_ev = .0; For(i,mod->ns) sum_ev += mod->eigen->e_val[i]; /* dist /= sum_ev; */ dist /= -4.; /* For(i,mod->ns) mod->e_frq->pi->v[i] = mod_pi[i]; */ /* Update_Qmat_GTR(mod); */ Free(pi); Free(mod_pi); Free(F_phydbl); if(isnan(dist)) return -1.; return dist; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct) { phydbl *pi; int i,j,k; phydbl dist; phydbl sum; phydbl *F_phydbl; pi = (phydbl *)mCalloc(eigen_struct->size,sizeof(phydbl)); F_phydbl = (phydbl *)mCalloc(eigen_struct->size*eigen_struct->size,sizeof(phydbl)); /* /\* Waddell and Steel's example *\/ */ /* F[4*0+0] = 1415./4898.; F[4*0+1] = 8./4898.; F[4*0+2] = 55./4898.; F[4*0+3] = 2./4898.; */ /* F[4*1+0] = 4./4898.; F[4*1+1] = 1371./4898.; F[4*1+2] = 1./4898.; F[4*1+3] = 144./4898.; */ /* F[4*2+0] = 73./4898.; F[4*2+1] = 0./4898.; F[4*2+2] = 578./4898.; F[4*2+3] = 0./4898.; */ /* F[4*3+0] = 3./4898.; F[4*3+1] = 117./4898.; F[4*3+2] = 1./4898.; F[4*3+3] = 1126./4898.; */ sum = 0.0; For(i,eigen_struct->size) { For(j,eigen_struct->size) { pi[i] += (F[eigen_struct->size*i+j] + F[eigen_struct->size*j+i])/2.; sum += F[eigen_struct->size*i+j]; } } /* /\* Jukes and Cantor correction *\/ */ /* sum = .0; */ /* For(i,eigen_struct->size) sum += F[eigen_struct->size*i+i]; */ /* sum = 1.-sum; */ /* For(i,eigen_struct->size*eigen_struct->size) F[i] = sum/12.; */ /* For(i,eigen_struct->size) F[eigen_struct->size*i+i] = (1.-sum)/4.; */ /* For(i,eigen_struct->size) pi[i] = 1./(phydbl)eigen_struct->size; */ Make_Symmetric(&F,eigen_struct->size); Divide_Mat_By_Vect(&F,pi,eigen_struct->size); /* Eigen decomposition of pi^{-1} x F */ For(i,eigen_struct->size) For(j,eigen_struct->size) F_phydbl[eigen_struct->size*i+j] = F[eigen_struct->size*i+j]; if(Eigen(1,F_phydbl,eigen_struct->size,eigen_struct->e_val, eigen_struct->e_val_im,eigen_struct->r_e_vect, eigen_struct->r_e_vect_im,eigen_struct->space)) { Free(pi); return -1.; } /* Get the left eigen vector of pi^{-1} x F */ For(i,eigen_struct->size*eigen_struct->size) eigen_struct->l_e_vect[i] = eigen_struct->r_e_vect[i]; if(!Matinv(eigen_struct->l_e_vect,eigen_struct->size,eigen_struct->size,YES)<0) {Free(pi); return -1.;} /* Equation (3) + inverse of the moment generating function for the gamma distribution (see Waddell & Steel, 1997) */ For(i,eigen_struct->size) { if(eigen_struct->e_val[i] < 0.0) { eigen_struct->e_val[i] = 0.0001; } if(alpha < .0) eigen_struct->e_val[i] = (phydbl)LOG(eigen_struct->e_val[i]); else eigen_struct->e_val[i] = alpha * (1. - (phydbl)POW(eigen_struct->e_val[i],-1./alpha)); } /* Matrix multiplications pi x LOG(pi^{-1} x F) */ For(i,eigen_struct->size) For(j,eigen_struct->size) eigen_struct->r_e_vect[eigen_struct->size*i+j] = eigen_struct->r_e_vect[eigen_struct->size*i+j] * eigen_struct->e_val[j]; For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] = .0; For(i,eigen_struct->size) For(j,eigen_struct->size) For(k,eigen_struct->size) F[eigen_struct->size*i+j] += eigen_struct->r_e_vect[eigen_struct->size*i+k] * eigen_struct->l_e_vect[eigen_struct->size*k+j]; For(i,eigen_struct->size) For(j,eigen_struct->size) F[eigen_struct->size*i+j] *= pi[i]; /* Trace */ dist = .0; For(i,eigen_struct->size) dist-=F[eigen_struct->size*i+i]; /* PhyML_Printf("\nDIST = %f\n",dist); Exit("\n"); */ Free(pi); Free(F_phydbl); if(isnan(dist)) return -1.; return dist; } phyml-3.2.0/src/models.h000066400000000000000000000032401263450375500151010ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef MODELS_H #define MODELS_H #include "utilities.h" #include "eigen.h" #include "free.h" #include "stats.h" #include "mixt.h" void PMat(phydbl l, t_mod *mod, int pos, phydbl *Pij); void PMat_K80(phydbl l,phydbl kappa, int pos, phydbl *Pij); void PMat_TN93(phydbl l, t_mod *mod, int pos, phydbl *Pij); void PMat_Empirical(phydbl l, t_mod *mod, int pos, phydbl *Pij); void PMat_Zero_Br_Len(t_mod *mod, int pos, phydbl *Pij); void PMat_Gamma(phydbl l, t_mod *mod, int pos, phydbl *Pij); int GetDaa (phydbl *daa, phydbl *pi, char *file_name); void Update_Qmat_GTR(phydbl *rr, phydbl *rr_val, int *rr_num, phydbl *pi, phydbl *qmat); void Update_Qmat_HKY(phydbl kappa, phydbl *pi, phydbl *qmat); void Update_Qmat_Generic(phydbl *rr, phydbl *pi, int ns, phydbl *qmat); void Translate_Custom_Mod_String(t_mod *mod); void Set_Model_Parameters(t_mod *mod); phydbl GTR_Dist(phydbl *F, phydbl alpha, eigen *eigen_struct); phydbl General_Dist(phydbl *F, t_mod *mod, eigen *eigen_struct); void Switch_From_Mod_To_M4mod(t_mod *mod); void Switch_From_M4mod_To_Mod(t_mod *mod); void PMat_JC69(phydbl l, int pos, phydbl *Pij, t_mod *mod); phydbl Get_Lambda_F84(phydbl *pi, phydbl *kappa); void Update_Eigen(t_mod *mod); void Update_RAS(t_mod *mod); void Update_Efrq(t_mod *mod); void PMat_MGF_Gamma(phydbl *Pij, phydbl shape, phydbl scale, phydbl scaling_fact, t_mod *mod); #endif phyml-3.2.0/src/mpi_boot.c000066400000000000000000000412761263450375500154340ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "mpi_boot.h" /* #ifdef MPI */ /*********************************************************/ void Bootstrap_MPI(t_tree *tree) { int *site_num, n_site; int replicate,j,k; int position, init_len, nbRep; calign *boot_data; t_tree *boot_tree; t_mod *boot_mod; matrix *boot_mat; char *s; MPI_Status Stat; int randomRecv, bootRecv, nbElem, i; int *score_par, *score_tot; char *bootStr, *t; randomRecv = nbElem = bootRecv = 0; tree->print_boot_val = 1; tree->print_alrt_val = 0; boot_tree = NULL; site_num = (int *)mCalloc(tree->data->init_len,sizeof(int)); Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); n_site = 0; For(j,tree->data->crunch_len) For(k,tree->data->wght[j]) { site_num[n_site] = j; n_site++; } boot_data = Copy_Cseq(tree->data,tree->io); if (Global_myRank == 0) PhyML_Printf("\n. Non parametric bootstrap analysis \n"); //number of bootstraps for each process if (tree->mod->bootstrap%Global_numTask != 0) { nbRep = (tree->mod->bootstrap / Global_numTask) + 1; tree->mod->bootstrap = nbRep * Global_numTask; if (Global_myRank == 0) { PhyML_Printf("\n. The number of replicates is not a multiple of %d CPUs.\n", Global_numTask); PhyML_Printf("\n. Will run %d replicates analysis.\n", tree->mod->bootstrap); } } else nbRep = tree->mod->bootstrap/Global_numTask; //Bip score if (Global_myRank == 0) { score_tot = (int *)mCalloc((2*tree->n_otu - 3),sizeof(int)); For(i,2*tree->n_otu-3) score_tot[i] = 0; } else score_tot = NULL; score_par = (int *)mCalloc((2*tree->n_otu - 3),sizeof(int)); For(i,2*tree->n_otu-3) score_par[i] = 0; if (Global_myRank == 0) PhyML_Printf("\n ["); For(replicate, nbRep) { For(j,boot_data->crunch_len) boot_data->wght[j] = 0; // Send random data to other process if (Global_myRank == 0) { // Compute number of data to send if (tree->mod->bootstrap - randomRecv > Global_numTask) nbElem = Global_numTask; else nbElem = tree->mod->bootstrap - randomRecv; For(i,nbElem) { For(j,boot_data->crunch_len) boot_data->wght[j] = 0; init_len = 0; // Create random data For(j,boot_data->init_len) { position = Rand_Int(0,(int)(tree->data->init_len-1.0)); boot_data->wght[site_num[position]] += 1; init_len++; } if (init_len != tree->data->init_len) { MPI_Finalize(); Warn_And_Exit("\n== Pb. when copying sequences...\n"); } // Send random data to other process, not to current process if (i < nbElem-1) { MPI_Ssend (boot_data->wght, boot_data->crunch_len, MPI_INT, i+1, Global_myRank, MPI_COMM_WORLD); #ifdef MPI_DEBUG fprintf (stderr, "\ntask %d, sending random to %d done\n", Global_myRank, i+1); fflush(stderr); #endif } randomRecv++; } } else { MPI_Recv (boot_data->wght, boot_data->crunch_len, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &Stat); #ifdef MPI_DEBUG fprintf (stderr, "\ntask %d, receiving random from task %d done\n", Global_myRank, Stat.MPI_SOURCE); fflush(stderr); #endif } init_len = 0; For(j,boot_data->crunch_len) init_len += boot_data->wght[j]; if(init_len != tree->data->init_len) { MPI_Finalize(); Warn_And_Exit("\n== Pb when copying sequences\n"); } (tree->mod->io->datatype == NT)? (Get_Base_Freqs(boot_data)): (Get_AA_Freqs(boot_data)); if(tree->io->random_boot_seq_order) Randomize_Sequence_Order(boot_data); Set_D_States(boot_data,tree->io->datatype,tree->io->state_len); boot_mod = Copy_Model(tree->mod); boot_mod->s_opt = tree->mod->s_opt; /* WARNING: re-using the same address here instead of creating a copying requires to leave the value of s_opt unchanged during the boostrap. */ boot_mod->io = tree->io; /* WARNING: re-using the same address here instead of creating a copying requires to leave the value of io unchanged during the boostrap. */ Init_Model(boot_data,boot_mod,tree->io); if(tree->io->mod->use_m4mod) M4_Init_Model(boot_mod->m4mod,boot_data,boot_mod); if(tree->io->in_tree == 2) { switch(tree->io->tree_file_format) { case PHYLIP: { rewind(tree->io->fp_in_tree); boot_tree = Read_Tree_File_Phylip(tree->io->fp_in_tree); break; } case NEXUS: { PhyML_Printf("\n. Unfortunately, PhyML cannot read NEXUS files and perform a bootstrap analysis."); PhyML_Printf("\n. Please use the PHYLIP format.."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } default: { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } } else { boot_mat = ML_Dist(boot_data,boot_mod); boot_mat->tree = Make_Tree_From_Scratch(boot_data->n_otu,boot_data); Fill_Missing_Dist(boot_mat); Bionj(boot_mat); boot_tree = boot_mat->tree; boot_tree->mat = boot_mat; } boot_tree->mod = boot_mod; boot_tree->io = tree->io; boot_tree->data = boot_data; boot_tree->mod->s_opt->print = 0; boot_tree->n_pattern = boot_tree->data->crunch_len; boot_tree->io->print_site_lnl = 0; boot_tree->io->print_trace = 0; Set_Both_Sides(YES,boot_tree); if((boot_tree->mod->s_opt->random_input_tree) && (boot_tree->mod->s_opt->topo_search == SPR_MOVE)) Random_Tree(boot_tree); Connect_CSeqs_To_Nodes(boot_data,boot_tree->io,boot_tree); Share_Lk_Struct(tree,boot_tree); Share_Spr_Struct(tree,boot_tree); Share_Pars_Struct(tree,boot_tree); Fill_Dir_Table(boot_tree); Update_Dirs(boot_tree); if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(boot_tree); else Init_P_Lk_Tips_Int(boot_tree); Init_Ui_Tips(boot_tree); Init_P_Pars_Tips(boot_tree); Br_Len_Not_Involving_Invar(boot_tree); if(boot_tree->mod->s_opt->opt_topo) { if(boot_tree->mod->s_opt->topo_search == NNI_MOVE) { Simu_Loop(boot_tree); } else if((boot_tree->mod->s_opt->topo_search == SPR_MOVE) || (boot_tree->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR)) { Speed_Spr_Loop(boot_tree); } } else { if(boot_tree->mod->s_opt->opt_subst_param || boot_tree->mod->s_opt->opt_bl) Round_Optimize(boot_tree,boot_tree->data,ROUND_MAX); else Lk(NULL,boot_tree); } Free_Bip(boot_tree); Alloc_Bip(boot_tree); Match_Tip_Numbers(tree,boot_tree); Get_Bip(boot_tree->a_nodes[0], boot_tree->a_nodes[0]->v[0], boot_tree); Compare_Bip(tree,boot_tree,NO); Br_Len_Involving_Invar(boot_tree); if(tree->io->print_boot_trees) { s = Write_Tree(boot_tree,NO); t=(char *)mCalloc(T_MAX_LINE,sizeof(char)); Print_Fp_Out_Lines_MPI(boot_tree, tree->io, replicate+1, t); // Get bootstrap trees from other process and write to boot file if (Global_myRank == 0) { fprintf(tree->io->fp_out_boot_tree,"%s\n",s); fprintf(tree->io->fp_out_boot_stats,"%s\n",t); bootRecv++; PhyML_Printf("."); if(!((bootRecv)%tree->io->boot_prog_every)) { PhyML_Printf("] %4d/%4d\n ",bootRecv,tree->mod->bootstrap); if(bootRecv != tree->mod->bootstrap) PhyML_Printf("["); } // Compute number of bootstraps to receive if (tree->mod->bootstrap - bootRecv > Global_numTask) nbElem = Global_numTask; else nbElem = tree->mod->bootstrap - bootRecv + 1; bootStr=(char *)mCalloc(T_MAX_LINE,sizeof(char)); for (i=1; iio->fp_out_boot_tree,"%s\n", bootStr); if (Stat.MPI_TAG == BootStatTag) fprintf(tree->io->fp_out_boot_stats,"%s\n", bootStr); MPI_Recv (bootStr, T_MAX_LINE, MPI_CHAR, i, MPI_ANY_TAG, MPI_COMM_WORLD, &Stat); #ifdef MPI_DEBUG fprintf (stderr, "\ntask %d, receiving bootstrap from task %d tag %d done\n", Global_myRank, Stat.MPI_SOURCE, Stat.MPI_TAG); fflush(stderr); #endif if (Stat.MPI_TAG == BootTreeTag) fprintf(tree->io->fp_out_boot_tree,"%s\n", bootStr); if (Stat.MPI_TAG == BootStatTag) fprintf(tree->io->fp_out_boot_stats,"%s\n", bootStr); bootRecv++; PhyML_Printf("."); if(!((bootRecv)%tree->io->boot_prog_every)) { PhyML_Printf("] %4d/%4d\n ",bootRecv,tree->mod->bootstrap); if(bootRecv != tree->mod->bootstrap) PhyML_Printf("["); } } Free(bootStr); } else { MPI_Ssend (s, T_MAX_LINE, MPI_CHAR, 0, BootTreeTag, MPI_COMM_WORLD); MPI_Ssend (t, T_MAX_LINE, MPI_CHAR, 0, BootStatTag, MPI_COMM_WORLD); #ifdef MPI_DEBUG fprintf (stderr, "\ntask %d, sending bootstraps done\n", Global_myRank); fflush(stderr); #endif } Free(t); Free(s); } #ifndef QUIET fflush(stdout); #endif /* if(boot_tree->mat) Free_Mat(boot_tree->mat); */ Free_Tree(boot_tree); Free_Model(boot_mod); //Each process computes the Bip score sum for all its bootstrap trees For(i,2*tree->n_otu-3) score_par[i] = tree->a_edges[i]->bip_score; //Each process sends its Bip score sum. The sums are summed. MPI_Reduce(score_par, score_tot, 2*tree->n_otu - 3, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD); } if (Global_myRank == 0) { For(i,2*tree->n_otu-3) tree->a_edges[i]->bip_score = score_tot[i]; Free (score_tot); } Free (score_par); if (Global_myRank == 0) if(((bootRecv)%tree->io->boot_prog_every)) PhyML_Printf("] %4d/%4d\n ",bootRecv,tree->mod->bootstrap); PhyML_Printf("\n\n. Exiting bootstrap function normally."); fflush(NULL); tree->lock_topo = 1; /* TopoLOGy should not be modified afterwards */ if(tree->io->print_boot_trees) { fclose(tree->io->fp_out_boot_tree); fclose(tree->io->fp_out_boot_stats); } Free_Cseq(boot_data); Free(site_num); } /*********************************************************/ void Print_Fp_Out_Lines_MPI(t_tree *tree, option *io, int n_data_set, char *bootStr) { char *s, *tmp; // Build a string to be sent to the writing process s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); tmp=(char *)mCalloc(T_MAX_LINE,sizeof(char)); if (Global_myRank == 0 && n_data_set == 1) { snprintf(tmp, T_MAX_LINE, ". Sequence file : [%s]\n\n", Basename(io->in_align_file)); strncat (s, tmp, T_MAX_LINE); (tree->mod->io->datatype == NT)? (snprintf(tmp, T_MAX_LINE, ". Model of nucleotides substitution : %s\n\n", io->mod->modelname->s)): (snprintf(tmp, T_MAX_LINE, ". Model of amino acids substitution : %s\n\n", io->mod->modelname->s)); strncat (s, tmp, T_MAX_LINE); switch(io->in_tree) { case 0: { snprintf(tmp, T_MAX_LINE, ". Initial tree : [BioNJ]\n\n"); break; } case 1: { snprintf(tmp, T_MAX_LINE, ". Initial tree : [parsimony]\n\n"); break; } case 2: { snprintf(tmp, T_MAX_LINE, ". Initial tree : [%s]\n\n",io->in_tree_file); break; } } strncat (s, tmp, T_MAX_LINE); strncat (s, "\n", T_MAX_LINE); /*headline 1*/ strncat (s, ". Data\t", T_MAX_LINE); strncat (s, "Nb of \t", T_MAX_LINE); strncat (s, "Likelihood\t", T_MAX_LINE); strncat (s, "Discrete \t", T_MAX_LINE); if(tree->mod->ras->n_catg > 1) strncat (s, "Number of \tGamma shape\t", T_MAX_LINE); strncat (s, "Proportion of\t", T_MAX_LINE); if(tree->mod->whichmodel <= 6) strncat (s, "Transition/ \t", T_MAX_LINE); strncat (s, "Nucleotides frequencies \t", T_MAX_LINE); if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) strncat (s, "Instantaneous rate matrix \t", T_MAX_LINE); strncat (s, "\n", T_MAX_LINE); /*headline 2*/ strncat (s, " set\t", T_MAX_LINE); strncat (s, "taxa\t", T_MAX_LINE); strncat (s, "loglk \t", T_MAX_LINE); strncat (s, "gamma model\t", T_MAX_LINE); if(tree->mod->ras->n_catg > 1) strncat (s, "categories\tparameter \t", T_MAX_LINE); strncat (s, "invariant \t", T_MAX_LINE); if(tree->mod->whichmodel <= 6) strncat (s, "transversion\t", T_MAX_LINE); strncat (s, "f(A) f(C) f(G) f(T) \t", T_MAX_LINE); if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) strncat (s, "[A---------C---------G---------T------]\t", T_MAX_LINE); strncat (s, "\n", T_MAX_LINE); /*headline 3*/ if(tree->mod->whichmodel == TN93) { strncat (s, " \t \t \t \t", T_MAX_LINE); if(tree->mod->ras->n_catg > 1) strncat (s, " \t \t", T_MAX_LINE); strncat (s, " \t", T_MAX_LINE); strncat (s, "purines pyrimid.\t", T_MAX_LINE); strncat (s, "\n", T_MAX_LINE); } strncat (s, "\n", T_MAX_LINE); } /*line items*/ snprintf(tmp, T_MAX_LINE, " #%d\t", (((n_data_set-1)*Global_numTask)+Global_myRank+1)); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%d \t",tree->n_otu); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%.5f\t",tree->c_lnL); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%s \t", (tree->mod->ras->n_catg>1)?("Yes"):("No ")); strncat (s, tmp, T_MAX_LINE); if(tree->mod->ras->n_catg > 1) { snprintf(tmp, T_MAX_LINE, "%d \t",tree->mod->ras->n_catg); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%.3f \t",tree->mod->ras->alpha->v); strncat (s, tmp, T_MAX_LINE); } snprintf(tmp, T_MAX_LINE, "%.3f \t",tree->mod->ras->pinvar->v); strncat (s, tmp, T_MAX_LINE); if(tree->mod->whichmodel <= 5) { snprintf(tmp, T_MAX_LINE, "%.3f \t",tree->mod->kappa->v); strncat (s, tmp, T_MAX_LINE); } else if(tree->mod->whichmodel == TN93) { snprintf(tmp, T_MAX_LINE, "%.3f ", tree->mod->kappa->v*2.*tree->mod->lambda->v/(1.+tree->mod->lambda->v)); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%.3f\t", tree->mod->kappa->v*2./(1.+tree->mod->lambda->v)); strncat (s, tmp, T_MAX_LINE); } if(tree->mod->io->datatype == NT) { snprintf(tmp, T_MAX_LINE, "%8.5f ",tree->mod->e_frq->pi->v[0]); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%8.5f ",tree->mod->e_frq->pi->v[1]); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%8.5f ",tree->mod->e_frq->pi->v[2]); strncat (s, tmp, T_MAX_LINE); snprintf(tmp, T_MAX_LINE, "%8.5f\t",tree->mod->e_frq->pi->v[3]); strncat (s, tmp, T_MAX_LINE); } if((tree->mod->whichmodel == GTR) || (tree->mod->whichmodel == CUSTOM)) { int i,j; For(i,4) { if (i!=0) { /*format*/ snprintf(tmp, T_MAX_LINE, " \t \t \t \t"); strncat (s, tmp, T_MAX_LINE); if(tree->mod->ras->n_catg > 1) { snprintf(tmp, T_MAX_LINE, " \t \t"); strncat (s, tmp, T_MAX_LINE); } snprintf(tmp, T_MAX_LINE, " \t \t"); strncat (s, tmp, T_MAX_LINE); } For(j,4) { snprintf(tmp, T_MAX_LINE, "%8.5f ",tree->mod->r_mat->qmat->v[i*4+j]); strncat (s, tmp, T_MAX_LINE); } if (i<3) { snprintf(tmp, T_MAX_LINE, "\n"); strncat (s, tmp, T_MAX_LINE); } } } Free (tmp); strncpy (bootStr, s, T_MAX_LINE); Free (s); return; } /* #endif */ phyml-3.2.0/src/mpi_boot.h000066400000000000000000000013341263450375500154300ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef MPI_H #define MPI_H #include "mpi.h" #include "utilities.h" #include "bionj.h" #include "lk.h" #include "pars.h" #include "free.h" #include "models.h" #include "simu.h" #include "spr.h" #define BootTreeTag 0 #define BootStatTag 1 int Global_numTask, Global_myRank; void Bootstrap_MPI(t_tree *tree); void Print_Fp_Out_Lines_MPI(t_tree *tree, option *io, int n_data_set, char *bootStr); #endif // MPI phyml-3.2.0/src/mxml.h000066400000000000000000000273561263450375500146110ustar00rootroot00000000000000/* * "$Id: mxml.h 427 2011-01-03 02:03:29Z mike $" * * Header file for Mini-XML, a small XML-like file parsing library. * * Copyright 2003-2011 by Michael R Sweet. * * These coded instructions, statements, and computer programs are the * property of Michael R Sweet and are protected by Federal copyright * law. Distribution and use rights are outlined in the file "COPYING" * which should have been included with this file. If this file is * missing or damaged, see the license at: * * http://www.minixml.org/ */ /* * Prevent multiple inclusion... */ #ifndef _mxml_h_ # define _mxml_h_ /* * Include necessary headers... */ # include # include # include # include # include /* * Constants... */ # define MXML_TAB 8 /* Tabs every N columns */ # define MXML_NO_CALLBACK 0 /* Don't use a type callback */ # define MXML_INTEGER_CALLBACK mxml_integer_cb /* Treat all data as integers */ # define MXML_OPAQUE_CALLBACK mxml_opaque_cb /* Treat all data as opaque */ # define MXML_REAL_CALLBACK mxml_real_cb /* Treat all data as real numbers */ # define MXML_TEXT_CALLBACK 0 /* Treat all data as text */ # define MXML_IGNORE_CALLBACK mxml_ignore_cb /* Ignore all non-element content */ # define MXML_NO_PARENT 0 /* No prev for the node */ # define MXML_DESCEND 1 /* Descend when finding/walking */ # define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */ # define MXML_DESCEND_FIRST -1 /* Descend for first find */ # define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */ # define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */ # define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */ # define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */ # define MXML_ADD_BEFORE 0 /* Add node before specified node */ # define MXML_ADD_AFTER 1 /* Add node after specified node */ # define MXML_ADD_TO_PARENT NULL /* Add node relative to prev */ /* * Data types... */ typedef enum mxml_sax_event_e /**** SAX event type. ****/ { MXML_SAX_CDATA, /* CDATA node */ MXML_SAX_COMMENT, /* Comment node */ MXML_SAX_DATA, /* Data node */ MXML_SAX_DIRECTIVE, /* Processing directive node */ MXML_SAX_ELEMENT_CLOSE, /* Element closed */ MXML_SAX_ELEMENT_OPEN /* Element opened */ } mxml_sax_event_t; typedef enum mxml_type_e /**** The XML node type. ****/ { MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */ MXML_ELEMENT, /* XML element with attributes */ MXML_INTEGER, /* Integer value */ MXML_OPAQUE, /* Opaque string */ MXML_REAL, /* Real value */ MXML_TEXT, /* Text fragment */ MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */ } mxml_type_t; typedef void (*mxml_custom_destroy_cb_t)(void *); /**** Custom data destructor ****/ typedef void (*mxml_error_cb_t)(const char *); /**** Error callback function ****/ typedef struct mxml_attr_s /**** An XML element attribute value. @private@ ****/ { char *name; /* Attribute name */ char *value; /* Attribute value */ } mxml_attr_t; typedef struct mxml_element_s /**** An XML element value. @private@ ****/ { char *name; /* Name of element */ int num_attrs; /* Number of attributes */ mxml_attr_t *attrs; /* Attributes */ } mxml_element_t; typedef struct mxml_text_s /**** An XML text value. @private@ ****/ { int whitespace; /* Leading whitespace? */ char *string; /* Fragment string */ } mxml_text_t; typedef struct mxml_custom_s /**** An XML custom value. @private@ ****/ { void *data; /* Pointer to (allocated) custom data */ mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */ } mxml_custom_t; typedef union mxml_value_u /**** An XML node value. @private@ ****/ { mxml_element_t element; /* Element */ int integer; /* Integer number */ char *opaque; /* Opaque string */ double real; /* Real number */ mxml_text_t text; /* Text fragment */ mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */ } mxml_value_t; struct mxml_node_s /**** An XML node. @private@ ****/ { mxml_type_t type; /* Node type */ struct mxml_node_s *next; /* Next node under same prev */ struct mxml_node_s *prev; /* Previous node under same prev */ struct mxml_node_s *prev; /* Parent node */ struct mxml_node_s *next; /* First next node */ struct mxml_node_s *last_next; /* Last next node */ mxml_value_t value; /* Node value */ int ref_count; /* Use count */ void *user_data; /* User data */ }; typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/ struct mxml_index_s /**** An XML node index. @private@ ****/ { char *attr; /* Attribute used for indexing or NULL */ int num_nodes; /* Number of nodes in index */ int alloc_nodes; /* Allocated nodes in index */ int cur_node; /* Current node */ mxml_node_t **nodes; /* Node array */ }; typedef struct mxml_index_s mxml_index_t; /**** An XML node index. ****/ typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *); /**** Custom data load callback function ****/ typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *); /**** Custom data save callback function ****/ typedef int (*mxml_entity_cb_t)(const char *); /**** Entity callback function */ typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *); /**** Load callback function ****/ typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int); /**** Save callback function ****/ typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *); /**** SAX callback function ****/ /* * C++ support... */ # ifdef __cplusplus extern "C" { # endif /* __cplusplus */ /* * Prototypes... */ extern void mxmlAdd(mxml_node_t *prev, int where, mxml_node_t *next, mxml_node_t *node); extern void mxmlDelete(mxml_node_t *node); extern void mxmlElementDeleteAttr(mxml_node_t *node, const char *name); extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name); extern void mxmlElementSetAttr(mxml_node_t *node, const char *name, const char *value); extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name, const char *format, ...) # ifdef __GNUC__ __attribute__ ((__format__ (__printf__, 3, 4))) # endif /* __GNUC__ */ ; extern int mxmlEntityAddCallback(mxml_entity_cb_t cb); extern const char *mxmlEntityGetName(int val); extern int mxmlEntityGetValue(const char *name); extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb); extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top, const char *name, const char *attr, const char *value, int descend); extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path); extern const char *mxmlGetCDATA(mxml_node_t *node); extern const void *mxmlGetCustom(mxml_node_t *node); extern const char *mxmlGetElement(mxml_node_t *node); extern mxml_node_t *mxmlGetFirstChild(mxml_node_t *node); extern int mxmlGetInteger(mxml_node_t *node); extern mxml_node_t *mxmlGetLastChild(mxml_node_t *node); extern mxml_node_t *mxmlGetNextSibling(mxml_node_t *node); extern const char *mxmlGetOpaque(mxml_node_t *node); extern mxml_node_t *mxmlGetParent(mxml_node_t *node); extern mxml_node_t *mxmlGetPrevSibling(mxml_node_t *node); extern double mxmlGetReal(mxml_node_t *node); extern int mxmlGetRefCount(mxml_node_t *node); extern const char *mxmlGetText(mxml_node_t *node, int *whitespace); extern mxml_type_t mxmlGetType(mxml_node_t *node); extern void *mxmlGetUserData(mxml_node_t *node); extern void mxmlIndexDelete(mxml_index_t *ind); extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind); extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind, const char *element, const char *value); extern int mxmlIndexGetCount(mxml_index_t *ind); extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element, const char *attr); extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind); extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd, mxml_type_t (*cb)(mxml_node_t *)); extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp, mxml_type_t (*cb)(mxml_node_t *)); extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s, mxml_type_t (*cb)(mxml_node_t *)); extern mxml_node_t *mxmlNewCDATA(mxml_node_t *prev, const char *string); extern mxml_node_t *mxmlNewCustom(mxml_node_t *prev, void *data, mxml_custom_destroy_cb_t destroy); extern mxml_node_t *mxmlNewElement(mxml_node_t *prev, const char *name); extern mxml_node_t *mxmlNewInteger(mxml_node_t *prev, int integer); extern mxml_node_t *mxmlNewOpaque(mxml_node_t *prev, const char *opaque); extern mxml_node_t *mxmlNewReal(mxml_node_t *prev, double real); extern mxml_node_t *mxmlNewText(mxml_node_t *prev, int whitespace, const char *string); extern mxml_node_t *mxmlNewTextf(mxml_node_t *prev, int whitespace, const char *format, ...) # ifdef __GNUC__ __attribute__ ((__format__ (__printf__, 3, 4))) # endif /* __GNUC__ */ ; extern mxml_node_t *mxmlNewXML(const char *version); extern int mxmlRelease(mxml_node_t *node); extern void mxmlRemove(mxml_node_t *node); extern int mxmlRetain(mxml_node_t *node); extern char *mxmlSaveAllocString(mxml_node_t *node, mxml_save_cb_t cb); extern int mxmlSaveFd(mxml_node_t *node, int fd, mxml_save_cb_t cb); extern int mxmlSaveFile(mxml_node_t *node, FILE *fp, mxml_save_cb_t cb); extern int mxmlSaveString(mxml_node_t *node, char *buffer, int bufsize, mxml_save_cb_t cb); extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd, mxml_type_t (*cb)(mxml_node_t *), mxml_sax_cb_t sax, void *sax_data); extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp, mxml_type_t (*cb)(mxml_node_t *), mxml_sax_cb_t sax, void *sax_data); extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s, mxml_type_t (*cb)(mxml_node_t *), mxml_sax_cb_t sax, void *sax_data); extern int mxmlSetCDATA(mxml_node_t *node, const char *data); extern int mxmlSetCustom(mxml_node_t *node, void *data, mxml_custom_destroy_cb_t destroy); extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load, mxml_custom_save_cb_t save); extern int mxmlSetElement(mxml_node_t *node, const char *name); extern void mxmlSetErrorCallback(mxml_error_cb_t cb); extern int mxmlSetInteger(mxml_node_t *node, int integer); extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque); extern int mxmlSetReal(mxml_node_t *node, double real); extern int mxmlSetText(mxml_node_t *node, int whitespace, const char *string); extern int mxmlSetTextf(mxml_node_t *node, int whitespace, const char *format, ...) # ifdef __GNUC__ __attribute__ ((__format__ (__printf__, 3, 4))) # endif /* __GNUC__ */ ; extern int mxmlSetUserData(mxml_node_t *node, void *data); extern void mxmlSetWrapMargin(int column); extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top, int descend); extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top, int descend); /* * Semi-private functions... */ extern void mxml_error(const char *format, ...); extern mxml_type_t mxml_ignore_cb(mxml_node_t *node); extern mxml_type_t mxml_integer_cb(mxml_node_t *node); extern mxml_type_t mxml_opaque_cb(mxml_node_t *node); extern mxml_type_t mxml_real_cb(mxml_node_t *node); /* * C++ support... */ # ifdef __cplusplus } # endif /* __cplusplus */ #endif /* !_mxml_h_ */ /* * End of "$Id: mxml.h 427 2011-01-03 02:03:29Z mike $". */ phyml-3.2.0/src/nexus.c000066400000000000000000000320451263450375500147600ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "nexus.h" void Find_Nexus_Com(char *token, nexcom **found_com, nexparm **default_parm, nexcom **com_list) { int i,j,tokenlen,ndiff; For(i,N_MAX_NEX_COM) { tokenlen = strlen(token); ndiff = -1; if(tokenlen && (tokenlen == strlen(com_list[i]->name))) { ndiff = 0; For(j,tokenlen) { Lowercase(token+j); Lowercase(com_list[i]->name+j); if(token[j] != com_list[i]->name[j]) ndiff++; } } if(!ndiff) { *found_com = com_list[i]; break; } } if(*found_com && (*found_com)->nparm) *default_parm = (*found_com)->parm[0]; /* if(*found_com) PhyML_Printf("\n. Found command '%s'.\n",(*found_com)->name); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Nexus_Parm(char *token, nexparm **found_parm, nexcom *curr_com) { int i,j; int tokenlen; int ndiff; if(!curr_com) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } For(i,curr_com->nparm) { tokenlen = strlen(token); ndiff = -1; if(tokenlen == strlen(curr_com->parm[i]->name)) { ndiff = 0; For(j,tokenlen) { Lowercase(token+j); Lowercase(curr_com->parm[i]->name+j); if(token[j] != curr_com->parm[i]->name[j]) ndiff++; } } if(!ndiff) { *found_parm = curr_com->parm[i]; break; } } /* if(*found_parm) PhyML_Printf("\n. Found parameter '%s'.\n",(*found_parm)->name); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Taxa(char *token, nexparm *curr_parm, option *io) { PhyML_Printf("\n. Skipping 'taxa' block"); do { Get_Token(io->fp_in_align,token); if(token[0] == ';') break; }while(strlen(token) > 0); fseek(io->fp_in_align,-1*sizeof(char),SEEK_CUR); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Translate(char *token, nexparm *curr_parm, option *io) { int tax_num; char *end; PhyML_Printf("\n. Reading 'translate' block"); io->size_tax_names = 0; do { Get_Token(io->fp_in_tree,token); if(token[0] == ';') break; tax_num = (int)strtol(token,&end,10); if(*end =='\0' && token[0]) { io->size_tax_names++; io->short_tax_names = (char **)realloc(io->short_tax_names,io->size_tax_names*sizeof(char *)); io->short_tax_names[io->size_tax_names-1] = (char *)mCalloc(strlen(token)+1,sizeof(char)); sprintf(io->short_tax_names[io->size_tax_names-1],"%d",tax_num); Get_Token(io->fp_in_tree,token); io->long_tax_names = (char **)realloc(io->long_tax_names,io->size_tax_names*sizeof(char *)); io->long_tax_names[io->size_tax_names-1] = (char *)mCalloc(strlen(token)+1,sizeof(char)); strcpy(io->long_tax_names[io->size_tax_names-1],token); /* printf("\n. Copying %s number %d",io->long_tax_names[io->size_long_tax_names-1],tax_num-1); */ } }while(strlen(token) > 0); fseek(io->fp_in_tree,-1*sizeof(char),SEEK_CUR); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Matrix(char *token, nexparm *curr_parm, option *io) { if(io->interleaved) io->data = Read_Seq_Interleaved(io); else io->data = Read_Seq_Sequential(io); fseek(io->fp_in_align,-1*sizeof(char),SEEK_CUR); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Tree(char *token, nexparm *curr_parm, option *io) { io->treelist->tree = (t_tree **)realloc(io->treelist->tree,(io->treelist->list_size+1)*sizeof(t_tree *)); io->tree = Read_Tree_File_Phylip(io->fp_in_tree); if(!(io->treelist->list_size%10) && io->treelist->list_size > 1) { PhyML_Printf("\n. Reading tree %d",io->treelist->list_size); if(io->tree->n_root) PhyML_Printf(" (that is a rooted tree)"); else PhyML_Printf(" (that is an unrooted tree)"); } io->treelist->tree[io->treelist->list_size] = io->tree; io->treelist->list_size++; fseek(io->fp_in_tree,-1*sizeof(char),SEEK_CUR); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Begin(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; if(!curr_parm) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } if(!strcmp(curr_parm->name,"data") || !strcmp(curr_parm->name,"trees")) PhyML_Printf("\n. Reading '%s' block.\n",curr_parm->value); else { PhyML_Printf("\n. The '%s' block type is not supported by PhyML. Sorry.\n",curr_parm->name); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Dimensions(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; if(!curr_parm) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } strcpy(curr_parm->value,token); if(!strcmp(curr_parm->name,"ntax")) { sscanf(curr_parm->value,"%d",&(io->n_otu)); } if(!strcmp(curr_parm->name,"nchar")) { sscanf(curr_parm->value,"%d",&(io->init_len)); } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Format(char *token, nexparm *curr_parm, option *io) { int i; if(token[0] == '=') return 0; if(!curr_parm) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } For(i,strlen(token)) Lowercase(token+i); strcpy(curr_parm->value,token); /* printf("\n. >> %s",curr_parm->value); */ if(!strcmp(curr_parm->name,"datatype")) { if(!strcmp(curr_parm->value,"standard")) { io->datatype = GENERIC; io->mod->whichmodel = JC69; io->mod->s_opt->opt_kappa = NO; io->mod->s_opt->opt_lambda = NO; io->mod->ns = 2; io->alphabet[0][0] = '0'; io->alphabet[0][1] = '\0'; io->alphabet[1][0] = '1'; io->alphabet[1][1] = '\0'; } else if(!strcmp(curr_parm->value,"dna")) { io->datatype = NT; io->mod->ns = 4; } else if(!strcmp(curr_parm->value,"rna")) { io->datatype = NT; io->mod->ns = 4; } else if(!strcmp(curr_parm->value,"nucleotide")) { io->datatype = NT; io->mod->ns = 4; } else if(!strcmp(curr_parm->value,"protein")) { io->datatype = AA; io->mod->ns = 20; } else if(!strcmp(curr_parm->value,"continuous")) { PhyML_Printf("\n== The 'continuous' format is not supported by PhyML. Sorry.\n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } else if(!strcmp(curr_parm->name,"missing")) { PhyML_Printf("\n== The 'missing' subcommand is not supported by PhyML. Please remove it from the NEXUS file."); PhyML_Printf("\n== Note that the characters 'X', '?' and '-' will be considered as indels by default."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } else if(!strcmp(curr_parm->name,"gap")) { PhyML_Printf("\n== The 'gap' subcommand is not supported by PhyML. Please remove it from the NEXUS file."); PhyML_Printf("\n== Note that the characters 'X', '?' and '-' will be considered as indels by default."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } else if(!strcmp(curr_parm->name,"symbols")) { if(*token != '"' || *(token+strlen(token)-1) != '"') { PhyML_Printf("\n== Symbols list is supposed to be displayed between quotation marks (e.g., \"ACTG\").\n"); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } int i,has_spaces,state_len; i = 0; has_spaces = 0; token++; /* Get rid of the first '"' character */ while(token[i] != '"') { if(token[i] == ' ') { has_spaces = 1; break; } i++; } io->mod->ns = 0; if(!has_spaces) { while(token[i] != '"') { io->alphabet[io->mod->ns][0] = token[i]; io->alphabet[io->mod->ns][1] = '\0'; io->mod->ns++; i++; if(io->mod->ns > T_MAX_ALPHABET) { PhyML_Printf("\n== The alphabet cannot contain more than %d characters. Sorry.",T_MAX_ALPHABET); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } } else { i = 0; do { state_len = 0; while(token[i] != ' ' && token[i] != '"') { io->alphabet[io->mod->ns][state_len] = token[i]; state_len++; i++; if(state_len > T_MAX_STATE) { PhyML_Printf("\n== A state cannot contain more than %d characters. Sorry.\n",T_MAX_STATE); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } io->alphabet[io->mod->ns][state_len] = '\0'; io->mod->ns++; if(token[i] != '"') i++; } while(token[i] != '"'); } int len; len = strlen(io->alphabet[0]); For(i,io->mod->ns) { if(strlen(io->alphabet[i]) != len) { PhyML_Printf("\n== All character states defined in the symbol list are supposed to have the same length.\n"); PhyML_Printf("\n== Er.r in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } io->state_len = len; /* For(i,io->mod->ns) PhyML_Printf("\n. '%s'",io->alphabet[i]); */ } else if(!strcmp(curr_parm->name,"equate")) { PhyML_Printf("\n== PhyML does not recognize the command '%s' yet. Sorry.",curr_parm->name); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } else if(!strcmp(curr_parm->name,"matchchar")) { PhyML_Printf("\n== PhyML does not recognize the command '%s' yet. Sorry.",curr_parm->name); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } else if(!strcmp(curr_parm->name,"items")) { PhyML_Printf("\n== PhyML does not recognize the command '%s' yet. Sorry.",curr_parm->name); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } else if(!strcmp(curr_parm->name,"interleave")) { io->interleaved = YES; } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Eliminate(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; PhyML_Printf("\n== 'Eliminate' command is not supported by PhyML. Sorry."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Taxlabel(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; PhyML_Printf("\n== 'Taxlabels' command is not supported by PhyML. Sorry."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Charstatelabels(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; PhyML_Printf("\n== 'CharStateLabels' command is not supported by PhyML. Sorry."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Charlabels(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; PhyML_Printf("\n== 'CharLabels' command is not supported by PhyML. Sorry."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Read_Nexus_Statelabels(char *token, nexparm *curr_parm, option *io) { if(token[0] == '=') return 0; PhyML_Printf("\n== 'StateLabels' command is not supported by PhyML. Sorry."); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/nexus.h000066400000000000000000000025331263450375500147640ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef NEXUS_H #define NEXUS_H #include "utilities.h" void Find_Nexus_Com(char *token,nexcom **found_com,nexparm **default_parm,nexcom **com_list); void Find_Nexus_Parm(char *token,nexparm **found_parm,nexcom *curr_com); int Read_Nexus_Taxa(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Translate(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Matrix(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Tree(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Begin(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Dimensions(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Format(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Eliminate(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Taxlabel(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Charstatelabels(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Charlabels(char *token,nexparm *curr_parm,option *io); int Read_Nexus_Statelabels(char *token,nexparm *curr_parm,option *io); #endif phyml-3.2.0/src/optimiz.c000066400000000000000000003155561263450375500153240ustar00rootroot00000000000000/* PhyML : a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "optimiz.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf, phydbl lim_sup, phydbl tol, int n_max_iter, int quickdirty) { phydbl lk_init; lk_init = tree->c_lnL; Generic_Brent_Lk(param, lim_inf, lim_sup, tol, n_max_iter, quickdirty, Wrap_Lk, NULL, tree, NULL, NO); if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== %.10f < %.10f --> diff=%.10f param value = %f\n", tree->c_lnL,lk_init, tree->c_lnL-lk_init, *param); Exit("\n== Optimisation failed !\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Generic_Brak(phydbl *param, phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, phydbl lim_inf, phydbl lim_sup, t_tree *tree) { phydbl ulim,u,r,q,fu,dum; u = 0.0; *param = *ax; if(*param > lim_sup) *param = lim_sup; if(*param < lim_inf) *param = lim_inf; *fa=-Lk(NULL,tree); *param = *bx; if(*param > lim_sup) *param = lim_sup; if(*param < lim_inf) *param = lim_inf; *fb=-Lk(NULL,tree); if (*fb > *fa) { SHFT(dum,*ax,*bx,dum) SHFT(dum,*fb,*fa,dum) } *cx=(*bx)+MNBRAK_GOLD*(*bx-*ax); *param = FABS(*cx); if(*param > lim_sup) *param = lim_sup; if(*param < lim_inf) *param = lim_inf; *fc=-Lk(NULL,tree); while (*fb > *fc) { if(*ax > lim_sup) *ax = lim_sup; if(*ax < lim_inf) *ax = lim_inf; if(*bx > lim_sup) *bx = lim_sup; if(*bx < lim_inf) *bx = lim_inf; if(*cx > lim_sup) *cx = lim_sup; if(*cx < lim_inf) *cx = lim_inf; if(u > lim_sup) u = lim_sup; if(u < lim_inf) u = lim_inf; r=(*bx-*ax)*(*fb-*fc); q=(*bx-*cx)*(*fb-*fa); u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r)); ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx); if ((*bx-u)*(u-*cx) > lim_inf) { *param = FABS(u); if(*param > lim_sup) {*param = u = lim_sup;} if(*param < lim_inf) {*param = u = lim_inf;} fu=-Lk(NULL,tree); if (fu < *fc) { *ax=(*bx); *bx=u; *fa=(*fb); *fb=fu; (*ax)=FABS(*ax); (*bx)=FABS(*bx); (*cx)=FABS(*cx); return(0); } else if (fu > *fb) { *cx=u; *fc=fu; (*ax)=FABS(*ax); (*bx)=FABS(*bx); (*cx)=FABS(*cx); return(0); } u=(*cx)+MNBRAK_GOLD*(*cx-*bx); *param = FABS(u); if(*param > lim_sup) {*param = u = lim_sup;} if(*param < lim_inf) {*param = u = lim_inf;} fu=-Lk(NULL,tree); } else if ((*cx-u)*(u-ulim) > lim_inf) { *param = FABS(u); if(*param > lim_sup) {*param = u = lim_sup;} if(*param < lim_inf) {*param = u = lim_inf;} fu=-Lk(NULL,tree); if (fu < *fc) { SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx)) *param = FABS(u); SHFT(*fb,*fc,fu,-Lk(NULL,tree)) } } else if ((u-ulim)*(ulim-*cx) >= lim_inf) { u=ulim; *param = FABS(u); if(*param > lim_sup) {*param = u = lim_sup;} if(*param < lim_inf) {*param = u = lim_inf;} fu=-Lk(NULL,tree); } else { u=(*cx)+MNBRAK_GOLD*(*cx-*bx); *param = FABS(u); if(*param > lim_sup) {*param = u = lim_sup;} if(*param < lim_inf) {*param = u = lim_inf;} fu=-Lk(NULL,tree); } SHFT(*ax,*bx,*cx,u) SHFT(*fa,*fb,*fc,fu) } (*ax)=FABS(*ax); (*bx)=FABS(*bx); (*cx)=FABS(*cx); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Generic_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, int n_iter_max, int quickdirty) { int iter; phydbl a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; phydbl e=0.0; phydbl init_lnL; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; (*xmin) = bx; fw=fv=fx=-Lk(NULL,tree); init_lnL = -fw; PhyML_Printf("\n. init_lnL = %f a=%f b=%f c=%f\n",init_lnL,ax,bx,cx); for(iter=1;iter<=n_iter_max;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*FABS(x)+BRENT_ZEPS); if(FABS(x - xm) <= (tol2 - 0.5 * (b - a))) { *xmin = x; Lk(NULL,tree); if(tree->c_lnL < init_lnL - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } return tree->c_lnL; } if(FABS(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if(q > 0.0) p = -p; q=FABS(q); etemp=e; e=d; if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf("Golden section step\n"); */ } else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); /* PhyML_Printf("Parabolic step [e=%f]\n",e); */ } } else { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf("Golden section step (default) [e=%f tol1=%f a=%f b=%f d=%f]\n",e,tol1,a,b,d); */ } u=(FABS(d) >= tol1 ? x+d : x+SIGN(tol1,d)); (*xmin) = FABS(u); fu = -Lk(NULL,tree); PhyML_Printf("\n. iter=%d/%d param=%f loglk=%f",iter,BRENT_IT_MAX,*xmin,tree->c_lnL); /* if(fu <= fx) */ if(fu < fx) { /* if(u >= x) a=x; else b=x; */ if(u > x) a=x; else b=x; SHFT(v,w,x,u) SHFT(fv,fw,fx,fu) } else { if (u < x) a=u; else b=u; /* if (fu <= fw || w == x) */ if (fu < fw || FABS(w-x) < SMALL) { v=w; w=u; fv=fw; fw=fu; } /* else if (fu <= fv || v == x || v == w) */ else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL) { v=u; fv=fu; } } } Exit("\n. Too many iterations in Generic_Brent !"); return(-1); /* Not Reached ?? *xmin=x; */ /* Not Reached ?? return fx; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RRparam_GTR_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata, phydbl *param, int n_iter_max) { phydbl f1,f2,x0,x1,x2,x3; int n_iter; x0=ax; x3=cx; if (FABS(cx-bx) > FABS(bx-ax)) { x1=bx; x2=bx+GOLDEN_C*(cx-bx); } else { x2=bx; x1=bx-GOLDEN_C*(bx-ax); } (*param)=x1; Lk(NULL,tree); f1=-tree->c_lnL; (*param)=x2; Lk(NULL,tree); f2=-tree->c_lnL; n_iter = 0; while (FABS(x3-x0) > tol*(FABS(x1)+FABS(x2))) { if (f2 < f1) { SHFT3(x0,x1,x2,GOLDEN_R*x1+GOLDEN_C*x3) (*param)=x2; Lk(NULL,tree); SHFT2(f1,f2,-tree->c_lnL) } else { SHFT3(x3,x2,x1,GOLDEN_R*x2+GOLDEN_C*x0) (*param)=x1; Lk(NULL,tree); SHFT2(f2,f1,-tree->c_lnL) } if(n_iter++ > n_iter_max) break; /* PhyML_Printf("p=%E %f\n",(*param),tree->c_lnL); */ } if (f1 < f2) { *xmin=x1; return f1; } else { *xmin=x2; return f2; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Br_Len_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_edge *b_fcus, t_tree *tree) { phydbl f1,f2,x0,x1,x2,x3; x0=ax; x3=cx; if (FABS(cx-bx) > FABS(bx-ax)) { x1=bx; x2=bx+GOLDEN_C*(cx-bx); } else { x2=bx; x1=bx-GOLDEN_C*(bx-ax); } b_fcus->l->v=x1; f1 = -Lk(b_fcus,tree); b_fcus->l->v=x2; f2 = -Lk(b_fcus,tree); while (FABS(x3-x0) > tol*(FABS(x1)+FABS(x2))) { if (f2 < f1) { SHFT3(x0,x1,x2,GOLDEN_R*x1+GOLDEN_C*x3) b_fcus->l->v=x2; SHFT2(f1,f2,-Lk(b_fcus,tree)) } else { SHFT3(x3,x2,x1,GOLDEN_R*x2+GOLDEN_C*x0) b_fcus->l->v=x1; SHFT2(f2,f1,-Lk(b_fcus,tree)) } } if (f1 < f2) { *xmin=FABS(x1); return -f1; } else { *xmin=FABS(x2); return -f2; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Br_Len_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_edge *b_fcus, t_tree *tree) { phydbl ulim,u,r,q,fu,dum; b_fcus->l->v = *ax; *fa=-Lk(b_fcus,tree); b_fcus->l->v = *bx; *fb=-Lk(b_fcus,tree); if (*fb > *fa) { SHFT(dum,*ax,*bx,dum) SHFT(dum,*fb,*fa,dum) } *cx=(*bx)+MNBRAK_GOLD*(*bx-*ax); b_fcus->l->v = *cx; *fc=-Lk(b_fcus,tree); while (*fb > *fc + tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("fb=%f fc=%f\n",*fb,*fc); r=(*bx-*ax)*(*fb-*fc); q=(*bx-*cx)*(*fb-*fa); u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r)); ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx); if ((*bx-u)*(u-*cx) > 0.0) { b_fcus->l->v = u; fu=-Lk(b_fcus,tree); if (fu < *fc) { *ax=(*bx); *bx=u; *fa=(*fb); *fb=fu; /* (*ax)=FABS(*ax); */ /* (*bx)=FABS(*bx); */ /* (*cx)=FABS(*cx); */ return(0); } else if (fu > *fb) { *cx=u; *fc=fu; /* (*ax)=FABS(*ax); */ /* (*bx)=FABS(*bx); */ /* (*cx)=FABS(*cx); */ return(0); } u=(*cx)+MNBRAK_GOLD*(*cx-*bx); b_fcus->l->v = u; fu=-Lk(b_fcus,tree); } else if ((*cx-u)*(u-ulim) > 0.0) { b_fcus->l->v = FABS(u); fu=-Lk(b_fcus,tree); if (fu < *fc) { SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx)) b_fcus->l->v = u; SHFT(*fb,*fc,fu,-Lk(b_fcus,tree)) } } else if ((u-ulim)*(ulim-*cx) >= 0.0) { u=ulim; b_fcus->l->v = u; fu=-Lk(b_fcus,tree); } else { u=(*cx)+MNBRAK_GOLD*(*cx-*bx); b_fcus->l->v = u; fu=-Lk(b_fcus,tree); } SHFT(*ax,*bx,*cx,u) SHFT(*fa,*fb,*fc,fu) } (*ax)=FABS(*ax); (*bx)=FABS(*bx); (*cx)=FABS(*cx); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Br_Len_Brent(phydbl prop_min, phydbl prop_max, t_edge *b_fcus, t_tree *tree) { t_tree *loc_tree; t_edge *loc_b; phydbl lk_begin, lk_end; lk_begin = UNLIKELY; lk_end = UNLIKELY; loc_tree = tree; loc_b = b_fcus; /*! Rewind back to the first mixt_tree */ while(loc_tree->prev) { loc_tree = loc_tree->prev; loc_b = loc_b->prev; } if(tree->is_mixt_tree) { MIXT_Br_Len_Brent(prop_min,prop_max,b_fcus,tree); return loc_tree->c_lnL; } if(b_fcus->l->onoff == OFF) return loc_tree->c_lnL; if(isinf(prop_min) || isnan(prop_min)) prop_min = 1.E-04; if(isinf(prop_max) || isnan(prop_max)) prop_max = 1.E+04; lk_begin = Lk(loc_b,loc_tree); /*! We can't assume that the log-lk value is up-to-date */ Generic_Brent_Lk(&(b_fcus->l->v), MAX(tree->mod->l_min,MIN(tree->mod->l_max,b_fcus->l->v))*MAX(1.E-04,prop_min), MAX(tree->mod->l_min,MIN(tree->mod->l_max,b_fcus->l->v))*MIN(1.E+04,prop_max), tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk_At_Given_Edge, loc_b,loc_tree,NULL,NO); /* if(tree->mod->gamma_mgf_bl == YES) */ /* { */ /* if(b_fcus->num == 0) */ /* { */ /* Generic_Brent_Lk(&(b_fcus->l_var), */ /* 1.E-4,100., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty, */ /* Wrap_Lk_At_Given_Edge,loc_b,loc_tree,NULL); */ /* /\* Wrap_Lk,NULL,loc_tree,NULL); *\/ */ /* } */ /* } */ lk_end = loc_tree->c_lnL; if(lk_end < lk_begin - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== prop_min: %f prop_max: %f l: %f var:%f",prop_min,prop_max,b_fcus->l->v,b_fcus->l_var->v); PhyML_Printf("\n== lk_beg = %f lk_end = %f",lk_begin, lk_end); PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__); Exit("\n"); } return loc_tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Round_Optimize(t_tree *tree, calign *data, int n_round_max) { int n_round,each; phydbl lk_old, lk_new; lk_new = tree->c_lnL; lk_old = UNLIKELY; n_round = 0; each = 0; Set_Both_Sides(NO,tree); /* Only the down partial likelihoods need to be up-to-date here */ Lk(NULL,tree); while(n_round < n_round_max) { if(tree->mod->s_opt->opt_bl || tree->mod->s_opt->constrained_br_len) Optimize_Br_Len_Serie(tree); if((tree->mod->s_opt->opt_bl || tree->mod->s_opt->constrained_br_len) && (tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Branch lengths ]"); Set_Both_Sides(YES,tree); Lk(NULL,tree); if(!each) { each = 1; Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print)); Set_Both_Sides(YES,tree); Lk(NULL,tree); } lk_new = tree->c_lnL; if(lk_new < lk_old - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== lk_new = %f lk_old = %f diff = %f",lk_new,lk_old,lk_new-lk_old); Exit("\n== Optimisation failed ! (Round_Optimize)\n"); } if(FABS(lk_new - lk_old) < tree->mod->s_opt->min_diff_lk_local) { // DUMP_D(FABS(lk_new - lk_old)); // DUMP_I(n_round); break; } else { lk_old = lk_new; } n_round++; each--; } Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Br_Len_Serie(t_tree *tree) { if(tree->mod->gamma_mgf_bl == YES) { phydbl lk_init = tree->c_lnL; Generic_Brent_Lk(&(tree->mod->l_var_sigma), tree->mod->l_var_min, tree->mod->l_var_max, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f -- %f",lk_init,tree->c_lnL); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); } if((tree->io->quiet)?(0):(tree->mod->s_opt->print)) { Print_Lk(tree,"[Branch len. var. ]"); PhyML_Printf("[%10f]",tree->mod->l_var_sigma); } } if(tree->n_root && tree->ignore_root == NO) { Update_P_Lk(tree,tree->n_root->b[1],tree->n_root); Optimize_Br_Len_Serie_Post(tree->n_root,tree->n_root->v[1],tree->n_root->b[1],tree); Update_P_Lk(tree,tree->n_root->b[2],tree->n_root); Optimize_Br_Len_Serie_Post(tree->n_root,tree->n_root->v[2],tree->n_root->b[2],tree); } else if(tree->n_root && tree->ignore_root == YES) { Optimize_Br_Len_Serie_Post(tree->e_root->rght, tree->e_root->left, tree->e_root,tree); Optimize_Br_Len_Serie_Post(tree->e_root->left, tree->e_root->rght, tree->e_root,tree); } else { Optimize_Br_Len_Serie_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Optimize_Br_Len_Multiplier(t_tree *mixt_tree, int verbose) { phydbl lk_init; t_tree *tree; tree = mixt_tree; do { if(tree->mod->s_opt->opt_br_len_mult == YES) { lk_init = Get_Lk(tree); Generic_Brent_Lk(&(tree->mod->br_len_mult_unscaled->v), 1.E-2,1.E+1, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(Get_Lk(tree) < lk_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f -- %f",lk_init,tree->c_lnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } tree = tree->next_mixt; } while(tree); tree = mixt_tree; do { if(verbose && tree->mod->s_opt->opt_br_len_mult == YES) { Print_Lk(tree,"[Tree scale ]"); PhyML_Printf("[%10f]",tree->mod->br_len_mult->v); } tree = tree->next_mixt; } while(tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tree) { int i; phydbl l_infa,l_infb; phydbl lk_init; lk_init = tree->c_lnL; if(tree->mod->s_opt->constrained_br_len == YES) { Generic_Brent_Lk(&(tree->mod->br_len_mult->v), 1.E-2,1.E+1, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f -- %f",lk_init,tree->c_lnL); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } return; } l_infa = tree->mod->l_max/b_fcus->l->v; l_infb = tree->mod->l_min/b_fcus->l->v; Set_Both_Sides(YES,tree); if(tree->io->mod->s_opt->opt_bl == YES) Br_Len_Brent(l_infb,l_infa,b_fcus,tree); if(tree->c_lnL < lk_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f %f %G",l_infa,l_infb,b_fcus->l->v); PhyML_Printf("\n== %f -- %f",lk_init,tree->c_lnL); PhyML_Printf("\n== Edge: %d",b_fcus->num); PhyML_Printf("\n== is_mixt_tree: %d",tree->is_mixt_tree); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } if(d->tax) return; if(tree->n_root) { For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { Update_P_Lk(tree,d->b[i],d); Optimize_Br_Len_Serie_Post(d,d->v[i],d->b[i],tree); } } For(i,3) if(d->v[i] == a || d->b[i] == tree->e_root) Update_P_Lk(tree,d->b[i],d); } else { For(i,3) { if(d->v[i] != a) { Update_P_Lk(tree,d->b[i],d); Optimize_Br_Len_Serie_Post(d,d->v[i],d->b[i],tree); } } For(i,3) if(d->v[i] == a) Update_P_Lk(tree,d->b[i],d); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimiz_Ext_Br(t_tree *tree) { int i; t_edge *b,*ori; phydbl l_infa,l_infb; phydbl lk_init,l_init; lk_init = tree->c_lnL; For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; if((b->left->tax) || (b->rght->tax)) { l_init = b->l->v; /* Fast_Br_Len(b,tree); */ /* lk = Lk(NULL,tree,b); */ l_infb = tree->mod->l_min/b->l->v; l_infa = 10.; Br_Len_Brent(l_infb,l_infa,b,tree); ori = b; do { b->nni->best_l = b->l->v; b->nni->l0 = b->l->v; b->nni->best_conf = 0; b->l->v = l_init; b = b->next; } while(b); b = ori; } } tree->c_lnL = lk_init; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimiz_All_Free_Param(t_tree *tree, int verbose) { int init_both_sides; if(!tree) return; if(tree->mixt_tree && tree->mod->ras->invar == YES) return; init_both_sides = tree->both_sides; Set_Both_Sides(NO,tree); Lk(NULL,tree); Optimize_RR_Params(tree,verbose); Optimize_TsTv(tree,verbose); Optimize_Lambda(tree,verbose); Optimiz_Alpha_And_Pinv(tree,verbose); Optimize_Pinv(tree,verbose); Optimize_Alpha(tree,verbose); Optimize_State_Freqs(tree,verbose); Optimize_Rmat_Weights(tree,verbose); Optimize_Efrq_Weights(tree,verbose); Optimize_Free_Rate(tree,verbose); Optimize_Br_Len_Multiplier(tree,verbose); if(tree->mod->use_m4mod) { int failed,i; if(tree->mod->s_opt->opt_cov_delta) { Switch_Eigen(YES,tree->mod); /* Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->delta), */ /* 0.01,10., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ Generic_Brent_Lk(&(tree->mod->m4mod->delta), 0.01,10., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(verbose) { Print_Lk(tree,"[Switching param. ]"); PhyML_Printf("[%10f]",tree->mod->m4mod->delta); } Switch_Eigen(NO,tree->mod); } if(tree->mod->s_opt->opt_cov_free_rates) { int rcat; Switch_Eigen(YES,tree->mod); For(rcat,tree->mod->m4mod->n_h) { /* Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->multipl_unscaled[rcat]), */ /* .01,10., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ Generic_Brent_Lk(&(tree->mod->m4mod->multipl_unscaled[rcat]), 0.1,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(verbose) { Print_Lk(tree,"[Rel. subst. rate ]"); PhyML_Printf("[%10f]",tree->mod->m4mod->multipl[rcat]); } } For(rcat,tree->mod->m4mod->n_h) { /* Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->h_fq_unscaled[rcat]), */ /* .01,100., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ Generic_Brent_Lk(&(tree->mod->m4mod->h_fq_unscaled[rcat]), 0.1,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(verbose) { Print_Lk(tree,"[Subst. class freq ]"); PhyML_Printf("[%10f]",tree->mod->m4mod->h_fq[rcat]); } } Switch_Eigen(NO,tree->mod); } if(tree->mod->s_opt->opt_cov_alpha) { Switch_Eigen(YES,tree->mod); /* Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->ras->alpha), */ /* .01,10., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ Generic_Brent_Lk(&(tree->mod->m4mod->alpha), 0.01,10., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(verbose) { Print_Lk(tree,"[Alpha (covarion) ]"); PhyML_Printf("[%10f]",tree->mod->m4mod->alpha); } Switch_Eigen(NO,tree->mod); } /* Substitutions between nucleotides are considered to follow a GTR model */ if(tree->mod->io->datatype == NT) { if(tree->mod->whichmodel == GTR || tree->mod->whichmodel == CUSTOM) { Switch_Eigen(YES,tree->mod); For(i,5) tree->mod->m4mod->o_rr[i] = LOG(tree->mod->m4mod->o_rr[i]); failed = YES; /* BFGS(tree,tree->mod->m4mod->o_rr,5,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES, */ BFGS(tree,tree->mod->m4mod->o_rr,5,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,YES,NO, &Return_Abs_Lk, &Num_Derivative_Several_Param, &Lnsrch,&failed); For(i,5) tree->mod->m4mod->o_rr[i] = EXP(tree->mod->m4mod->o_rr[i]); For(i,5) { /* Optimize_Single_Param_Generic(tree,&(tree->mod->m4mod->o_rr[i]), */ /* 1.E-20,1.E+10, */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ Generic_Brent_Lk(&(tree->mod->m4mod->o_rr[i]), 1.E-4,1.E+4, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); } if(verbose) Print_Lk(tree,"[GTR parameters ]"); Switch_Eigen(NO,tree->mod); } } } Set_Both_Sides(init_both_sides,tree); if(tree->both_sides == YES) Lk(NULL,tree); /* Needed to update all partial likelihoods */ /* if(tree->next) Optimiz_All_Free_Param(tree->next,verbose); */ /* else Optimiz_All_Free_Param(tree->next,verbose); */ /* if(tree->nextree) Optimiz_All_Free_Param(tree->nextree,verbose); */ } #define ITMAX 200 #define EPS 3.0e-8 #define TOLX (4*EPS) #define STPMX 100.0 static phydbl sqrarg; #define SQR(a) ((sqrarg=(a)) < SMALL ? 0.0 : sqrarg*sqrarg) void BFGS(t_tree *tree, phydbl *p, int n, phydbl gtol, phydbl difff, phydbl step_size, int logt, int is_positive, phydbl(*func)(t_tree *tree), int(*dfunc)(t_tree *tree,phydbl *param,int n_param,phydbl stepsize,int logt, phydbl(*func)(t_tree *tree),phydbl *derivatives, int is_positive), int(*lnsrch)(t_tree *tree, int n, phydbl *xold, phydbl fold, phydbl *g, phydbl *p, phydbl *x,phydbl *f, phydbl stpmax, int *check, int logt, int is_positive), int *failed) { int check,i,its,j; phydbl den,fac,fad,fae,fp,stpmax,sum=0.0,sumdg,sumxi,temp,test,fret; phydbl *dg,*g,*hdg,**hessin,*pnew,*xi; phydbl fp_old; phydbl *init,*sign; hessin = (phydbl **)mCalloc(n,sizeof(phydbl *)); For(i,n) hessin[i] = (phydbl *)mCalloc(n,sizeof(phydbl)); dg = (phydbl *)mCalloc(n,sizeof(phydbl )); g = (phydbl *)mCalloc(n,sizeof(phydbl )); pnew = (phydbl *)mCalloc(n,sizeof(phydbl )); hdg = (phydbl *)mCalloc(n,sizeof(phydbl )); xi = (phydbl *)mCalloc(n,sizeof(phydbl )); init = (phydbl *)mCalloc(n,sizeof(phydbl )); sign = (phydbl *)mCalloc(n,sizeof(phydbl )); For(i,n) init[i] = p[i]; /*! p is log transformed */ if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i])); fp=(*func)(tree); if(logt == YES) For(i,n) p[i] = LOG(p[i]); /* PhyML_Printf("\n. ENTER BFGS WITH: %f\n",fp); */ fp_old = fp; (*dfunc)(tree,p,n,step_size,logt,func,g,is_positive); /* PhyML_Printf("\n. BFGS step_size: %f",step_size); */ for (i=0;i %f stpmax: %f\n",tree->c_lnL,stpmax); */ lnsrch(tree,n,p,fp,g,xi,pnew,&fret,stpmax,&check,logt,is_positive); fp_old = fp; fp = fret; for (i=0;i test) test=temp; } if (test < TOLX || (FABS(fp-fp_old) < difff && its > 1)) { if(fp > fp_old) { For(i,n) p[i] = init[i]; *failed = YES; } if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i])); For(i,n) sign[i] = p[i] > .0 ? 1. : -1.; if(is_positive == YES) For(i,n) p[i] = FABS(p[i]); (*func)(tree); if(is_positive == YES) For(i,n) p[i] *= sign[i]; if(logt == YES) For(i,n) p[i] = LOG(p[i]); if(is_positive == YES) For(i,n) p[i] = FABS(p[i]); For(i,n) Free(hessin[i]); free(hessin); free(xi); free(pnew); free(hdg); free(g); free(dg); free(init); free(sign); return; } for (i=0;i test) test=temp; } if (test < gtol) { *failed = NO; if(logt == YES) For(i,n) p[i] = EXP(MIN(1.E+2,p[i])); For(i,n) sign[i] = p[i] > .0 ? 1. : -1.; if(is_positive == YES) For(i,n) p[i] = FABS(p[i]); (*func)(tree); if(is_positive == YES) For(i,n) p[i] *= sign[i]; if(logt == YES) For(i,n) p[i] = LOG(p[i]); if(is_positive == YES) For(i,n) p[i] = FABS(p[i]); For(i,n) Free(hessin[i]); free(hessin); free(xi); free(pnew); free(hdg); free(g); free(dg); free(init); free(sign); return; } for (i=0;i EPS*sumdg*sumxi) { fac=1.0/fac; fad=1.0/fae; for (i=0;i %f\n",tree->c_lnL); */ fp_old = fp; fp = fret; for (i=0;i test) test=temp; } if (test < TOLX || (FABS(fp_old-fp) < difff && its > 1)) { if(fp > fp_old) { For(i,n) (*(p[i])) = init[i]; *failed = 1; } if(logt == YES) For(i,n) (*(p[i])) = EXP(MIN(1.E+2,*(p[i]))); For(i,n) sign[i] = *(p[i]) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i])); (*func)(tree); if(is_positive == YES) For(i,n) *(p[i]) *= sign[i]; if(logt == YES) For(i,n) (*(p[i])) = LOG(*(p[i])); if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i])); For(i,n) Free(hessin[i]); free(hessin); free(xi); free(pnew); free(hdg); free(g); free(dg); free(init); free(sign); return; } for (i=0;i test) test=temp; } if (test < gtol) { if(logt == YES) For(i,n) (*(p[i])) = EXP(MIN(1.E+2,*(p[i]))); For(i,n) sign[i] = *(p[i]) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i])); (*func)(tree); if(is_positive == YES) For(i,n) *(p[i]) *= sign[i]; if(logt == YES) For(i,n) (*(p[i])) = LOG(*(p[i])); if(is_positive == YES) For(i,n) *(p[i]) = FABS(*(p[i])); For(i,n) Free(hessin[i]); free(hessin); free(xi); free(pnew); free(hdg); free(g); free(dg); free(init); free(sign); return; } for (i=0;i EPS*sumdg*sumxi) { fac=1.0/fac; fad=1.0/fae; for (i=0;i stpmax) For(i,n) p[i] *= stpmax/sum; /* For(i,n) PhyML_Printf("\n. lnsrch p[i]: %f",p[i]); */ slope=0.0; For(i,n) slope += g[i]*p[i]; /* PhyML_Printf("\n. lnsrch slope: %f",slope); */ test=0.0; for(i=0;i test) test=temp; } alamin=TOLX/test; alam=1.0; for (;;) { For(i,n) { x[i]=local_xold[i]+alam*p[i]; xold[i] = x[i]; /* PhyML_Printf("\n. lnsrch x[i]: %f",x[i]); */ } /* PhyML_Printf("\n. lnsrch loop slope: %f alam: %f alam2: %f",slope,alam,alam2); */ if(i==n) { if(logt == YES) For(i,n) xold[i] = EXP(MIN(1.E+2,xold[i])); For(i,n) sign[i] = xold[i] < .0 ? -1. : 1.; if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]); /* For(i,n) PhyML_Printf("\n. <<>> %f",xold[i]); */ *f=Return_Abs_Lk(tree); if(is_positive == YES) For(i,n) xold[i] *= sign[i]; if(logt == YES) For(i,n) xold[i] = LOG(xold[i]); } else *f=1.+fold+ALF*alam*slope; if (alam < alamin) { *check=1; For(i,n) xold[i] = local_xold[i]; if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]); Free(local_xold); Free(sign); return 0; } else if (*f <= fold+ALF*alam*slope) { For(i,n) xold[i] = local_xold[i]; if(is_positive == YES) For(i,n) xold[i] = FABS(xold[i]); Free(local_xold); Free(sign); return 0; } else { /* if (alam == 1.0) */ if ((alam < 1.0+SMALL) && (alam > 1.0-SMALL)) tmplam = -slope/(2.0*(*f-fold-slope)); else { rhs1 = *f-fold-alam*slope; rhs2=f2-fold2-alam2*slope; a=(rhs1/(alam*alam)-rhs2/(alam2*alam2))/(alam-alam2); b=(-alam2*rhs1/(alam*alam)+alam*rhs2/(alam2*alam2))/(alam-alam2); if (a < SMALL && a > -SMALL) tmplam = -slope/(2.0*b); else { disc=b*b-3.0*a*slope; if (disc<0.0) tmplam = 0.5*alam; else if(b <= 0.0) tmplam=(-b+SQRT(disc))/(3.0*a); else tmplam = -slope/(b+SQRT(disc)); } if (tmplam>0.5*alam) tmplam=0.5*alam; } } alam2=alam; f2 = *f; fold2=fold; alam=MAX(tmplam,0.1*alam); } Free(sign); Free(local_xold); return 1; } #undef ALF #undef TOLX #undef NRANSI ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #define ALF 1.0e-4 #define TOLX 1.0e-7 int Lnsrch_Nonaligned(t_tree *tree, int n, phydbl **xold, phydbl fold, phydbl *g, phydbl *p, phydbl *x, phydbl *f, phydbl stpmax, int *check, int logt, int is_positive) { int i; phydbl a,alam,alam2,alamin,b,disc,f2,fold2,rhs1,rhs2,slope,sum,temp,test,tmplam; phydbl *local_xold,*sign; alam = alam2 = f2 = fold2 = tmplam = .0; local_xold = (phydbl *)mCalloc(n,sizeof(phydbl)); sign = (phydbl *)mCalloc(n,sizeof(phydbl)); For(i,n) local_xold[i] = *(xold[i]); *check=0; for(sum=0.0,i=0;i stpmax) for(i=0;i test) test=temp; } alamin=TOLX/test; alam=1.0; for (;;) { for(i=0;i 1.0-SMALL)) tmplam = -slope/(2.0*(*f-fold-slope)); else { rhs1 = *f-fold-alam*slope; rhs2=f2-fold2-alam2*slope; a=(rhs1/(alam*alam)-rhs2/(alam2*alam2))/(alam-alam2); b=(-alam2*rhs1/(alam*alam)+alam*rhs2/(alam2*alam2))/(alam-alam2); if (a < SMALL && a > -SMALL) tmplam = -slope/(2.0*b); else { disc=b*b-3.0*a*slope; if (disc<0.0) tmplam = 0.5*alam; else if(b <= 0.0) tmplam=(-b+SQRT(disc))/(3.0*a); else tmplam = -slope/(b+SQRT(disc)); } if (tmplam>0.5*alam) tmplam=0.5*alam; } } alam2=alam; f2 = *f; fold2=fold; alam=MAX(tmplam,0.1*alam); } Free(local_xold); Free(sign); return 1; } #undef ALF #undef TOLX #undef NRANSI ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Dist_F_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *F, phydbl *param, t_mod *mod) { phydbl ulim,u,r,q,dum; phydbl fa, fb, fc, fu; fa = -Lk_Dist(F,FABS(*ax),mod); fb = -Lk_Dist(F,FABS(*bx),mod); if(fb > fa) { SHFT(dum,*ax,*bx,dum) SHFT(dum,fb,fa,dum) } *cx=(*bx)+MNBRAK_GOLD*(*bx-*ax); fc = -Lk_Dist(F,FABS(*cx),mod); while (fb > fc) { r=(*bx-*ax)*(fb-fc); q=(*bx-*cx)*(fb-fa); u=(*bx)-((*bx-*cx)*q-(*bx-*ax)*r)/ (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r)); ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx); if ((*bx-u)*(u-*cx) > 0.0) { fu = -Lk_Dist(F,FABS(u),mod); if (fu < fc) { *ax=(*bx); *bx=u; fa=fb; fb=fu; return(0); } else if (fu > fb) { *cx=u; fc=fu; return(0); } u=(*cx)+MNBRAK_GOLD*(*cx-*bx); fu = -Lk_Dist(F,FABS(u),mod); } else if ((*cx-u)*(u-ulim) > 0.0) { fu = -Lk_Dist(F,FABS(u),mod); if (fu < fc) { SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx)) SHFT(fb,fc,fu,-Lk_Dist(F,FABS(u),mod)) } } else if ((u-ulim)*(ulim-*cx) >= 0.0) { u = ulim; fu = -Lk_Dist(F,FABS(u),mod); } else { u =(*cx)+MNBRAK_GOLD*(*cx-*bx); fu = -Lk_Dist(F,FABS(u),mod); } SHFT(*ax,*bx,*cx,u) SHFT(fa,fb,fc,fu) } return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dist_F_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max, phydbl *param, phydbl *F, t_mod *mod) { int iter; phydbl a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; phydbl e=0.0; phydbl old_lnL,init_lnL, curr_lnL; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x = w = v = bx; old_lnL = UNLIKELY; fw = fv = fx = -Lk_Dist(F,FABS(bx),mod); curr_lnL = init_lnL = -fw; for(iter=1;iter<=BRENT_IT_MAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*FABS(x)+BRENT_ZEPS); if( ((FABS(curr_lnL-old_lnL) < mod->s_opt->min_diff_lk_local) && (curr_lnL > init_lnL - mod->s_opt->min_diff_lk_local)) || (iter > n_iter_max - 1) ) { *param = x; curr_lnL = Lk_Dist(F,*param,mod); return -curr_lnL; } if(FABS(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if(q > 0.0) p = -p; q=FABS(q); etemp=e; e=d; if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf("Golden section step\n"); */ } else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); /* PhyML_Printf("Parabolic step\n"); */ } } else { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf("Golden section step (default)\n"); */ } u=(FABS(d) >= tol1 ? x+d : x+SIGN(tol1,d)); (*param) = FABS(u); old_lnL = curr_lnL; fu = -Lk_Dist(F,FABS(u),mod); curr_lnL = -fu; /* PhyML_Printf("param=%f loglk=%f\n",*param,fu); */ /* if(fu <= fx) */ if(fu < fx) { if(iter > n_iter_max) return -fu; if(u >= x) a=x; else b=x; SHFT(v,w,x,u) SHFT(fv,fw,fx,fu) } else { if (u < x) a=u; else b=u; /* if (fu <= fw || w == x) */ if (fu < fw || FABS(w-x) < SMALL) { v=w; w=u; fv=fw; fw=fu; } /* else if (fu <= fv || v == x || v == w) */ else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL) { v=u; fv=fu; } } } Exit("\n. Too many iterations in Dist_F_Brent !"); return(-1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Opt_Dist_F(phydbl *dist, phydbl *F, t_mod *mod) { phydbl ax,bx,cx; if(*dist < mod->l_min) *dist = mod->l_min; ax = mod->l_min; bx = (*dist); cx = mod->l_max; /* Dist_F_Brak(&ax,&bx,&cx,F,dist,mod); */ Dist_F_Brent(ax,bx,cx,1.E-10,1000,dist,F,mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Missing_Dist_Brak(phydbl *ax, phydbl *bx, phydbl *cx, int x, int y, matrix *mat) { phydbl ulim,u,r,q,dum; phydbl fa, fb, fc, fu; fa = Least_Square_Missing_Dist_XY(x,y,FABS(*ax),mat); fb = Least_Square_Missing_Dist_XY(x,y,FABS(*bx),mat); if(fb > fa) { SHFT(dum,*ax,*bx,dum) SHFT(dum,fb,fa,dum) } *cx=(*bx)+MNBRAK_GOLD*((*bx)-(*ax)); fc = Least_Square_Missing_Dist_XY(x,y,FABS(*cx),mat); while (fb > fc) { r=((*bx)-(*ax))*(fb-fc); q=((*bx)-(*cx))*(fb-fa); u=(*bx)-(((*bx)-(*cx))*q-((*bx)-(*ax))*r)/ (2.0*SIGN(MAX(FABS(q-r),MNBRAK_TINY),q-r)); ulim=(*bx)+MNBRAK_GLIMIT*(*cx-*bx); if ((*bx-u)*(u-*cx) > 0.0) { fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); if (fu < fc) { *ax=(*bx); *bx=u; fa=fb; fb=fu; return(0); } else if (fu > fb) { *cx=u; fc=fu; return(0); } u=(*cx)+MNBRAK_GOLD*(*cx-*bx); fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); } else if ((*cx-u)*(u-ulim) > 0.0) { fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); if (fu < fc) { SHFT(*bx,*cx,u,*cx+MNBRAK_GOLD*(*cx-*bx)) SHFT(fb,fc,fu,Least_Square_Missing_Dist_XY(x,y,FABS(u),mat)) } } else if ((u-ulim)*(ulim-*cx) >= 0.0) { u = ulim; fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); } else { u =(*cx)+MNBRAK_GOLD*(*cx-*bx); fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); } SHFT(*ax,*bx,*cx,u) SHFT(fa,fb,fc,fu) } return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Missing_Dist_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max, int x, int y, matrix *mat) { int iter; phydbl a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,xx,xm; phydbl e=0.0; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); xx=w=v=bx; fx=Least_Square_Missing_Dist_XY(x,y,FABS(bx),mat); fw=fv=-fx; for(iter=1;iter<=BRENT_IT_MAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*FABS(xx)+BRENT_ZEPS); if(FABS(xx-xm) <= (tol2-0.5*(b-a))) { mat->dist[x][y] = xx; Least_Square_Missing_Dist_XY(x,y,mat->dist[x][y],mat); return -fx; } if(FABS(e) > tol1) { r=(xx-w)*(fx-fv); q=(xx-v)*(fx-fw); p=(xx-v)*q-(xx-w)*r; q=2.0*(q-r); if(q > 0.0) p = -p; q=FABS(q); etemp=e; e=d; if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-xx) || p >= q*(b-xx)) { d=BRENT_CGOLD*(e=(xx >= xm ? a-xx : b-xx)); /* PhyML_Printf("Golden section step\n"); */ } else { d=p/q; u=xx+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-xx); /* PhyML_Printf("Parabolic step\n"); */ } } else { d=BRENT_CGOLD*(e=(xx >= xm ? a-xx : b-xx)); /* PhyML_Printf("Golden section step (default)\n"); */ } u=(FABS(d) >= tol1 ? xx+d : xx+SIGN(tol1,d)); fu = Least_Square_Missing_Dist_XY(x,y,FABS(u),mat); /* PhyML_Printf("param=%f loglk=%f\n",u,fu); */ /* if(fu <= fx) */ if(fu < fx) { if(iter > n_iter_max) return -fu; if(u >= xx) a=xx; else b=xx; SHFT(v,w,xx,u) SHFT(fv,fw,fx,fu) } else { if (u < xx) a=u; else b=u; /* if (fu <= fw || w == xx) */ if (fu < fw || FABS(w-xx) < SMALL) { v=w; w=u; fv=fw; fw=fu; } /* else if (fu <= fv || v == xx || v == w) */ else if (fu < fv || FABS(v-xx) < SMALL || FABS(v-w) < SMALL) { v=u; fv=fu; } } } Exit("\n. Too many iterations in Missing_Dist_Brent !"); return(-1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Opt_Missing_Dist(int x, int y, matrix *mat) { phydbl ax,bx,cx; ax = DIST_MAX; bx = DIST_MAX/4.; Missing_Dist_Brak(&ax,&bx,&cx,x,y,mat); PhyML_Printf("ax=%f bx=%f cx=%f\n",FABS(ax),FABS(bx),FABS(cx)); Missing_Dist_Brent(FABS(ax),FABS(bx),FABS(cx),1.E-5,100,x,y,mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Optimiz_Alpha_And_Pinv(t_tree *mixt_tree, int verbose) { scalar_dbl **alpha; int n_alpha; t_tree *tree; int i; Switch_Eigen(NO,mixt_tree->mod); alpha = NULL; n_alpha = 0; tree = mixt_tree; do { if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->n_catg > 1) { For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break; if(i == n_alpha) { if(!alpha) alpha = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); else alpha = (scalar_dbl **)mRealloc(alpha,n_alpha+1,sizeof(scalar_dbl *)); alpha[n_alpha] = tree->mod->ras->alpha; n_alpha++; if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->free_mixt_rates == NO) { if(tree->mod->ras->n_catg > 1) { Generic_Brent_Lk(&(tree->mod->ras->alpha->v), tree->mod->ras->alpha->v/2.,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); } if(verbose) { Print_Lk(mixt_tree,"[Alpha ]"); PhyML_Printf("[%10f]",tree->mod->ras->alpha->v); } } if(tree->mod->s_opt->opt_pinvar == YES && tree->mod->ras->free_mixt_rates == NO) { tree->mod->s_opt->skip_tree_traversal = YES; Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->pinvar->v),.0001,0.9999, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty); tree->mod->s_opt->skip_tree_traversal = NO; Print_Lk(mixt_tree,"[P-inv ]"); PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v); } } } tree = tree->next_mixt; } while(tree); if(alpha) Free(alpha); return 1; /* t_tree *tree; */ /* int iter; */ /* phydbl best_alpha, best_pinv, best_mult; */ /* phydbl slope, intercept; */ /* phydbl lk_b, lk_a; */ /* phydbl f0,f1,f2,x0,x1,x2,x3; */ /* phydbl pinv0, pinv1; */ /* phydbl a, b, c; */ /* phydbl fa, fb, fc; */ /* phydbl K; */ /* phydbl alpha0, alpha1; */ /* phydbl best_lnL; */ /* scalar_dbl **alpha; */ /* int n_alpha; */ /* int i; */ /* Switch_Eigen(NO,mixt_tree->mod); */ /* alpha = NULL; */ /* n_alpha = 0; */ /* tree = mixt_tree; */ /* do */ /* { */ /* For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break; */ /* if(i == n_alpha) */ /* { */ /* if(!alpha) alpha = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); */ /* else alpha = (scalar_dbl **)mRealloc(alpha,n_alpha+1,sizeof(scalar_dbl *)); */ /* alpha[n_alpha] = tree->mod->ras->alpha; */ /* n_alpha++; */ /* if((tree->mod->s_opt->opt_pinvar) && (tree->mod->s_opt->opt_alpha) && (tree->mod->ras->n_catg > 1)) */ /* { */ /* lk_b = UNLIKELY; */ /* lk_a = UNLIKELY; */ /* /\* PhyML_Printf("\n\n. %p Init lnL = %f alpha=%f pinv=%f", *\/ */ /* /\* tree, *\/ */ /* /\* mixt_tree->c_lnL, *\/ */ /* /\* tree->mod->ras->alpha, *\/ */ /* /\* tree->mod->ras->pinvar->v); *\/ */ /* /\* Two (full) steps to compute pinv_alpha_slope & pinv_alpha_intercept *\/ */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* lk_b = mixt_tree->c_lnL; */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* Set_Both_Sides(NO,mixt_tree); */ /* Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->alpha->v),0.01,100., */ /* mixt_tree->mod->s_opt->min_diff_lk_local, */ /* mixt_tree->mod->s_opt->brent_it_max, */ /* mixt_tree->mod->s_opt->quickdirty); */ /* Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->pinvar->v),.0001,0.9999, */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ /* pinv0 = tree->mod->ras->pinvar->v; */ /* alpha0 = tree->mod->ras->alpha->v; */ /* f0 = mixt_tree->c_lnL; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* Set_Both_Sides(NO,mixt_tree); */ /* Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->alpha->v),0.01,100., */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ /* Optimize_Single_Param_Generic(mixt_tree,&(tree->mod->ras->pinvar->v),.0001,0.9999, */ /* tree->mod->s_opt->min_diff_lk_local, */ /* tree->mod->s_opt->brent_it_max, */ /* tree->mod->s_opt->quickdirty); */ /* lk_a = mixt_tree->c_lnL; */ /* pinv1 = tree->mod->ras->pinvar->v; */ /* alpha1 = tree->mod->ras->alpha->v; */ /* f1 = mixt_tree->c_lnL; */ /* best_lnL = f1; */ /* if(lk_a < lk_b - mixt_tree->mod->s_opt->min_diff_lk_local) */ /* { */ /* PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ /* } */ /* else if(FABS(lk_a - lk_b) < mixt_tree->mod->s_opt->min_diff_lk_local) */ /* { */ /* if(alpha) Free(alpha); */ /* return 1; */ /* } */ /* Record_Br_Len(mixt_tree); */ /* best_alpha = tree->mod->ras->alpha->v; */ /* best_pinv = tree->mod->ras->pinvar->v; */ /* best_mult = tree->mod->br_len_mult->v; */ /* /\* PhyML_Printf("\n\n. Init lnL after std opt = %f [%f] best_alpha=%f best_pinv=%f",mixt_tree->c_lnL,Lk(NULL,mixt_tree),best_alpha,best_pinv); *\/ */ /* /\* PhyML_Printf("\n. Best_lnL = %f %d",best_lnL,tree->mod->ras->invar); *\/ */ /* slope = (pinv1 - pinv0)/(alpha1 - alpha0); */ /* intercept = pinv1 - slope * alpha1; */ /* /\* printf("\n. slope = %f pinv1=%f pinv0=%f alpha1=%f alpha0=%f", *\/ */ /* /\* slope,pinv1,pinv0,alpha1,alpha0); *\/ */ /* if((slope > 0.001) && (slope < 1./0.001)) */ /* { */ /* /\* PhyML_Printf("\n. pinv0 = %f, pinv1 = %f, alpha0 = %f, alpha1 = %f",pinv0,pinv1,alpha0,alpha1); *\/ */ /* /\* PhyML_Printf("\n. slope = %f intercept = %f",slope,intercept); *\/ */ /* K = 0.381966; */ /* if(alpha1 < alpha0) */ /* { */ /* c = alpha0; */ /* b = alpha1; */ /* fc = f0; */ /* fb = f1; */ /* a = (0.1 < alpha1)?(0.1):(0.5*alpha1); */ /* tree->mod->ras->alpha->v = a; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* fa = mixt_tree->c_lnL; */ /* iter = 0; */ /* /\* PhyML_Printf("\n. a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f (alpha=%f pinv=%f)",a,b,c,fa,fb,fc,tree->mod->ras->alpha->v,tree->mod->ras->pinvar->v); *\/ */ /* while(fa > fb) */ /* { */ /* a = a/5.; */ /* tree->mod->ras->alpha->v = a; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* fa = mixt_tree->c_lnL; */ /* /\* PhyML_Printf("\n1 a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f",a,b,c,fa,fb,fc); *\/ */ /* if(iter++ > 10) */ /* { */ /* if(alpha) Free(alpha); */ /* return 0; */ /* } */ /* } */ /* } */ /* else */ /* { */ /* a = alpha0; */ /* b = alpha1; */ /* fa = f0; */ /* fb = f1; */ /* c = (alpha1 < 2.)?(2.0):(2.*alpha1); */ /* tree->mod->ras->alpha->v = c; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* fc = mixt_tree->c_lnL; */ /* /\* PhyML_Printf("\n. a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f (alpha=%f pinv=%f)",a,b,c,fa,fb,fc,tree->mod->ras->alpha->v,tree->mod->ras->pinvar->v); *\/ */ /* iter = 0; */ /* while(fc > fb) */ /* { */ /* c = c*2.; */ /* tree->mod->ras->alpha->v = c; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* fc = mixt_tree->c_lnL; */ /* /\* PhyML_Printf("\n2 a=%f, b=%f, c=%f, fa=%f, fb=%f, fc=%f",a,b,c,fa,fb,fc); *\/ */ /* if(iter++ > 10) */ /* { */ /* if(alpha) Free(alpha); */ /* return 0; */ /* } */ /* } */ /* } */ /* if(FABS(b - c) > FABS(a - b)) */ /* { */ /* x0 = a; x1 = b; x3 = c; */ /* x2 = b + K * FABS(b - c); */ /* f0 = fa; */ /* f1 = fb; */ /* tree->mod->ras->alpha->v = x2; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* f2 = mixt_tree->c_lnL; */ /* } */ /* else /\* |b -c| < |a - b| *\/ */ /* { */ /* x0 = a; x2 = b; x3 = c; */ /* x1 = b - K * FABS(b - a); */ /* f0 = fa; */ /* f2 = fb; */ /* tree->mod->ras->alpha->v = x1; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* f1 = mixt_tree->c_lnL; */ /* } */ /* iter = 0; */ /* do */ /* { */ /* /\* PhyML_Printf("\n. x0=%f, x1=%f, x2=%f, x3=%f, f0=%f, f1=%f, f2=%f, f3=%f", *\/ */ /* /\* x0,x1,x2,x3,f0,f1,f2,f3); *\/ */ /* if(f1 > f2) */ /* { */ /* x3 = x2; */ /* x2 = x1; */ /* x1 = x2 - K * FABS(x2 - x0); */ /* f2 = f1; */ /* tree->mod->ras->alpha->v = x1; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* f1 = mixt_tree->c_lnL; */ /* if(f1 > best_lnL) */ /* { */ /* Record_Br_Len(mixt_tree); */ /* best_alpha = tree->mod->ras->alpha->v; */ /* best_pinv = tree->mod->ras->pinvar->v; */ /* best_mult = tree->mod->br_len_mult->v; */ /* /\* PhyML_Printf("\n>.< New alpha=%f pinv=%f",best_alpha,best_pinv); *\/ */ /* } */ /* /\* PhyML_Printf("\n> f1=%f",f1); *\/ */ /* } */ /* else /\* f1 < f2 *\/ */ /* { */ /* x0 = x1; */ /* x1 = x2; */ /* x2 = x2 + K * FABS(x3 - x2); */ /* f0 = f1; */ /* f1 = f2; */ /* tree->mod->ras->alpha->v = x2; */ /* tree->mod->ras->pinvar->v = slope * tree->mod->ras->alpha->v + intercept; */ /* if(tree->mod->ras->pinvar->v > 1.0) tree->mod->ras->pinvar->v = 0.9; */ /* if(tree->mod->ras->pinvar->v < 0.0) tree->mod->ras->pinvar->v = 0.001; */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* Optimize_Br_Len_Serie(mixt_tree); */ /* f2 = mixt_tree->c_lnL; */ /* if(f2 > best_lnL) */ /* { */ /* Record_Br_Len(mixt_tree); */ /* best_alpha = tree->mod->ras->alpha->v; */ /* best_pinv = tree->mod->ras->pinvar->v; */ /* best_mult = tree->mod->br_len_mult->v; */ /* /\* PhyML_Printf("\n>o< New alpha=%f pinv=%f",best_alpha,best_pinv); *\/ */ /* } */ /* /\* PhyML_Printf("\n> f2=%f",f2); *\/ */ /* } */ /* if(FABS(f1 - f2) < 0.01) break; */ /* iter++; */ /* }while(iter < 100); */ /* } */ /* tree->mod->ras->alpha->v = best_alpha; */ /* tree->mod->ras->pinvar->v = best_pinv; */ /* tree->mod->br_len_mult->v = best_mult; */ /* Restore_Br_Len(mixt_tree); */ /* Set_Both_Sides(YES,mixt_tree); */ /* Lk(NULL,mixt_tree); */ /* if(verbose) */ /* { */ /* Print_Lk(mixt_tree,"[Alpha ]"); */ /* PhyML_Printf("[%10f]",tree->mod->ras->alpha->v); */ /* Print_Lk(mixt_tree,"[P-inv ]"); */ /* PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v); */ /* } */ /* } */ /* } */ /* tree = tree->next_mixt; */ /* } */ /* while(tree); */ /* /\* PhyML_Printf("\n\n. Init lnL after golden opt = %f [%f] best_alpha=%f best_pinv=%f",tree->c_lnL,Lk(tree),best_alpha,best_pinv); *\/ */ /* if(alpha) Free(alpha); */ /* return 1; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol, int n_iter_max, int quickdirty, phydbl (*obj_func)(t_edge *,t_tree *,supert_tree *), t_edge *branch, t_tree *tree, supert_tree *stree, int logt) { int iter; phydbl a,b,d,etemp,fu,fv,fw,fx,p,q,r,tol1,tol2,u,v,w,x,xm; phydbl e=0.0; phydbl old_lnL,init_lnL; phydbl bx = *param; d=0.0; a=((ax < cx) ? ax : cx); b=((ax > cx) ? ax : cx); x=w=v=bx; old_lnL = UNLIKELY; (*param) = bx; if(logt == YES) (*param) = EXP(MIN(1.E+2,*param)); fw=fv=fx=fu=-(*obj_func)(branch,tree,stree); if(logt == YES) (*param) = LOG(*param); init_lnL = -fw; /* PhyML_Printf("\n. %p %p %p init_lnL = %f a=%f b=%f c=%f",branch,tree,stree,init_lnL,ax,bx,cx); */ for(iter=1;iter<=BRENT_IT_MAX;iter++) { xm=0.5*(a+b); tol2=2.0*(tol1=tol*x+BRENT_ZEPS); if((fu > init_lnL + tol) && (quickdirty)) { (*param) = x; if(logt == YES) (*param) = EXP(MIN(1.E+2,*param)); fu = (*obj_func)(branch,tree,stree); if(logt == YES) (*param) = LOG(*param); return fu; } /* if(((FABS(cur_lnL-old_lnL) < tol) && (cur_lnL > init_lnL - tol)) || (iter > n_iter_max - 1)) */ if((FABS(fu-old_lnL) < tol) || (iter > n_iter_max - 1)) { (*param) = x; if(logt == YES) (*param) = EXP(MIN(1.E+2,*param)); fu = (*obj_func)(branch,tree,stree); if(logt == YES) (*param) = LOG(*param); /* Exit("\n"); */ return fu; } if(FABS(e) > tol1) { r=(x-w)*(fx-fv); q=(x-v)*(fx-fw); p=(x-v)*q-(x-w)*r; q=2.0*(q-r); if(q > 0.0) p = -p; q=FABS(q); etemp=e; e=d; if(FABS(p) >= FABS(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x)) { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf(" Golden section step\n"); */ } else { d=p/q; u=x+d; if (u-a < tol2 || b-u < tol2) d=SIGN(tol1,xm-x); /* PhyML_Printf(" Parabolic step [e=%f]\n",e); */ } } else { d=BRENT_CGOLD*(e=(x >= xm ? a-x : b-x)); /* PhyML_Printf(" Golden section step (default) [e=%f tol1=%f a=%f b=%f d=%f]\n",e,tol1,a,b,d); */ } u=(FABS(d) >= tol1 ? x+d : x+SIGN(tol1,d)); (*param) = u; old_lnL = fu; if(logt == YES) (*param) = EXP(MIN(1.E+2,*param)); fu = -(*obj_func)(branch,tree,stree); if(logt == YES) (*param) = LOG(*param); /* PhyML_Printf("\n. iter=%d/%d param=%f lnL=%f",iter,BRENT_IT_MAX,*param,fu); */ if(fu <= fx) { if(u >= x) a=x; else b=x; SHFT(v,w,x,u) SHFT(fv,fw,fx,fu) } else { if (u < x) a=u; else b=u; /* if (fu <= fw || w == x) */ if (fu < fw || FABS(w-x) < SMALL) { v=w; w=u; fv=fw; fw=fu; } /* else if (fu <= fv || v == x || v == w) */ else if (fu < fv || FABS(v-x) < SMALL || FABS(v-w) < SMALL) { v=u; fv=fu; } } } Exit("\n. Too many iterations in Generic_Brent_Lk !"); return(-1); /* Not Reached ?? *param=x; */ /* Not Reached ?? return fx; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* find ML erstimates of node heights given fixed substitution rates on branches. Also optimizes the overall substitution rate */ void Round_Optimize_Node_Heights(t_tree *tree) { phydbl cur_lnL, new_lnL; int n_iter; cur_lnL = UNLIKELY; new_lnL = Lk(NULL,tree); printf("\n. cur_lnL = %f new_lnL=%f",cur_lnL,new_lnL); n_iter = 0; while(fabs(new_lnL - cur_lnL) > tree->mod->s_opt->min_diff_lk_local) { cur_lnL = tree->c_lnL; Opt_Node_Heights_Recurr(tree); Generic_Brent_Lk(&(tree->rates->clock_r), tree->rates->min_clock, tree->rates->max_clock, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); printf("\n. cur_lnL=%f new_lnL=%f clock_r=%G root height=%f", cur_lnL,new_lnL,tree->rates->clock_r,tree->rates->nd_t[tree->n_root->num]); new_lnL = tree->c_lnL; n_iter++; if(n_iter > 100) break; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Opt_Node_Heights_Recurr(t_tree *tree) { Opt_Node_Heights_Recurr_Pre(tree->n_root,tree->n_root->v[2],tree); Opt_Node_Heights_Recurr_Pre(tree->n_root,tree->n_root->v[1],tree); Generic_Brent_Lk(&(tree->rates->nd_t[tree->n_root->num]), MIN(tree->rates->t_prior_max[tree->n_root->num], MIN(tree->rates->nd_t[tree->n_root->v[2]->num], tree->rates->nd_t[tree->n_root->v[1]->num])), tree->rates->t_prior_min[tree->n_root->num], tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Opt_Node_Heights_Recurr_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; phydbl t0,t2,t3; phydbl t_min,t_max; t_node *v2,*v3; v2 = v3 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v2) { v2 = d->v[i]; } else { v3 = d->v[i]; } } Opt_Node_Heights_Recurr_Pre(d,v2,tree); Opt_Node_Heights_Recurr_Pre(d,v3,tree); t0 = tree->rates->nd_t[a->num]; t2 = tree->rates->nd_t[v2->num]; t3 = tree->rates->nd_t[v3->num]; t_min = t0; t_max = MIN(t2,t3); t_min = MAX(t_min,tree->rates->t_prior_min[d->num]); t_max = MIN(t_max,tree->rates->t_prior_max[d->num]); t_min += tree->rates->min_dt; t_max -= tree->rates->min_dt; if(t_min > t_max) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } Generic_Brent_Lk(&(tree->rates->nd_t[d->num]), t_min,t_max, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); /* printf("\n. t%d = %f [%f;%f] lnL = %f",d->num,tree->rates->nd_t[d->num],t_min,t_max,tree->c_lnL); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_RR_Params(t_tree *mixt_tree, int verbose) { t_tree *tree; t_rmat **r_mat; int n_r_mat; int i; Switch_Eigen(YES,mixt_tree->mod); n_r_mat = 0; tree = mixt_tree; r_mat = NULL; do { if(tree->next) tree = tree->next; For(i,n_r_mat) if(tree->mod->r_mat == r_mat[i]) break; if(i == n_r_mat) // tree->mod->r_mat was not found before { if(!r_mat) r_mat = (t_rmat **)mCalloc(1,sizeof(t_rmat *)); else r_mat = (t_rmat **)mRealloc(r_mat,n_r_mat+1,sizeof(t_rmat *)); r_mat[n_r_mat] = tree->mod->r_mat; n_r_mat++; if((tree->mod->whichmodel == GTR) || ((tree->mod->whichmodel == CUSTOM) && (tree->mod->s_opt->opt_rr) && (tree->mod->r_mat->n_diff_rr > 1))) { int failed,i; For(i,tree->mod->r_mat->n_diff_rr) tree->mod->r_mat->rr_val->v[i] = LOG(tree->mod->r_mat->rr_val->v[i]); failed = YES; /* BFGS(mixt_tree,tree->mod->r_mat->rr_val->v,tree->mod->r_mat->n_diff_rr,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES, */ if(tree->mod->r_mat->n_diff_rr > 2) { BFGS(mixt_tree,tree->mod->r_mat->rr_val->v,tree->mod->r_mat->n_diff_rr,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,YES,NO, &Return_Abs_Lk, &Num_Derivative_Several_Param, &Lnsrch,&failed); } For(i,tree->mod->r_mat->n_diff_rr) tree->mod->r_mat->rr_val->v[i] = EXP(tree->mod->r_mat->rr_val->v[i]); if(failed == YES) { For(i,tree->mod->r_mat->n_diff_rr) if(i != 5) { Generic_Brent_Lk(&(tree->mod->r_mat->rr_val->v[i]), 1.E-2,1.E+2, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); } } if(verbose) Print_Lk(tree->mixt_tree? tree->mixt_tree: tree,"[GTR parameters ]"); } } tree = tree->next; if(!tree) break; } while(1); if(r_mat) Free(r_mat); Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_TsTv(t_tree *mixt_tree, int verbose) { scalar_dbl **tstv; int n_tstv; t_tree *tree; int i; Switch_Eigen(YES,mixt_tree->mod); tstv = NULL; n_tstv = 0; tree = mixt_tree; do { if(tree->next) tree = tree->next; For(i,n_tstv) if(tree->mod->kappa == tstv[i]) break; if(i == n_tstv) { if(!tstv) tstv = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); else tstv = (scalar_dbl **)mRealloc(tstv,n_tstv+1,sizeof(scalar_dbl *)); tstv[n_tstv] = tree->mod->kappa; n_tstv++; if(tree->mod->s_opt->opt_kappa) { Generic_Brent_Lk(&(tree->mod->kappa->v), 0.1,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(verbose) { Print_Lk(mixt_tree,"[Ts/ts ratio ]"); PhyML_Printf("[%10f]",tree->mod->kappa->v); } } } tree = tree->next; } while(tree); if(tstv) Free(tstv); Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Pinv(t_tree *mixt_tree, int verbose) { scalar_dbl **pinv; int n_pinv; t_tree *tree; int i; Switch_Eigen(NO,mixt_tree->mod); pinv = NULL; n_pinv = 0; tree = mixt_tree; do { For(i,n_pinv) if(tree->mod->ras->pinvar == pinv[i]) break; if(i == n_pinv) { if(!pinv) pinv = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); else pinv = (scalar_dbl **)mRealloc(pinv,n_pinv+1,sizeof(scalar_dbl *)); pinv[n_pinv] = tree->mod->ras->pinvar; n_pinv++; if(tree->mod->s_opt->opt_pinvar == YES && tree->mod->s_opt->opt_alpha == NO) { Generic_Brent_Lk(&(tree->mod->ras->pinvar->v), 0.0001,0.9999, tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(verbose) { Print_Lk(mixt_tree,"[P-inv ]"); PhyML_Printf("[%10f]",tree->mod->ras->pinvar->v); } } } tree = tree->next; } while(tree); if(pinv) Free(pinv); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Alpha(t_tree *mixt_tree, int verbose) { scalar_dbl **alpha; int n_alpha; t_tree *tree; int i; Switch_Eigen(NO,mixt_tree->mod); alpha = NULL; n_alpha = 0; tree = mixt_tree; do { if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->n_catg > 1) { For(i,n_alpha) if(tree->mod->ras->alpha == alpha[i]) break; if(i == n_alpha) { if(!alpha) alpha = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); else alpha = (scalar_dbl **)mRealloc(alpha,n_alpha+1,sizeof(scalar_dbl *)); alpha[n_alpha] = tree->mod->ras->alpha; n_alpha++; if(tree->mod->s_opt->opt_alpha == YES && tree->mod->ras->free_mixt_rates == NO && tree->mod->s_opt->opt_pinvar == NO) { if(tree->mod->ras->n_catg > 1) { Generic_Brent_Lk(&(tree->mod->ras->alpha->v), tree->mod->ras->alpha->v/2.,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); } if(verbose) { Print_Lk(mixt_tree,"[Alpha ]"); PhyML_Printf("[%10f]",tree->mod->ras->alpha->v); } } } } tree = tree->next_mixt; } while(tree); if(alpha) Free(alpha); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Free_Rate(t_tree *mixt_tree, int verbose) { t_tree *tree; int fast; int i,pos,failed; phydbl lk_before, lk_after; tree = mixt_tree; lk_before = lk_after = UNLIKELY; do { if((tree->mod->s_opt->opt_free_mixt_rates) && (tree->mod->ras->free_mixt_rates == YES) && (tree->mod->ras->n_catg > 1)) { if(tree->mod->s_opt->serial_free_rates == YES) { fast = YES; lk_before = tree->c_lnL; Optimize_Free_Rate_Weights(tree,fast,verbose); Optimize_Free_Rate_Rr(tree,fast,verbose); lk_after = tree->c_lnL; if(lk_after < lk_before - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== lk_before: %f lk_after: %f diff: %G",lk_before,lk_after,lk_before-lk_after); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } if(FABS(lk_before - lk_after) > 0.001) { phydbl **x; x = (phydbl **)mCalloc(2*tree->n_otu-3 + 2*tree->mod->ras->n_catg,sizeof(phydbl *)); pos = 0; lk_before = tree->c_lnL; /* For(i,2*tree->n_otu-3) x[pos++] = &(tree->a_edges[i]->l->v); */ For(i,tree->mod->ras->n_catg) x[pos++] = tree->mod->ras->gamma_rr_unscaled->v+i; For(i,tree->mod->ras->n_catg) x[pos++] = tree->mod->ras->gamma_r_proba_unscaled->v+i; /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = LOG(MAX(1.E-10,*(x[i]))); */ /* For(i,2*tree->mod->ras->n_catg) printf("\n:: %12f",*(x[i])); fflush(NULL); */ For(i,2*tree->mod->ras->n_catg) *(x[i]) = LOG(MAX(1.E-10,*(x[i]))); /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) printf("\n<> %12f",*(x[i])); */ /* For(i,2*tree->mod->ras->n_catg) printf("\n<> %12f",*(x[i])); fflush(NULL); */ failed = YES; /* BFGS_Nonaligned(tree,x,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg,1.e-5,tree->mod->s_opt->min_diff_lk_global,1.e-5,YES, */ BFGS_Nonaligned(tree,x,2*tree->mod->ras->n_catg,1.e-5,tree->mod->s_opt->min_diff_lk_global,1.e-5,YES,NO, &Return_Abs_Lk, &Num_Derivative_Several_Param_Nonaligned, &Lnsrch_Nonaligned,&failed); /* For(i,2*tree->n_otu-3 + 2*tree->mod->ras->n_catg) *(x[i]) = EXP(*(x[i])); */ For(i,2*tree->mod->ras->n_catg) *(x[i]) = EXP(MIN(1.E+2,*(x[i]))); lk_after = tree->c_lnL; /* For(i,2*tree->mod->ras->n_catg) printf("\n>< %12f",*(x[i])); fflush(NULL); */ if(lk_after < lk_before - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== lk_before: %f lk_after: %f diff: %G",lk_before,lk_after,lk_before-lk_after); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } Free(x); } } tree = tree->next_mixt; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose) { phydbl lk_before, lk_after; lk_before = tree->c_lnL; if(tree->prev == NULL && tree->next == NULL) { int i; phydbl wm; /* tree->mod->s_opt->curr_opt_free_rates = YES; */ if(fast == YES) { For(i,tree->mod->ras->n_catg) tree->mod->ras->skip_rate_cat[i] = YES; tree->mod->ras->normalise_rr = NO; wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v, tree->mod->ras->gamma_r_proba->v, tree->mod->ras->n_catg); tree->mod->ras->free_rate_mr->v = 100.; For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v /= (wm * tree->mod->ras->free_rate_mr->v); } For(i,tree->mod->ras->n_catg-1) { if(fast == YES) tree->mod->ras->skip_rate_cat[i] = NO; Generic_Brent_Lk(&(tree->mod->ras->gamma_rr_unscaled->v[i]), 0.0, 100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); if(fast == YES) tree->mod->ras->skip_rate_cat[i] = YES; lk_after = tree->c_lnL; if(lk_after < lk_before - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== lk_before: %f lk_after: %f diff: %G",lk_before,lk_after,lk_before-lk_after); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } } if(fast == YES) { For(i,tree->mod->ras->n_catg) tree->mod->ras->skip_rate_cat[i] = NO; tree->mod->ras->normalise_rr = YES; wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v, tree->mod->ras->gamma_r_proba->v, tree->mod->ras->n_catg); For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v *= (wm * tree->mod->ras->free_rate_mr->v); } /* tree->mod->s_opt->curr_opt_free_rates = NO; */ } else { int i; For(i,tree->mod->ras->n_catg-1) { Generic_Brent_Lk(&(tree->mod->ras->gamma_rr_unscaled->v[i]), 1.E-2,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); } } lk_after = tree->c_lnL; if(lk_after < lk_before - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== lk_before: %f lk_after: %f diff: %G",lk_before,lk_after,lk_before-lk_after); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } if(verbose) Print_Lk(tree,"[Rate class values ]"); /* int i; */ /* For(i,tree->mod->ras->n_catg) */ /* { */ /* printf("\n+ c %2d p: %15f r: %15f up: %15f ur: %5f", */ /* i+1, */ /* tree->mod->ras->gamma_r_proba->v[i], */ /* tree->mod->ras->gamma_rr->v[i], */ /* tree->mod->ras->gamma_r_proba_unscaled->v[i], */ /* tree->mod->ras->gamma_rr_unscaled->v[i]); */ /* } */ /* fflush(NULL); */ /* printf("\n. LK: %f",Lk(NULL,tree)); */ /* int i; */ /* printf("\n"); */ /* printf("X*X %f ",tree->c_lnL); */ /* /\* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_rr_unscaled->v[i]); *\/ */ /* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_rr->v[i]); */ /* For(i,tree->mod->ras->n_catg) printf("%f ",tree->mod->ras->gamma_r_proba->v[i]); */ /* For(i,2*tree->n_otu-3) printf("%f ",tree->a_edges[i]->l->v); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Free_Rate_Weights(t_tree *tree, int fast, int verbose) { int i; phydbl wm; phydbl lk_before, lk_after; lk_before = tree->c_lnL; /*! Only skip tree traversal when data is not partitionned */ if(tree->prev == NULL && tree->next == NULL && fast == YES) { tree->mod->s_opt->skip_tree_traversal = YES; tree->mod->ras->normalise_rr = NO; wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v, tree->mod->ras->gamma_r_proba->v, tree->mod->ras->n_catg); tree->mod->ras->free_rate_mr->v = 100.; For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v /= (wm * tree->mod->ras->free_rate_mr->v); } For(i,tree->mod->ras->n_catg-1) { Generic_Brent_Lk(&(tree->mod->ras->gamma_r_proba_unscaled->v[i]), 0.0, 100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,tree,NULL,NO); } if(tree->mod->s_opt->skip_tree_traversal == YES && fast == YES) { tree->mod->s_opt->skip_tree_traversal = NO; tree->mod->ras->normalise_rr = YES; wm = Weighted_Mean(tree->mod->ras->gamma_rr_unscaled->v, tree->mod->ras->gamma_r_proba->v, tree->mod->ras->n_catg); For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v *= (wm * tree->mod->ras->free_rate_mr->v); } lk_after = tree->c_lnL; if(lk_after < lk_before - tree->mod->s_opt->min_diff_lk_global) { PhyML_Printf("\n== lk_before: %f lk_after: %f diff: %G",lk_before,lk_after,lk_before-lk_after); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit(""); } if(verbose) Print_Lk(tree,"[Rate class freqs. ]"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_State_Freqs(t_tree *mixt_tree, int verbose) { vect_dbl **freqs; int n_freqs; t_tree *tree; int i; int failed; Switch_Eigen(YES,mixt_tree->mod); freqs = NULL; n_freqs = 0; tree = mixt_tree; do { if(tree->next) tree = tree->next; For(i,n_freqs) if(tree->mod->e_frq->pi_unscaled == freqs[i]) break; if(i == n_freqs) { if(!freqs) freqs = (vect_dbl **)mCalloc(1,sizeof(vect_dbl *)); else freqs = (vect_dbl **)mRealloc(freqs,n_freqs+1,sizeof(vect_dbl *)); freqs[n_freqs] = tree->mod->e_frq->pi_unscaled; n_freqs++; if((tree->mod->s_opt->opt_state_freq) && (tree->io->datatype == NT)) { failed = YES; BFGS(mixt_tree,tree->mod->e_frq->pi_unscaled->v,tree->mod->ns,1.e-5,tree->mod->s_opt->min_diff_lk_local,1.e-5,NO,YES, &Return_Abs_Lk, &Num_Derivative_Several_Param, &Lnsrch,&failed); if(failed == YES) { For(i,tree->mod->ns) { Generic_Brent_Lk(&(tree->mod->e_frq->pi_unscaled->v[i]), 0.,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); } } if(verbose) { Print_Lk(mixt_tree,"[Nucleotide freqs. ]"); } } } tree = tree->next; } while(tree); if(freqs) Free(freqs); Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Rmat_Weights(t_tree *mixt_tree, int verbose) { scalar_dbl *r_mat_weight; Switch_Eigen(NO,mixt_tree->mod); if(mixt_tree->is_mixt_tree == NO) return; r_mat_weight = mixt_tree->next->mod->r_mat_weight; if(mixt_tree->next->mod->s_opt->opt_rmat_weight == YES) { do { Generic_Brent_Lk(&(r_mat_weight->v), 0.,100., mixt_tree->mod->s_opt->min_diff_lk_local, mixt_tree->mod->s_opt->brent_it_max, mixt_tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(verbose) { Print_Lk(mixt_tree,"[Rate mat. weights ]"); } r_mat_weight = r_mat_weight->next; } while(r_mat_weight); } Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Efrq_Weights(t_tree *mixt_tree, int verbose) { scalar_dbl *e_frq_weight; Switch_Eigen(NO,mixt_tree->mod); if(mixt_tree->is_mixt_tree == NO) return; e_frq_weight = mixt_tree->next->mod->e_frq_weight; if(mixt_tree->next->mod->s_opt->opt_efrq_weight == YES) { do { Generic_Brent_Lk(&(e_frq_weight->v), 0.,100., mixt_tree->mod->s_opt->min_diff_lk_local, mixt_tree->mod->s_opt->brent_it_max, mixt_tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(verbose) { Print_Lk(mixt_tree,"[Equ. frq. weights ]"); } e_frq_weight = e_frq_weight->next; } while(e_frq_weight); } Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimize_Lambda(t_tree *mixt_tree, int verbose) { scalar_dbl **lambda; int n_lambda; t_tree *tree; int i; Switch_Eigen(YES,mixt_tree->mod); lambda = NULL; n_lambda = 0; tree = mixt_tree; do { if(tree->next) tree = tree->next; For(i,n_lambda) if(tree->mod->lambda == lambda[i]) break; if(i == n_lambda) { if(!lambda) lambda = (scalar_dbl **)mCalloc(1,sizeof(scalar_dbl *)); else lambda = (scalar_dbl **)mRealloc(lambda,n_lambda+1,sizeof(scalar_dbl *)); lambda[n_lambda] = tree->mod->lambda; n_lambda++; if(tree->mod->s_opt->opt_lambda) { Generic_Brent_Lk(&(tree->mod->lambda->v), 0.001,100., tree->mod->s_opt->min_diff_lk_local, tree->mod->s_opt->brent_it_max, tree->mod->s_opt->quickdirty, Wrap_Lk,NULL,mixt_tree,NULL,NO); if(verbose) { Print_Lk(mixt_tree,"[Lambda ]"); PhyML_Printf("[%10f]",tree->mod->lambda->v); } } } tree = tree->next; } while(tree); if(lambda) Free(lambda); Switch_Eigen(NO,mixt_tree->mod); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/optimiz.h000066400000000000000000000202631263450375500153150ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef OPTIMIZ_H #define OPTIMIZ_H #include "utilities.h" #include "lk.h" #include "free.h" #include "models.h" #include "mg.h" #include "tiporder.h" void Optimiz_Ext_Br(t_tree *tree); void Optimize_Param_Parall(t_tree *tree); phydbl Optimize_Branch_Quad(t_tree *tree, calign *cdata, t_edge *b_fcus); void Optimize_After_Hide(t_tree *tree, calign *cdata, t_node *h); void Round_Optimize(t_tree *tree, calign *data, int n_round_max); int Dist_Seq_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, calign *data, int num1, int num2, t_mod *mod); phydbl Dist_Seq_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, calign *data, int num1, int num2, t_mod *mod); phydbl Kappa_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata); phydbl Lambda_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata); phydbl Alpha_Golden_Br_Opt(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata, int n_opt, phydbl *init_l); phydbl Alpha_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol,phydbl *xmin, t_tree *tree, calign *cdata); phydbl Br_Len_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_edge *b_fcus, t_tree *tree); phydbl Br_Len_Brent(phydbl prop_min, phydbl prop_max, t_edge *b_fcus, t_tree *tree); int Br_Len_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_edge *b_fcus, t_tree *tree); phydbl Optimize_Path_Length(t_mod *mod, calign *cdata, t_edge *a, int lra, t_edge *b, int lrb, phydbl i_len); void Optimize_Param_Serie(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tree, calign *cdata, int n_passes); phydbl Optimize_Dist(t_mod *mod, phydbl init, calign *twoseqs); phydbl Pinvar_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata, int n_iter_max); void Optimize_Pinvar(t_tree *tree); int Lambda_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_tree *tree); int Kappa_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_tree *tree); int Alpha_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_tree *tree); int Pinvar_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_tree *tree); void Optimiz_All_Free_Param(t_tree *tree, int verbose); void Optimiz_RRparam_GTR(t_tree *tree, int num_param); phydbl RRparam_GTR_Golden(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, calign *cdata, phydbl *param, int n_iter_max); int Powell_GTR_Param(t_tree *tree, phydbl *p, int n, phydbl ftol); phydbl Linmin_GTR_Param(t_tree *tree,phydbl *p, phydbl *xi, int n); phydbl F1dim(t_tree *tree, phydbl x, phydbl *p, phydbl *xi, phydbl n); int Mnbrak_1dim(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, t_tree *tree, phydbl *p, phydbl *xi, phydbl n); phydbl Brent_1dim(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, phydbl *p, phydbl *xi, phydbl n); int Min_With_Derivatives(t_tree *tree, phydbl *p, int n, phydbl ftol, phydbl step_size, phydbl (*func) (), void (*dfunc)(), phydbl (*linmin)()); void BFGS(t_tree *tree, phydbl *p, int n, phydbl gtol, phydbl difff, phydbl step_size, int logt, int is_positive, phydbl(*func)(t_tree *tree), int(*dfunc)(t_tree *tree,phydbl *param,int n_param,phydbl stepsize,int logt,phydbl(*func)(t_tree *tree),phydbl *derivatives, int is_positive), int(*lnsrch)(t_tree *tree, int n, phydbl *xold, phydbl fold,phydbl *g, phydbl *p, phydbl *x,phydbl *f, phydbl stpmax, int *check, int logt, int is_positive), int *failed); void BFGS_Nonaligned(t_tree *tree, phydbl **p, int n, phydbl gtol, phydbl difff, phydbl step_size, int logt, int is_positive, phydbl(*func)(t_tree *tree), int(*dfunc_nonaligned)(t_tree *tree,phydbl **param,int n_param,phydbl stepsize,int logt,phydbl(*func)(t_tree *tree),phydbl *derivatives, int is_positive), int(*lnsrch_nonaligned)(t_tree *tree, int n, phydbl **xold, phydbl fold,phydbl *g, phydbl *p, phydbl *x,phydbl *f, phydbl stpmax, int *check, int logt, int is_positive), int *failed); void Optimize_Single_Param_Generic(t_tree *tree, phydbl *param, phydbl lim_inf, phydbl lim_sup, phydbl tol, int n_max_iter, int quickdirty); int Generic_Brak(phydbl *param, phydbl *ax, phydbl *bx, phydbl *cx, phydbl *fa, phydbl *fb, phydbl *fc, phydbl lim_inf, phydbl lim_sup, t_tree *tree); phydbl Generic_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, int n_iter_max,int quickdirty); void Optimize_Br_Len_Serie(t_tree *tree); void Optimize_Br_Len_Serie_Post(t_node *a, t_node *d, t_edge *b_fcus, t_tree *tree); void Optimize_Global_Rate(t_tree *tree); phydbl Br_Len_Brent_Default(t_edge *b_fcus, t_tree *tree); void EM_Dist(t_mod *mod, calign *data); phydbl Dist_F_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max, phydbl *param, phydbl *F, t_mod *mod); int Dist_F_Brak(phydbl *ax, phydbl *bx, phydbl *cx, phydbl *F, phydbl *param, t_mod *mod); void Opt_Dist_F(phydbl *dist, phydbl *F, t_mod *mod); phydbl Missing_Dist_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, int n_iter_max, int x, int y, matrix *mat); int Missing_Dist_Brak(phydbl *ax, phydbl *bx, phydbl *cx, int x, int y, matrix *mat); void Opt_Missing_Dist(int x, int y, matrix *mat); int Optimiz_Alpha_And_Pinv(t_tree *tree, int verbose); phydbl Node_Time_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, t_node *anc, t_node *des, t_tree *tree, int n_iter_max); phydbl Time_Stamps_Mult_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, t_tree *tree, int n_iter_max); phydbl Branch_Rate_Shape_Brent(phydbl ax, phydbl bx, phydbl cx, phydbl tol, phydbl *xmin, t_tree *tree, int n_iter_max); phydbl Node_Time_Brent_Fixed_Br_Len(phydbl ax, phydbl bx, phydbl cx, phydbl tol, t_node *n, t_tree *tree, int n_iter_max); phydbl Generic_Brent_Lk(phydbl *param, phydbl ax, phydbl cx, phydbl tol, int n_iter_max, int quickdirty, phydbl (*obj_func)(t_edge *,t_tree *,supert_tree *), t_edge *branch, t_tree *tree, supert_tree *stree, int logt); void Round_Optimize_Node_Heights(t_tree *tree); void Opt_Node_Heights_Recurr_Pre(t_node *a, t_node *d, t_tree *tree); void Opt_Node_Heights_Recurr(t_tree *tree); int Lnsrch(t_tree *tree, int n, phydbl *xold, phydbl fold, phydbl *g, phydbl *p, phydbl *x, phydbl *f, phydbl stpmax, int *check, int logt, int is_positive); int Lnsrch_Nonaligned(t_tree *tree, int n, phydbl **xold, phydbl fold, phydbl *g, phydbl *p, phydbl *x, phydbl *f, phydbl stpmax, int *check, int logt, int is_positive); void Optimize_RR_Params(t_tree *mixt_tree, int verbose); void Optimize_TsTv(t_tree *mixt_tree, int verbose); void Optimize_Lambda(t_tree *mixt_tree, int verbose); void Optimize_Alpha(t_tree *mixt_tree, int verbose); void Optimize_Pinv(t_tree *mixt_tree, int verbose); void Optimize_State_Freqs(t_tree *mixt_tree, int verbose); void Optimize_Rmat_Weights(t_tree *mixt_tree, int verbose); void Optimize_Efrq_Weights(t_tree *mixt_tree, int verbose); void Optimize_Free_Rate(t_tree *mixt_tree, int verbose); void Optimize_Free_Rate_Weights(t_tree *tree, int fast, int verbose); void Optimize_Free_Rate_Rr(t_tree *tree, int fast, int verbose); void Optimize_Br_Len_Multiplier(t_tree *tree, int verbose); #endif phyml-3.2.0/src/pars.c000066400000000000000000001042021263450375500145560ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "pars.h" /*********************************************************/ int Pars(t_edge *b, t_tree *tree) { int site,n_patterns; n_patterns = tree->n_pattern; if(!b) { Post_Order_Pars(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); if(tree->both_sides == YES) Pre_Order_Pars(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); } if(!b) b = tree->a_nodes[0]->b[0]; tree->c_pars = 0; For(site,n_patterns) { tree->site_pars[site] = 0; tree->curr_site = site; tree->site_pars[site] = Pars_Core(b,tree); tree->c_pars += tree->site_pars[site] * tree->data->wght[site]; /* printf("\n. site %d pars: %d",site,tree->c_pars); */ } if(tree->is_mixt_tree) { MIXT_Pars(b,tree); } return tree->c_pars; } /*********************************************************/ void Post_Order_Pars(t_node *a, t_node *d, t_tree *tree) { int i,dir; dir = -1; if(d->tax) return; else { For(i,3) { if(d->v[i] != a) Post_Order_Pars(d,d->v[i],tree); else dir = i; } Get_All_Partial_Pars(tree,d->b[dir],a,d); } } /*********************************************************/ void Pre_Order_Pars(t_node *a, t_node *d, t_tree *tree) { int i; if(d->tax) return; else { For(i,3) { if(d->v[i] != a) { Get_All_Partial_Pars(tree,d->b[i],d->v[i],d); Pre_Order_Pars(d,d->v[i],tree); } } } } /*********************************************************/ void Get_All_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d) { Update_P_Pars(tree,b_fcus,d); } /*********************************************************/ void Site_Pars(t_tree *tree) { tree->site_pars[tree->curr_site] = Pars_Core(tree->a_nodes[0]->b[0],tree); } /*********************************************************/ void Init_P_Pars_Tips(t_tree *tree) { int curr_site,i,j; short int *state_v; int dim1; dim1 = tree->mod->ns; state_v = (short int *)mCalloc(tree->mod->ns,sizeof(short int)); For(curr_site,tree->data->crunch_len) { For(i,tree->n_otu) { if(tree->a_nodes[i]->b[0]->rght->tax != 1) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(tree->io->datatype == NT) { Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site], 0, state_v); For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS; For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = 0; } else if(tree->io->datatype == AA) { Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site], 0, state_v); For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS; For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = 0; } else if(tree->io->datatype == GENERIC) { Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len, tree->mod->ns, tree->mod->io->state_len, 0, state_v); For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = MAX_PARS; For(j,tree->mod->ns) if(state_v[j] > 0.5) tree->a_nodes[i]->b[0]->p_pars_r[curr_site*dim1+j] = 0; } } } Free(state_v); } /*********************************************************/ void Init_Ui_Tips(t_tree *tree) { int curr_site,i,j,br; short int *state_v; state_v = (short int *)mCalloc(tree->mod->ns,sizeof(short int)); For(curr_site,tree->data->crunch_len) { For(i,tree->n_otu) { if(tree->io->datatype == NT) { if(tree->a_nodes[i]->b[0]->rght->tax != 1) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } Init_Tips_At_One_Site_Nucleotides_Int(tree->a_nodes[i]->c_seq->state[curr_site], 0, state_v); /* Init_Tips_At_One_Site_Nucleotides_Int(tree->data->c_seq[i]->state[curr_site], */ /* 0, */ /* state_v); */ tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0; For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j)); } else if(tree->io->datatype == AA) { Init_Tips_At_One_Site_AA_Int(tree->a_nodes[i]->c_seq->state[curr_site], 0, state_v); /* Init_Tips_At_One_Site_AA_Int(tree->data->c_seq[i]->state[curr_site], */ /* 0, */ /* state_v); */ tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0; For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j)); } else if(tree->io->datatype == GENERIC) { Init_Tips_At_One_Site_Generic_Int(tree->a_nodes[i]->c_seq->state+curr_site*tree->mod->io->state_len, tree->mod->ns, tree->mod->io->state_len, 0, state_v); /* Init_Tips_At_One_Site_Generic_Int(tree->data->c_seq[i]->state+curr_site*tree->mod->io->state_len, */ /* tree->mod->ns, */ /* tree->mod->io->state_len, */ /* 0, */ /* state_v); */ tree->a_nodes[i]->b[0]->ui_r[curr_site] = 0; For(j,tree->mod->ns) tree->a_nodes[i]->b[0]->ui_r[curr_site] += (unsigned int)(state_v[j] * POW(2,j)); } } } For(br,2*tree->n_otu-3) { For(curr_site,tree->data->crunch_len) { tree->a_edges[br]->pars_r[curr_site] = 0; tree->a_edges[br]->pars_l[curr_site] = 0; } } Free(state_v); } /*********************************************************/ void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n) { /* | |<- b_fcus | n / \ / \ / \ */ int i,j; int site; unsigned int *ui, *ui_v1, *ui_v2; int *p_pars_v1, *p_pars_v2, *p_pars; int *pars, *pars_v1, *pars_v2; int n_patterns; int min_v1,min_v2; int v; int dim1; if((tree->io->do_alias_subpatt == YES) && (tree->update_alias_subpatt == YES)) Alias_One_Subpatt((n==b_fcus->left)?(b_fcus->rght):(b_fcus->left),n,tree); if(n->tax) return; dim1 = tree->mod->ns; ui = ui_v1 = ui_v2 = NULL; p_pars = p_pars_v1 = p_pars_v2 = NULL; pars = pars_v1 = pars_v2 = NULL; n_patterns = tree->n_pattern; if(n == b_fcus->left) { ui = b_fcus->ui_l; pars = b_fcus->pars_l; p_pars = b_fcus->p_pars_l; ui_v1 = (n == n->b[b_fcus->l_v1]->left)? (n->b[b_fcus->l_v1]->ui_r): (n->b[b_fcus->l_v1]->ui_l); ui_v2 = (n == n->b[b_fcus->l_v2]->left)? (n->b[b_fcus->l_v2]->ui_r): (n->b[b_fcus->l_v2]->ui_l); p_pars_v1 = (n == n->b[b_fcus->l_v1]->left)? (n->b[b_fcus->l_v1]->p_pars_r): (n->b[b_fcus->l_v1]->p_pars_l); p_pars_v2 = (n == n->b[b_fcus->l_v2]->left)? (n->b[b_fcus->l_v2]->p_pars_r): (n->b[b_fcus->l_v2]->p_pars_l); pars_v1 = (n == n->b[b_fcus->l_v1]->left)? (n->b[b_fcus->l_v1]->pars_r): (n->b[b_fcus->l_v1]->pars_l); pars_v2 = (n == n->b[b_fcus->l_v2]->left)? (n->b[b_fcus->l_v2]->pars_r): (n->b[b_fcus->l_v2]->pars_l); } else { ui = b_fcus->ui_r; pars = b_fcus->pars_r; p_pars = b_fcus->p_pars_r; ui_v1 = (n == n->b[b_fcus->r_v1]->left)? (n->b[b_fcus->r_v1]->ui_r): (n->b[b_fcus->r_v1]->ui_l); ui_v2 = (n == n->b[b_fcus->r_v2]->left)? (n->b[b_fcus->r_v2]->ui_r): (n->b[b_fcus->r_v2]->ui_l); p_pars_v1 = (n == n->b[b_fcus->r_v1]->left)? (n->b[b_fcus->r_v1]->p_pars_r): (n->b[b_fcus->r_v1]->p_pars_l); p_pars_v2 = (n == n->b[b_fcus->r_v2]->left)? (n->b[b_fcus->r_v2]->p_pars_r): (n->b[b_fcus->r_v2]->p_pars_l); pars_v1 = (n == n->b[b_fcus->r_v1]->left)? (n->b[b_fcus->r_v1]->pars_r): (n->b[b_fcus->r_v1]->pars_l); pars_v2 = (n == n->b[b_fcus->r_v2]->left)? (n->b[b_fcus->r_v2]->pars_r): (n->b[b_fcus->r_v2]->pars_l); } if(tree->mod->s_opt->general_pars) { For(site,n_patterns) { For(i,tree->mod->ns) { min_v1 = MAX_PARS; For(j,tree->mod->ns) { v = p_pars_v1[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j]; if(v < min_v1) min_v1 = v; } min_v2 = MAX_PARS; For(j,tree->mod->ns) { v = p_pars_v2[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j]; if(v < min_v2) min_v2 = v; } p_pars[site*dim1+i] = min_v1 + min_v2; } } } else { For(site,n_patterns) { pars[site] = pars_v1[site] + pars_v2[site]; ui[site] = ui_v1[site] & ui_v2[site]; if(!ui[site]) { pars[site]++; ui[site] = ui_v1[site] | ui_v2[site]; } } } } /*********************************************************/ int Pars_Core(t_edge *b, t_tree *tree) { int site; int i,j; int site_pars; int min_l,min_r; int v; int dim1; dim1 = tree->mod->ns; site = tree->curr_site; site_pars = MAX_PARS; if(tree->mod->s_opt->general_pars) { For(i,tree->mod->ns) { min_l = MAX_PARS; For(j,tree->mod->ns) { v = b->p_pars_l[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j]; if(v < min_l) min_l = v; } min_r = MAX_PARS; For(j,tree->mod->ns) { v = b->p_pars_r[site*dim1+j] + tree->step_mat[i*tree->mod->ns+j]; if(v < min_r) min_r = v; } if((min_l + min_r) < site_pars) site_pars = min_l + min_r; } } else { site_pars = b->pars_l[site] + b->pars_r[site]; if(!(b->ui_l[site] & b->ui_r[site])) site_pars++; } return site_pars; } /*********************************************************/ /* Is there one or more parsimoniy step(s) along this t_edge ? 0 -> NO; 1 -> YES */ int One_Pars_Step(t_edge *b,t_tree *tree) { int site; int init_general_pars; init_general_pars = tree->mod->s_opt->general_pars; tree->mod->s_opt->general_pars = 0; Set_Both_Sides(YES,tree); Pars(NULL,tree); For(site,tree->n_pattern) { if(!(b->ui_l[site] & b->ui_r[site])) break; } tree->mod->s_opt->general_pars = init_general_pars; if(site == tree->n_pattern) return 0; else { PhyML_Printf("\n. One parsimony step ocurred at site %4d",site); return 1; } } /*********************************************************/ int Pars_At_Given_Edge(t_edge *b, t_tree *tree) { int site,n_patterns; /* n_patterns = (int)FLOOR(tree->n_pattern*tree->prop_of_sites_to_consider); */ n_patterns = tree->n_pattern; tree->c_pars = .0; For(site,n_patterns) { tree->site_pars[site] = 0; tree->curr_site = site; tree->site_pars[site] = Pars_Core(b,tree); tree->c_pars += tree->site_pars[site] * tree->data->wght[site]; } return tree->c_pars; } /*********************************************************/ int Update_Pars_At_Given_Edge(t_edge *b_fcus, t_tree *tree) { Update_P_Pars(tree,b_fcus,b_fcus->left); Update_P_Pars(tree,b_fcus,b_fcus->rght); tree->c_pars = Pars(b_fcus,tree); return tree->c_pars; } /*********************************************************/ void Get_Step_Mat(t_tree *tree) { int i; if(tree->io->datatype == AA) { tree->step_mat[ 0*tree->mod->ns+ 0] = 0 ; tree->step_mat[ 0*tree->mod->ns+ 1] = 3 ; tree->step_mat[ 0*tree->mod->ns+ 2] = 3 ; tree->step_mat[ 0*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 0*tree->mod->ns+ 4] = 3 ; tree->step_mat[ 0*tree->mod->ns+ 5] = 3 ; tree->step_mat[ 0*tree->mod->ns+ 6] = 2 ; tree->step_mat[ 0*tree->mod->ns+ 7] = 2 ; tree->step_mat[ 0*tree->mod->ns+ 8] = 3 ; tree->step_mat[ 0*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 0*tree->mod->ns+10] = 3 ; tree->step_mat[ 0*tree->mod->ns+11] = 3 ; tree->step_mat[ 0*tree->mod->ns+12] = 3 ; tree->step_mat[ 0*tree->mod->ns+13] = 3 ; tree->step_mat[ 0*tree->mod->ns+14] = 2 ; tree->step_mat[ 0*tree->mod->ns+15] = 2 ; tree->step_mat[ 0*tree->mod->ns+16] = 2 ; tree->step_mat[ 0*tree->mod->ns+17] = 3 ; tree->step_mat[ 0*tree->mod->ns+18] = 3 ; tree->step_mat[ 0*tree->mod->ns+19] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 1*tree->mod->ns+ 1] = 0 ; tree->step_mat[ 1*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 3] = 3 ; tree->step_mat[ 1*tree->mod->ns+ 4] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 5] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 6] = 3 ; tree->step_mat[ 1*tree->mod->ns+ 7] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 8] = 2 ; tree->step_mat[ 1*tree->mod->ns+ 9] = 2 ; tree->step_mat[ 1*tree->mod->ns+10] = 2 ; tree->step_mat[ 1*tree->mod->ns+11] = 2 ; tree->step_mat[ 1*tree->mod->ns+12] = 2 ; tree->step_mat[ 1*tree->mod->ns+13] = 3 ; tree->step_mat[ 1*tree->mod->ns+14] = 2 ; tree->step_mat[ 1*tree->mod->ns+15] = 2 ; tree->step_mat[ 1*tree->mod->ns+16] = 2 ; tree->step_mat[ 1*tree->mod->ns+17] = 2 ; tree->step_mat[ 1*tree->mod->ns+18] = 3 ; tree->step_mat[ 1*tree->mod->ns+19] = 3 ; tree->step_mat[ 2*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 2*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 2] = 0 ; tree->step_mat[ 2*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 4] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 5] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 6] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 7] = 3 ; tree->step_mat[ 2*tree->mod->ns+ 8] = 2 ; tree->step_mat[ 2*tree->mod->ns+ 9] = 2 ; tree->step_mat[ 2*tree->mod->ns+10] = 3 ; tree->step_mat[ 2*tree->mod->ns+11] = 1 ; tree->step_mat[ 2*tree->mod->ns+12] = 2 ; tree->step_mat[ 2*tree->mod->ns+13] = 2 ; tree->step_mat[ 2*tree->mod->ns+14] = 3 ; tree->step_mat[ 2*tree->mod->ns+15] = 2 ; tree->step_mat[ 2*tree->mod->ns+16] = 2 ; tree->step_mat[ 2*tree->mod->ns+17] = 3 ; tree->step_mat[ 2*tree->mod->ns+18] = 2 ; tree->step_mat[ 2*tree->mod->ns+19] = 3 ; tree->step_mat[ 3*tree->mod->ns+ 0] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 1] = 3 ; tree->step_mat[ 3*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 3] = 0 ; tree->step_mat[ 3*tree->mod->ns+ 4] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 5] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 6] = 1 ; tree->step_mat[ 3*tree->mod->ns+ 7] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 8] = 2 ; tree->step_mat[ 3*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 3*tree->mod->ns+10] = 3 ; tree->step_mat[ 3*tree->mod->ns+11] = 2 ; tree->step_mat[ 3*tree->mod->ns+12] = 3 ; tree->step_mat[ 3*tree->mod->ns+13] = 2 ; tree->step_mat[ 3*tree->mod->ns+14] = 3 ; tree->step_mat[ 3*tree->mod->ns+15] = 3 ; tree->step_mat[ 3*tree->mod->ns+16] = 3 ; tree->step_mat[ 3*tree->mod->ns+17] = 3 ; tree->step_mat[ 3*tree->mod->ns+18] = 2 ; tree->step_mat[ 3*tree->mod->ns+19] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 4*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 4] = 0 ; tree->step_mat[ 4*tree->mod->ns+ 5] = 3 ; tree->step_mat[ 4*tree->mod->ns+ 6] = 3 ; tree->step_mat[ 4*tree->mod->ns+ 7] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 8] = 2 ; tree->step_mat[ 4*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 4*tree->mod->ns+10] = 2 ; tree->step_mat[ 4*tree->mod->ns+11] = 3 ; tree->step_mat[ 4*tree->mod->ns+12] = 3 ; tree->step_mat[ 4*tree->mod->ns+13] = 2 ; tree->step_mat[ 4*tree->mod->ns+14] = 3 ; tree->step_mat[ 4*tree->mod->ns+15] = 2 ; tree->step_mat[ 4*tree->mod->ns+16] = 3 ; tree->step_mat[ 4*tree->mod->ns+17] = 1 ; tree->step_mat[ 4*tree->mod->ns+18] = 2 ; tree->step_mat[ 4*tree->mod->ns+19] = 3 ; tree->step_mat[ 5*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 5*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 5*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 5*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 5*tree->mod->ns+ 4] = 3 ; tree->step_mat[ 5*tree->mod->ns+ 5] = 0 ; tree->step_mat[ 5*tree->mod->ns+ 6] = 2 ; tree->step_mat[ 5*tree->mod->ns+ 7] = 3 ; tree->step_mat[ 5*tree->mod->ns+ 8] = 1 ; tree->step_mat[ 5*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 5*tree->mod->ns+10] = 2 ; tree->step_mat[ 5*tree->mod->ns+11] = 2 ; tree->step_mat[ 5*tree->mod->ns+12] = 2 ; tree->step_mat[ 5*tree->mod->ns+13] = 3 ; tree->step_mat[ 5*tree->mod->ns+14] = 2 ; tree->step_mat[ 5*tree->mod->ns+15] = 3 ; tree->step_mat[ 5*tree->mod->ns+16] = 3 ; tree->step_mat[ 5*tree->mod->ns+17] = 2 ; tree->step_mat[ 5*tree->mod->ns+18] = 2 ; tree->step_mat[ 5*tree->mod->ns+19] = 3 ; tree->step_mat[ 6*tree->mod->ns+ 0] = 2 ; tree->step_mat[ 6*tree->mod->ns+ 1] = 3 ; tree->step_mat[ 6*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 6*tree->mod->ns+ 3] = 1 ; tree->step_mat[ 6*tree->mod->ns+ 4] = 3 ; tree->step_mat[ 6*tree->mod->ns+ 5] = 2 ; tree->step_mat[ 6*tree->mod->ns+ 6] = 0 ; tree->step_mat[ 6*tree->mod->ns+ 7] = 2 ; tree->step_mat[ 6*tree->mod->ns+ 8] = 2 ; tree->step_mat[ 6*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 6*tree->mod->ns+10] = 3 ; tree->step_mat[ 6*tree->mod->ns+11] = 2 ; tree->step_mat[ 6*tree->mod->ns+12] = 2 ; tree->step_mat[ 6*tree->mod->ns+13] = 3 ; tree->step_mat[ 6*tree->mod->ns+14] = 3 ; tree->step_mat[ 6*tree->mod->ns+15] = 3 ; tree->step_mat[ 6*tree->mod->ns+16] = 3 ; tree->step_mat[ 6*tree->mod->ns+17] = 2 ; tree->step_mat[ 6*tree->mod->ns+18] = 2 ; tree->step_mat[ 6*tree->mod->ns+19] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 0] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 2] = 3 ; tree->step_mat[ 7*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 4] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 5] = 3 ; tree->step_mat[ 7*tree->mod->ns+ 6] = 2 ; tree->step_mat[ 7*tree->mod->ns+ 7] = 0 ; tree->step_mat[ 7*tree->mod->ns+ 8] = 3 ; tree->step_mat[ 7*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 7*tree->mod->ns+10] = 3 ; tree->step_mat[ 7*tree->mod->ns+11] = 3 ; tree->step_mat[ 7*tree->mod->ns+12] = 3 ; tree->step_mat[ 7*tree->mod->ns+13] = 3 ; tree->step_mat[ 7*tree->mod->ns+14] = 3 ; tree->step_mat[ 7*tree->mod->ns+15] = 2 ; tree->step_mat[ 7*tree->mod->ns+16] = 3 ; tree->step_mat[ 7*tree->mod->ns+17] = 2 ; tree->step_mat[ 7*tree->mod->ns+18] = 3 ; tree->step_mat[ 7*tree->mod->ns+19] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 8*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 3] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 4] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 5] = 1 ; tree->step_mat[ 8*tree->mod->ns+ 6] = 2 ; tree->step_mat[ 8*tree->mod->ns+ 7] = 3 ; tree->step_mat[ 8*tree->mod->ns+ 8] = 0 ; tree->step_mat[ 8*tree->mod->ns+ 9] = 3 ; tree->step_mat[ 8*tree->mod->ns+10] = 2 ; tree->step_mat[ 8*tree->mod->ns+11] = 2 ; tree->step_mat[ 8*tree->mod->ns+12] = 3 ; tree->step_mat[ 8*tree->mod->ns+13] = 2 ; tree->step_mat[ 8*tree->mod->ns+14] = 2 ; tree->step_mat[ 8*tree->mod->ns+15] = 3 ; tree->step_mat[ 8*tree->mod->ns+16] = 3 ; tree->step_mat[ 8*tree->mod->ns+17] = 3 ; tree->step_mat[ 8*tree->mod->ns+18] = 2 ; tree->step_mat[ 8*tree->mod->ns+19] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 0] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 1] = 2 ; tree->step_mat[ 9*tree->mod->ns+ 2] = 2 ; tree->step_mat[ 9*tree->mod->ns+ 3] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 4] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 5] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 6] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 7] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 8] = 3 ; tree->step_mat[ 9*tree->mod->ns+ 9] = 0 ; tree->step_mat[ 9*tree->mod->ns+10] = 2 ; tree->step_mat[ 9*tree->mod->ns+11] = 2 ; tree->step_mat[ 9*tree->mod->ns+12] = 1 ; tree->step_mat[ 9*tree->mod->ns+13] = 2 ; tree->step_mat[ 9*tree->mod->ns+14] = 3 ; tree->step_mat[ 9*tree->mod->ns+15] = 2 ; tree->step_mat[ 9*tree->mod->ns+16] = 2 ; tree->step_mat[ 9*tree->mod->ns+17] = 3 ; tree->step_mat[ 9*tree->mod->ns+18] = 3 ; tree->step_mat[ 9*tree->mod->ns+19] = 2 ; tree->step_mat[10*tree->mod->ns+ 0] = 3 ; tree->step_mat[10*tree->mod->ns+ 1] = 2 ; tree->step_mat[10*tree->mod->ns+ 2] = 3 ; tree->step_mat[10*tree->mod->ns+ 3] = 3 ; tree->step_mat[10*tree->mod->ns+ 4] = 2 ; tree->step_mat[10*tree->mod->ns+ 5] = 2 ; tree->step_mat[10*tree->mod->ns+ 6] = 3 ; tree->step_mat[10*tree->mod->ns+ 7] = 3 ; tree->step_mat[10*tree->mod->ns+ 8] = 2 ; tree->step_mat[10*tree->mod->ns+ 9] = 2 ; tree->step_mat[10*tree->mod->ns+10] = 0 ; tree->step_mat[10*tree->mod->ns+11] = 3 ; tree->step_mat[10*tree->mod->ns+12] = 2 ; tree->step_mat[10*tree->mod->ns+13] = 2 ; tree->step_mat[10*tree->mod->ns+14] = 2 ; tree->step_mat[10*tree->mod->ns+15] = 3 ; tree->step_mat[10*tree->mod->ns+16] = 3 ; tree->step_mat[10*tree->mod->ns+17] = 2 ; tree->step_mat[10*tree->mod->ns+18] = 2 ; tree->step_mat[10*tree->mod->ns+19] = 2 ; tree->step_mat[11*tree->mod->ns+ 0] = 3 ; tree->step_mat[11*tree->mod->ns+ 1] = 2 ; tree->step_mat[11*tree->mod->ns+ 2] = 1 ; tree->step_mat[11*tree->mod->ns+ 3] = 2 ; tree->step_mat[11*tree->mod->ns+ 4] = 3 ; tree->step_mat[11*tree->mod->ns+ 5] = 2 ; tree->step_mat[11*tree->mod->ns+ 6] = 2 ; tree->step_mat[11*tree->mod->ns+ 7] = 3 ; tree->step_mat[11*tree->mod->ns+ 8] = 2 ; tree->step_mat[11*tree->mod->ns+ 9] = 2 ; tree->step_mat[11*tree->mod->ns+10] = 3 ; tree->step_mat[11*tree->mod->ns+11] = 0 ; tree->step_mat[11*tree->mod->ns+12] = 2 ; tree->step_mat[11*tree->mod->ns+13] = 3 ; tree->step_mat[11*tree->mod->ns+14] = 3 ; tree->step_mat[11*tree->mod->ns+15] = 2 ; tree->step_mat[11*tree->mod->ns+16] = 2 ; tree->step_mat[11*tree->mod->ns+17] = 2 ; tree->step_mat[11*tree->mod->ns+18] = 2 ; tree->step_mat[11*tree->mod->ns+19] = 3 ; tree->step_mat[12*tree->mod->ns+ 0] = 3 ; tree->step_mat[12*tree->mod->ns+ 1] = 2 ; tree->step_mat[12*tree->mod->ns+ 2] = 2 ; tree->step_mat[12*tree->mod->ns+ 3] = 3 ; tree->step_mat[12*tree->mod->ns+ 4] = 3 ; tree->step_mat[12*tree->mod->ns+ 5] = 2 ; tree->step_mat[12*tree->mod->ns+ 6] = 2 ; tree->step_mat[12*tree->mod->ns+ 7] = 3 ; tree->step_mat[12*tree->mod->ns+ 8] = 3 ; tree->step_mat[12*tree->mod->ns+ 9] = 1 ; tree->step_mat[12*tree->mod->ns+10] = 2 ; tree->step_mat[12*tree->mod->ns+11] = 2 ; tree->step_mat[12*tree->mod->ns+12] = 0 ; tree->step_mat[12*tree->mod->ns+13] = 2 ; tree->step_mat[12*tree->mod->ns+14] = 3 ; tree->step_mat[12*tree->mod->ns+15] = 2 ; tree->step_mat[12*tree->mod->ns+16] = 2 ; tree->step_mat[12*tree->mod->ns+17] = 2 ; tree->step_mat[12*tree->mod->ns+18] = 3 ; tree->step_mat[12*tree->mod->ns+19] = 2 ; tree->step_mat[13*tree->mod->ns+ 0] = 3 ; tree->step_mat[13*tree->mod->ns+ 1] = 3 ; tree->step_mat[13*tree->mod->ns+ 2] = 2 ; tree->step_mat[13*tree->mod->ns+ 3] = 2 ; tree->step_mat[13*tree->mod->ns+ 4] = 2 ; tree->step_mat[13*tree->mod->ns+ 5] = 3 ; tree->step_mat[13*tree->mod->ns+ 6] = 3 ; tree->step_mat[13*tree->mod->ns+ 7] = 3 ; tree->step_mat[13*tree->mod->ns+ 8] = 2 ; tree->step_mat[13*tree->mod->ns+ 9] = 2 ; tree->step_mat[13*tree->mod->ns+10] = 2 ; tree->step_mat[13*tree->mod->ns+11] = 3 ; tree->step_mat[13*tree->mod->ns+12] = 2 ; tree->step_mat[13*tree->mod->ns+13] = 0 ; tree->step_mat[13*tree->mod->ns+14] = 3 ; tree->step_mat[13*tree->mod->ns+15] = 2 ; tree->step_mat[13*tree->mod->ns+16] = 3 ; tree->step_mat[13*tree->mod->ns+17] = 2 ; tree->step_mat[13*tree->mod->ns+18] = 2 ; tree->step_mat[13*tree->mod->ns+19] = 2 ; tree->step_mat[14*tree->mod->ns+ 0] = 2 ; tree->step_mat[14*tree->mod->ns+ 1] = 2 ; tree->step_mat[14*tree->mod->ns+ 2] = 3 ; tree->step_mat[14*tree->mod->ns+ 3] = 3 ; tree->step_mat[14*tree->mod->ns+ 4] = 3 ; tree->step_mat[14*tree->mod->ns+ 5] = 2 ; tree->step_mat[14*tree->mod->ns+ 6] = 3 ; tree->step_mat[14*tree->mod->ns+ 7] = 3 ; tree->step_mat[14*tree->mod->ns+ 8] = 2 ; tree->step_mat[14*tree->mod->ns+ 9] = 3 ; tree->step_mat[14*tree->mod->ns+10] = 2 ; tree->step_mat[14*tree->mod->ns+11] = 3 ; tree->step_mat[14*tree->mod->ns+12] = 3 ; tree->step_mat[14*tree->mod->ns+13] = 3 ; tree->step_mat[14*tree->mod->ns+14] = 0 ; tree->step_mat[14*tree->mod->ns+15] = 2 ; tree->step_mat[14*tree->mod->ns+16] = 2 ; tree->step_mat[14*tree->mod->ns+17] = 3 ; tree->step_mat[14*tree->mod->ns+18] = 3 ; tree->step_mat[14*tree->mod->ns+19] = 3 ; tree->step_mat[15*tree->mod->ns+ 0] = 2 ; tree->step_mat[15*tree->mod->ns+ 1] = 2 ; tree->step_mat[15*tree->mod->ns+ 2] = 2 ; tree->step_mat[15*tree->mod->ns+ 3] = 3 ; tree->step_mat[15*tree->mod->ns+ 4] = 2 ; tree->step_mat[15*tree->mod->ns+ 5] = 3 ; tree->step_mat[15*tree->mod->ns+ 6] = 3 ; tree->step_mat[15*tree->mod->ns+ 7] = 2 ; tree->step_mat[15*tree->mod->ns+ 8] = 3 ; tree->step_mat[15*tree->mod->ns+ 9] = 2 ; tree->step_mat[15*tree->mod->ns+10] = 3 ; tree->step_mat[15*tree->mod->ns+11] = 2 ; tree->step_mat[15*tree->mod->ns+12] = 2 ; tree->step_mat[15*tree->mod->ns+13] = 2 ; tree->step_mat[15*tree->mod->ns+14] = 2 ; tree->step_mat[15*tree->mod->ns+15] = 0 ; tree->step_mat[15*tree->mod->ns+16] = 2 ; tree->step_mat[15*tree->mod->ns+17] = 2 ; tree->step_mat[15*tree->mod->ns+18] = 2 ; tree->step_mat[15*tree->mod->ns+19] = 3 ; tree->step_mat[16*tree->mod->ns+ 0] = 2 ; tree->step_mat[16*tree->mod->ns+ 1] = 2 ; tree->step_mat[16*tree->mod->ns+ 2] = 2 ; tree->step_mat[16*tree->mod->ns+ 3] = 3 ; tree->step_mat[16*tree->mod->ns+ 4] = 3 ; tree->step_mat[16*tree->mod->ns+ 5] = 3 ; tree->step_mat[16*tree->mod->ns+ 6] = 3 ; tree->step_mat[16*tree->mod->ns+ 7] = 3 ; tree->step_mat[16*tree->mod->ns+ 8] = 3 ; tree->step_mat[16*tree->mod->ns+ 9] = 2 ; tree->step_mat[16*tree->mod->ns+10] = 3 ; tree->step_mat[16*tree->mod->ns+11] = 2 ; tree->step_mat[16*tree->mod->ns+12] = 2 ; tree->step_mat[16*tree->mod->ns+13] = 3 ; tree->step_mat[16*tree->mod->ns+14] = 2 ; tree->step_mat[16*tree->mod->ns+15] = 2 ; tree->step_mat[16*tree->mod->ns+16] = 0 ; tree->step_mat[16*tree->mod->ns+17] = 3 ; tree->step_mat[16*tree->mod->ns+18] = 3 ; tree->step_mat[16*tree->mod->ns+19] = 3 ; tree->step_mat[17*tree->mod->ns+ 0] = 3 ; tree->step_mat[17*tree->mod->ns+ 1] = 2 ; tree->step_mat[17*tree->mod->ns+ 2] = 3 ; tree->step_mat[17*tree->mod->ns+ 3] = 3 ; tree->step_mat[17*tree->mod->ns+ 4] = 1 ; tree->step_mat[17*tree->mod->ns+ 5] = 2 ; tree->step_mat[17*tree->mod->ns+ 6] = 2 ; tree->step_mat[17*tree->mod->ns+ 7] = 2 ; tree->step_mat[17*tree->mod->ns+ 8] = 3 ; tree->step_mat[17*tree->mod->ns+ 9] = 3 ; tree->step_mat[17*tree->mod->ns+10] = 2 ; tree->step_mat[17*tree->mod->ns+11] = 2 ; tree->step_mat[17*tree->mod->ns+12] = 2 ; tree->step_mat[17*tree->mod->ns+13] = 2 ; tree->step_mat[17*tree->mod->ns+14] = 3 ; tree->step_mat[17*tree->mod->ns+15] = 2 ; tree->step_mat[17*tree->mod->ns+16] = 3 ; tree->step_mat[17*tree->mod->ns+17] = 0 ; tree->step_mat[17*tree->mod->ns+18] = 2 ; tree->step_mat[17*tree->mod->ns+19] = 3 ; tree->step_mat[18*tree->mod->ns+ 0] = 3 ; tree->step_mat[18*tree->mod->ns+ 1] = 3 ; tree->step_mat[18*tree->mod->ns+ 2] = 2 ; tree->step_mat[18*tree->mod->ns+ 3] = 2 ; tree->step_mat[18*tree->mod->ns+ 4] = 2 ; tree->step_mat[18*tree->mod->ns+ 5] = 2 ; tree->step_mat[18*tree->mod->ns+ 6] = 2 ; tree->step_mat[18*tree->mod->ns+ 7] = 3 ; tree->step_mat[18*tree->mod->ns+ 8] = 2 ; tree->step_mat[18*tree->mod->ns+ 9] = 3 ; tree->step_mat[18*tree->mod->ns+10] = 2 ; tree->step_mat[18*tree->mod->ns+11] = 2 ; tree->step_mat[18*tree->mod->ns+12] = 3 ; tree->step_mat[18*tree->mod->ns+13] = 2 ; tree->step_mat[18*tree->mod->ns+14] = 3 ; tree->step_mat[18*tree->mod->ns+15] = 2 ; tree->step_mat[18*tree->mod->ns+16] = 3 ; tree->step_mat[18*tree->mod->ns+17] = 2 ; tree->step_mat[18*tree->mod->ns+18] = 0 ; tree->step_mat[18*tree->mod->ns+19] = 3 ; tree->step_mat[19*tree->mod->ns+ 0] = 2 ; tree->step_mat[19*tree->mod->ns+ 1] = 3 ; tree->step_mat[19*tree->mod->ns+ 2] = 3 ; tree->step_mat[19*tree->mod->ns+ 3] = 2 ; tree->step_mat[19*tree->mod->ns+ 4] = 3 ; tree->step_mat[19*tree->mod->ns+ 5] = 3 ; tree->step_mat[19*tree->mod->ns+ 6] = 2 ; tree->step_mat[19*tree->mod->ns+ 7] = 2 ; tree->step_mat[19*tree->mod->ns+ 8] = 3 ; tree->step_mat[19*tree->mod->ns+ 9] = 2 ; tree->step_mat[19*tree->mod->ns+10] = 2 ; tree->step_mat[19*tree->mod->ns+11] = 3 ; tree->step_mat[19*tree->mod->ns+12] = 2 ; tree->step_mat[19*tree->mod->ns+13] = 2 ; tree->step_mat[19*tree->mod->ns+14] = 3 ; tree->step_mat[19*tree->mod->ns+15] = 3 ; tree->step_mat[19*tree->mod->ns+16] = 3 ; tree->step_mat[19*tree->mod->ns+17] = 3 ; tree->step_mat[19*tree->mod->ns+18] = 3 ; tree->step_mat[19*tree->mod->ns+19] = 0 ; } else { tree->step_mat[0*tree->mod->ns+0] = 0; tree->step_mat[0*tree->mod->ns+1] = 2; tree->step_mat[0*tree->mod->ns+2] = 1; tree->step_mat[0*tree->mod->ns+3] = 2; tree->step_mat[1*tree->mod->ns+0] = 2; tree->step_mat[1*tree->mod->ns+1] = 0; tree->step_mat[1*tree->mod->ns+2] = 2; tree->step_mat[1*tree->mod->ns+3] = 1; tree->step_mat[2*tree->mod->ns+0] = 1; tree->step_mat[2*tree->mod->ns+1] = 2; tree->step_mat[2*tree->mod->ns+2] = 0; tree->step_mat[2*tree->mod->ns+3] = 2; tree->step_mat[3*tree->mod->ns+0] = 2; tree->step_mat[3*tree->mod->ns+1] = 1; tree->step_mat[3*tree->mod->ns+2] = 2; tree->step_mat[3*tree->mod->ns+3] = 0; /* tree->step_mat[0*tree->mod->ns+0] = 0; */ /* tree->step_mat[0*tree->mod->ns+1] = 1; */ /* tree->step_mat[0*tree->mod->ns+2] = 1; */ /* tree->step_mat[0*tree->mod->ns+3] = 1; */ /* tree->step_mat[1*tree->mod->ns+0] = 1; */ /* tree->step_mat[1*tree->mod->ns+1] = 0; */ /* tree->step_mat[1*tree->mod->ns+2] = 1; */ /* tree->step_mat[1*tree->mod->ns+3] = 1; */ /* tree->step_mat[2*tree->mod->ns+0] = 1; */ /* tree->step_mat[2*tree->mod->ns+1] = 1; */ /* tree->step_mat[2*tree->mod->ns+2] = 0; */ /* tree->step_mat[2*tree->mod->ns+3] = 1; */ /* tree->step_mat[3*tree->mod->ns+0] = 1; */ /* tree->step_mat[3*tree->mod->ns+1] = 1; */ /* tree->step_mat[3*tree->mod->ns+2] = 1; */ /* tree->step_mat[3*tree->mod->ns+3] = 0; */ } For(i,tree->mod->ns) tree->step_mat[i*tree->mod->ns+i] = 0; } /*********************************************************/ /*********************************************************/ phyml-3.2.0/src/pars.h000066400000000000000000000022001263450375500145560ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef PARS_H #define PARS_H #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "models.h" #include "free.h" int Pars(t_edge *b, t_tree *tree); void Post_Order_Pars(t_node *a, t_node *d, t_tree *tree); void Pre_Order_Pars(t_node *a, t_node *d, t_tree *tree); void Get_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d); void Site_Pars(t_tree *tree); void Init_Ui_Tips(t_tree *tree); void Update_P_Pars(t_tree *tree, t_edge *b_fcus, t_node *n); int Pars_At_Given_Edge(t_edge *b, t_tree *tree); void Get_All_Partial_Pars(t_tree *tree, t_edge *b_fcus, t_node *a, t_node *d); int Update_Pars_At_Given_Edge(t_edge *b_fcus, t_tree *tree); void Init_P_Pars_Tips(t_tree *tree); void Get_Step_Mat(t_tree *tree); int Pars_Core(t_edge *b, t_tree *tree); int One_Pars_Step(t_edge *b,t_tree *tree); #endif phyml-3.2.0/src/phyrex.c000066400000000000000000004161741263450375500151460ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Routines that implement Etheridge and Barton's model of continuous-space coalescent. */ #include "phyrex.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PHYREX_Main(int argc, char *argv[]) { return(PHYREX_Main_Estimate(argc,argv)); /* return(PHYREX_Main_Simulate(argc,argv)); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PHYREX_Main_Estimate(int argc, char *argv[]) { t_tree *tree; phydbl *res; int n_dim,i; t_dsk *disk; option *io; calign *cdata; t_ldsk **ldsk_a; n_dim = 2; io = (option *)Get_Input(argc,argv); assert(io); Get_Seq(io); assert(io->data); Make_Model_Complete(io->mod); Set_Model_Name(io->mod); Print_Settings(io); cdata = Compact_Data(io->data,io); Free_Seq(io->data,cdata->n_otu); tree = Make_Tree_From_Scratch(cdata->n_otu,cdata); Connect_CSeqs_To_Nodes(cdata,io,tree); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,io->rates,tree->n_otu); /* Allocate migrep model */ tree->mmod = PHYREX_Make_Migrep_Model(n_dim); PHYREX_Init_Migrep_Mod(tree->mmod,n_dim,10.0,10.0); tree->data = cdata; tree->mod = io->mod; tree->io = io; tree->n_pattern = tree->data->crunch_len; /* Allocate and initialise first disk event */ disk = PHYREX_Make_Disk_Event(n_dim,tree->n_otu); PHYREX_Init_Disk_Event(disk,n_dim,NULL); disk->time = 0.0; disk->mmod = tree->mmod; disk->n_ldsk_a = tree->n_otu; tree->disk = disk; /* Allocate coordinates for all the tips first (will grow afterwards) */ ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *)); For(i,tree->n_otu) { ldsk_a[i] = PHYREX_Make_Lindisk_Node(n_dim); PHYREX_Init_Lindisk_Node(ldsk_a[i],disk,n_dim); } PHYREX_Read_Tip_Coordinates(ldsk_a,tree); tree->disk->ldsk_a = ldsk_a; /* Initialize parameters of migrep model */ tree->mmod->lbda = Uni()*(0.3 - 0.05) + 0.05; tree->mmod->mu = Uni()*(1.0 - 0.3) + 0.3; tree->mmod->rad = Uni()*(5.0 - 1.5) + 1.5; tree->mmod->sigsq = PHYREX_Update_Sigsq(tree); /* Random genealogy */ PHYREX_Simulate_Backward_Core(NO,tree->disk,tree); PHYREX_Ldsk_To_Tree(tree); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); RATES_Fill_Lca_Table(tree); disk = tree->disk; while(disk->prev) disk = disk->prev; tree->rates->bl_from_rt = YES; tree->rates->clock_r = 0.01 / FABS(disk->time); tree->rates->model = STRICTCLOCK; RATES_Update_Cur_Bl(tree); Init_Model(tree->data,io->mod,io); Prepare_Tree_For_Lk(tree); Init_P_Lk_Tips_Int(tree); Init_P_Lk_Loc(tree); res = PHYREX_MCMC(tree); Free(res); return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int PHYREX_Main_Simulate(int argc, char *argv[]) { t_tree *tree; phydbl *res; int seed,pid,i; char *s; t_dsk *disk; int n_otus, n_sites; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); pid = getpid(); seed = pid; n_otus = (int)atoi(argv[1]); n_sites = (int)atoi(argv[2]); /* !!!!!!!!!!!!! */ /* seed = 9498; */ /* seed = 27351; */ /* seed = 359; */ /* seed = 1; */ /* seed = 10112; */ /* seed = 5818; */ /* seed = 16167; */ /* seed = 18885; */ /* seed = 22776; */ /* seed = 629; */ /* seed = 1; */ /* seed = 14493; */ /* seed = 15364; */ /* seed = 21414; */ /* seed = 13536; */ /* seed = 28366; */ /* seed = 20679; */ /* seed = 23661; */ printf("\n. seed: %d",seed); srand(seed); tree = PHYREX_Simulate((int)atoi(argv[1]),(int)atoi(argv[2]),10.,10.,seed); disk = tree->disk; while(disk->prev) disk = disk->prev; strcpy(s,"phyrex_trees"); sprintf(s+strlen(s),".%d",tree->mod->io->r_seed); tree->io->fp_out_tree = Openfile(s,WRITE); strcpy(s,"phyrex_stats"); sprintf(s+strlen(s),".%d",tree->mod->io->r_seed); tree->io->fp_out_stats = Openfile(s,WRITE); strcpy(s,"phyrex_summary"); sprintf(s+strlen(s),".%d",tree->mod->io->r_seed); tree->io->fp_out_summary = Openfile(s,WRITE); strcpy(s,"phyrex_mtt"); sprintf(s+strlen(s),".%d.xml",tree->mod->io->r_seed); PHYREX_Print_MultiTypeTree_Config_File(n_sites,s,tree); res = PHYREX_MCMC(tree); disk = tree->disk; For(i,disk->n_ldsk_a) Free_Ldisk(disk->ldsk_a[i]); while(disk->prev) { disk = disk->prev; if(disk->next->ldsk != NULL) Free_Ldisk(disk->next->ldsk); Free_Disk(disk->next); } /* Root */ Free_Ldisk(disk->ldsk); Free_Disk(disk); RATES_Free_Rates(tree->rates); MCMC_Free_MCMC(tree->mcmc); Free_Mmod(tree->mmod); Free_Spr_List(tree); Free_Triplet(tree->triplet_struct); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Input(tree->io); Free_Optimiz(tree->mod->s_opt); Free_Model_Complete(tree->mod); Free_Model_Basic(tree->mod); Free_Cseq(tree->data); Free_Tree(tree); Free(res); Free(s); return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Simulate Etheridge-Barton model backwards in time, following n_otu lineages // on a rectangle of dimension width x height // See Kelleher, Barton & Etheridge, Bioinformatics, 2013. t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int r_seed) { t_tree *tree; int n_dim; t_phyrex_mod *mmod; t_dsk *disk; option *io; t_mod *mod; t_opt *s_opt; calign *cdata; /* phydbl max_mu, min_mu; */ /* phydbl max_rad, min_rad; */ /* phydbl min_rate, max_rate; */ /* phydbl min_lbda, max_lbda; */ phydbl min_neigh, max_neigh; /* phydbl min_sigsq, max_sigsq; */ phydbl area, neigh; phydbl T; phydbl Ne,maxNe,minNe; n_dim = 2; // 2-dimensional landscape area = width * height; io = (option *)Make_Input(); mod = (t_mod *)Make_Model_Basic(); s_opt = (t_opt *)Make_Optimiz(); Set_Defaults_Input(io); Set_Defaults_Model(mod); Set_Defaults_Optimiz(s_opt); io->mod = mod; mod->io = io; mod->s_opt = s_opt; io->r_seed = r_seed; io->n_otu = n_otu; io->init_len = 500; /* sequence length */ io->data = Make_Empty_Alignment(io); Make_Model_Complete(io->mod); Set_Model_Name(io->mod); /* Print_Settings(io); */ io->colalias = NO; cdata = Compact_Data(io->data,io); Free_Seq(io->data,io->n_otu); tree = Make_Tree_From_Scratch(n_otu,cdata); Connect_CSeqs_To_Nodes(cdata,io,tree); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,io->rates,tree->n_otu); tree->data = cdata; tree->mod = mod; tree->io = io; tree->n_pattern = tree->data->crunch_len; /* Allocate migrep model */ mmod = PHYREX_Make_Migrep_Model(n_dim); tree->mmod = mmod; PHYREX_Init_Migrep_Mod(mmod,n_dim,width,height); do { /* Effective population size */ minNe = 100.; maxNe = 5000.; Ne = Uni() * (maxNe - minNe) + minNe; /* Neighborhood size */ max_neigh = 0.01*Ne; min_neigh = 0.001*Ne; neigh = Uni()*(max_neigh - min_neigh) + min_neigh; } while(neigh < 2.0); /* Death parameter */ mmod->mu = 2./neigh; /* Theta (radius) */ tree->mmod->rad = Uni()*(4.0 - 1.5) + 1.5; mmod->sigsq = neigh / (4.*PI*Ne/area); tree->mmod->lbda = area * mmod->sigsq / (4.*PI*tree->mmod->mu*POW(tree->mmod->rad,4)); /* mmod->lbda = 0.04; */ /* mmod->mu = 0.16; */ /* mmod->rad = 2.75; */ /* neigh = 2./mmod->mu; */ /* mmod->sigsq = PHYREX_Update_Sigsq(tree); */ PhyML_Printf("\n. lbda: %G mu: %G sigsq: %G rad: %G neigh: %G N: %G rhoe: %G", mmod->lbda, mmod->mu, mmod->sigsq, mmod->rad, neigh, area*neigh/(4*PI*mmod->sigsq), neigh/(4.*PI*mmod->sigsq)); fflush(NULL); /* PHYREX_Simulate_Backward_Core(YES,tree->disk,tree); */ mmod->sampl_area = PHYREX_Simulate_Forward_Core(n_sites,tree); PHYREX_Ldsk_To_Tree(tree); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); RATES_Fill_Lca_Table(tree); /* min_rate = 1.E-5; */ /* max_rate = 1.E-4; */ T = PHYREX_Tree_Height(tree); tree->rates->bl_from_rt = YES; /* tree->rates->clock_r = Uni()*(max_rate - min_rate) + min_rate; */ tree->rates->clock_r = 0.01/FABS(T); tree->rates->model = STRICTCLOCK; RATES_Update_Cur_Bl(tree); Init_Model(cdata,mod,io); tree->mod->ras->n_catg = 1; tree->mod->whichmodel = HKY85; tree->mod->kappa->v = 4.0; Prepare_Tree_For_Lk(tree); Evolve(tree->data,tree->mod,tree); if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(tree); else Init_P_Lk_Tips_Int(tree); Init_P_Lk_Loc(tree); disk = tree->disk->prev; while(disk->prev) disk = disk->prev; printf("\n. XXX %f %d %d %d %f %f %f %f %f %f\n", disk->time, PHYREX_Total_Number_Of_Intervals(tree), PHYREX_Total_Number_Of_Coal_Disks(tree), PHYREX_Total_Number_Of_Hit_Disks(tree), disk->ldsk->coord->lonlat[0], disk->ldsk->coord->lonlat[1], mmod->lbda, mmod->mu, mmod->sigsq, Nucleotide_Diversity(tree->data)); return(tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ // Simulate Etheridge-Barton model backwards in time, following n_otu lineages // on a rectangle of dimension width x height phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree) { t_dsk *disk; t_ldsk *new_ldsk,**ldsk_a,**ldsk_a_tmp; int i,j,n_disk,n_lineages,n_dim,n_hit,n_lineages_new,err; phydbl dt_dsk,curr_t,prob_hit,u; t_phyrex_mod *mmod; phydbl lnL; mmod = tree->mmod; n_dim = tree->mmod->n_dim; if(new_loc == YES) { init_disk = PHYREX_Make_Disk_Event(n_dim,tree->n_otu); PHYREX_Init_Disk_Event(init_disk,n_dim,NULL); init_disk->time = 0.0; init_disk->mmod = mmod; init_disk->centr->lonlat[0] = .5*mmod->lim->lonlat[0]; init_disk->centr->lonlat[1] = .5*mmod->lim->lonlat[1]; init_disk->n_ldsk_a = tree->n_otu; tree->disk = init_disk; } if(new_loc == YES) { For(i,tree->n_otu) { char *s; init_disk->ldsk_a[i] = PHYREX_Make_Lindisk_Node(n_dim); PHYREX_Init_Lindisk_Node(init_disk->ldsk_a[i],init_disk,n_dim); s = (char *)mCalloc(strlen(init_disk->ldsk_a[i]->coord->id)+1+20,sizeof(char)); strcpy(s,init_disk->ldsk_a[i]->coord->id); strcat(s,"_deme0\0"); Free(init_disk->ldsk_a[i]->coord->id); init_disk->ldsk_a[i]->coord->id = s; } /* PhyML_Printf("\n. WARNING: position of samples are not random."); */ /* Generate coordinates for the tip nodes (uniform distribution on the rectangle) */ For(i,tree->n_otu) { init_disk->ldsk_a[i]->coord->lonlat[0] = Uni()*tree->mmod->lim->lonlat[0]; // longitude init_disk->ldsk_a[i]->coord->lonlat[1] = Uni()*tree->mmod->lim->lonlat[1]; // latitude /* init_disk->ldsk_a[i]->coord->lonlat[0] = (i/(int)SQRT(tree->n_otu)+1)*tree->mmod->lim->lonlat[0]/(SQRT(tree->n_otu)+1); // longitude */ /* init_disk->ldsk_a[i]->coord->lonlat[1] = (i%(int)SQRT(tree->n_otu)+1)*tree->mmod->lim->lonlat[1]/(SQRT(tree->n_otu)+1); // latitude */ } } /* Allocate coordinates for all the tips first (will grow afterwards) */ ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *)); For(i,tree->n_otu) ldsk_a[i] = init_disk->ldsk_a[i]; /* Allocate and initialise for next event */ init_disk->prev = PHYREX_Make_Disk_Event(n_dim,tree->n_otu); PHYREX_Init_Disk_Event(init_disk->prev,n_dim,NULL); init_disk->prev->next = init_disk; /* Move to it */ disk = init_disk->prev; ldsk_a_tmp = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *)); curr_t = init_disk->time; dt_dsk = 0.0; n_lineages = init_disk->n_ldsk_a; n_disk = 0; lnL = 0.0; do { /* Time of next event */ dt_dsk = Rexp(mmod->lbda); curr_t -= dt_dsk; /* Coordinates of next event */ disk->centr->lonlat[0] = Uni()*mmod->lim->lonlat[0]; disk->centr->lonlat[1] = Uni()*mmod->lim->lonlat[1]; /* Density for waiting time to next event */ lnL += (LOG(mmod->lbda) - mmod->lbda*dt_dsk); /* Uniform density for disk center */ For(j,mmod->n_dim) lnL -= LOG(mmod->lim->lonlat[j]); disk->time = curr_t; disk->mmod = mmod; /* printf("\n. Disk %s has %d lindisk nodes and %d disks under",disk->id,disk->n_ldsk_a,disk->n_disk_under); */ /* New lindisk (will not be used if no lineage is hit) */ new_ldsk = PHYREX_Make_Lindisk_Node(n_dim); PHYREX_Init_Lindisk_Node(new_ldsk,disk,n_dim); /* Sample the location of new_ldsk. */ /* Takes into account the limits of the landscape */ switch(mmod->name) { case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(new_ldsk,disk,mmod); break; } case PHYREX_NORMAL: { PHYREX_Rnorm_Trunc(new_ldsk,disk,mmod); break; } default : { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); break; } } n_hit = 0; n_lineages_new = 0; For(i,n_lineages) { ldsk_a[i]->prev = NULL; prob_hit = -1.; switch(mmod->name) { case PHYREX_UNIFORM: { prob_hit = mmod->mu; break; } case PHYREX_NORMAL: { prob_hit = LOG(mmod->mu); For(j,mmod->n_dim) prob_hit += -POW(ldsk_a[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2)); prob_hit = EXP(prob_hit); break; } } if(PHYREX_Is_In_Disk(ldsk_a[i]->coord,disk,mmod) == YES) { u = Uni(); if(!(u > prob_hit)) { lnL += LOG(prob_hit); PHYREX_Make_Lindisk_Next(new_ldsk); ldsk_a[i]->prev = new_ldsk; new_ldsk->is_hit = YES; new_ldsk->next[new_ldsk->n_next-1] = ldsk_a[i]; disk->ldsk = new_ldsk; n_hit++; if(n_hit == 1) { ldsk_a_tmp[n_lineages_new] = new_ldsk; n_lineages_new++; } } else { lnL += LOG(1. - prob_hit); } } if(ldsk_a[i]->prev == NULL) /* Lineage was not hit */ { ldsk_a_tmp[n_lineages_new] = ldsk_a[i]; n_lineages_new++; } } if(n_hit >= 1) { phydbl log_dens_coal; log_dens_coal = 0.0; For(j,mmod->n_dim) log_dens_coal += Log_Dnorm_Trunc(new_ldsk->coord->lonlat[j], disk->centr->lonlat[j], mmod->rad, 0.0, mmod->lim->lonlat[j],&err); lnL += log_dens_coal; } assert(!((n_hit > 0) && (n_lineages_new != n_lineages - n_hit + 1))); if(n_hit > 0) n_lineages -= (n_hit-1); if(n_hit == 0) Free_Ldisk(new_ldsk); n_disk++; Free(ldsk_a); if(n_lineages == 1) break; ldsk_a = (t_ldsk **)mCalloc(tree->n_otu,sizeof(t_ldsk *)); For(i,n_lineages) ldsk_a[i] = ldsk_a_tmp[i]; disk->prev = PHYREX_Make_Disk_Event(n_dim,tree->n_otu); PHYREX_Init_Disk_Event(disk->prev,n_dim,NULL); disk->prev->next = disk; disk = disk->prev; } while(1); Free(ldsk_a_tmp); return(lnL); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ // Simulate Etheridge-Barton model forwards in time, following n_otu lineages // on a rectangle of dimension width x height phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree) { t_dsk *disk; t_ldsk *new_ldsk,**ldsk_a_pop,**ldsk_a_samp,**ldsk_a_tmp,**ldsk_a_tips; int i,j,n_disk,n_dim,n_otu,pop_size,parent_id,n_lineages,sample_size,n_poly,*permut; phydbl dt_dsk,curr_t,sum,*parent_prob,prob_death,tree_height,max_x,max_y,trans_x,trans_y,area; short int dies,n_remain; t_phyrex_mod *mmod; t_poly **poly; mmod = tree->mmod; n_dim = tree->mmod->n_dim; n_otu = tree->n_otu; /* pop_size = (int)(tree->mmod->rho * tree->mmod->lim->lonlat[0] * tree->mmod->lim->lonlat[1]); */ pop_size = 100*n_otu; parent_prob = (phydbl *)mCalloc(pop_size,sizeof(phydbl)); /* Allocate and initialise first disk event */ disk = PHYREX_Make_Disk_Event(n_dim,pop_size); PHYREX_Init_Disk_Event(disk,n_dim,NULL); /* Allocate coordinates for all the individuals in the population */ ldsk_a_pop = (t_ldsk **)mCalloc(pop_size,sizeof(t_ldsk *)); For(i,pop_size) { ldsk_a_pop[i] = PHYREX_Make_Lindisk_Node(n_dim); PHYREX_Init_Lindisk_Node(ldsk_a_pop[i],disk,n_dim); } /* Generate coordinates for all individuals */ For(i,pop_size) { ldsk_a_pop[i]->coord->lonlat[0] = Uni()*tree->mmod->lim->lonlat[0]; // longitude ldsk_a_pop[i]->coord->lonlat[1] = Uni()*tree->mmod->lim->lonlat[1]; // latitude } disk->prev = NULL; curr_t = 0.0; dt_dsk = 0.0; n_disk = 0; do { /* Coordinates of event */ disk->centr->lonlat[0] = Uni()*mmod->lim->lonlat[0]; disk->centr->lonlat[1] = Uni()*mmod->lim->lonlat[1]; /* Select one parent */ For(i,pop_size) { switch(mmod->name) { case PHYREX_UNIFORM: { if(PHYREX_Is_In_Disk(ldsk_a_pop[i]->coord,disk,mmod) == YES) parent_prob[i] = 1.0; else parent_prob[i] = 0.0; break; } case PHYREX_NORMAL: { parent_prob[i] = 0.0; For(j,mmod->n_dim) parent_prob[i] += -POW(ldsk_a_pop[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2)); parent_prob[i] = EXP(parent_prob[i]); break; } } } sum = 0.0; For(i,pop_size) sum += parent_prob[i]; For(i,pop_size) parent_prob[i] /= sum; parent_id = Sample_i_With_Proba_pi(parent_prob,pop_size); disk->ldsk = ldsk_a_pop[parent_id]; ldsk_a_pop[parent_id]->disk = disk; /* printf("\n. Disk %s has %s on it",disk->id,ldsk_a_pop[parent_id]->coord->id); */ /* Which lineages die in that event? Each lineage that dies off is being replaced with a new one which location is chosen randomly following the model */ For(i,pop_size) { prob_death = 0.0; switch(mmod->name) { case PHYREX_UNIFORM: { if(PHYREX_Is_In_Disk(ldsk_a_pop[i]->coord,disk,mmod) == YES) prob_death = mmod->mu; break; } case PHYREX_NORMAL: { prob_death = LOG(mmod->mu); For(j,mmod->n_dim) prob_death += -POW(ldsk_a_pop[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/(2.*POW(mmod->rad,2)); prob_death = EXP(prob_death); break; } } dies = NO; if(Uni() < prob_death || i == parent_id) dies = YES; /* Note: parent always dies (not in the model...) */ if(dies == YES) /* Replace dead lineage with new one */ { /* New lindisk */ new_ldsk = PHYREX_Make_Lindisk_Node(n_dim); PHYREX_Init_Lindisk_Node(new_ldsk,disk,n_dim); /* Select new location for new lineage replacing the one that just died */ switch(mmod->name) { case PHYREX_UNIFORM: { PHYREX_Runif_Rectangle_Overlap(new_ldsk,disk,mmod); break; } case PHYREX_NORMAL: { PHYREX_Rnorm_Trunc(new_ldsk,disk,mmod); break; } } /* Connect to parent */ new_ldsk->prev = disk->ldsk; /* Replace dead individual (thus, number of birth == number of death) */ if(i != parent_id) Free_Ldisk(ldsk_a_pop[i]); ldsk_a_pop[i] = new_ldsk; } } disk->next = PHYREX_Make_Disk_Event(n_dim,n_otu); PHYREX_Init_Disk_Event(disk->next,n_dim,NULL); disk->next->prev = disk; disk = disk->next; n_disk++; /* Time of next event */ dt_dsk = Rexp(mmod->lbda); curr_t += dt_dsk; disk->time = curr_t; disk->mmod = mmod; } while(n_disk < 100000); For(i,pop_size) ldsk_a_pop[i]->disk = disk; /* Allocate coordinates for all the tips first (will grow afterwards) */ ldsk_a_samp = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *)); ldsk_a_tips = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *)); ldsk_a_tmp = (t_ldsk **)mCalloc(n_otu,sizeof(t_ldsk *)); /* Sample individuals (take the first n_otu ldsk within ldsk_a_pop array) */ /* For(i,n_otu) ldsk_a_samp[i] = ldsk_a_pop[i]; */ n_poly = n_sites; do { poly = (t_poly **)mCalloc(n_poly,sizeof(t_poly *)); For(i,n_poly) poly[i] = Rpoly(3); /* triangles */ For(i,n_poly) { For(j,poly[i]->n_poly_vert) { poly[i]->poly_vert[j]->lonlat[0] *= mmod->lim->lonlat[0]*0.5; poly[i]->poly_vert[j]->lonlat[1] *= mmod->lim->lonlat[1]*0.5; } max_x = 0.0; max_y = 0.0; For(j,poly[i]->n_poly_vert) { if(poly[i]->poly_vert[j]->lonlat[0] > max_x) max_x = poly[i]->poly_vert[j]->lonlat[0]; if(poly[i]->poly_vert[j]->lonlat[1] > max_y) max_y = poly[i]->poly_vert[j]->lonlat[1]; } trans_x = Uni()*(mmod->lim->lonlat[0] - max_x); trans_y = Uni()*(mmod->lim->lonlat[1] - max_y); For(j,poly[i]->n_poly_vert) { poly[i]->poly_vert[j]->lonlat[0] += trans_x; poly[i]->poly_vert[j]->lonlat[1] += trans_y; PhyML_Printf("\n# Sampling == polygon %d vertex @ (%f; %f)", i, poly[i]->poly_vert[j]->lonlat[0], poly[i]->poly_vert[j]->lonlat[1]); } } For(i,n_otu) ldsk_a_samp[i] = NULL; permut = Permutate(n_poly); sample_size = 0; For(i,pop_size) { For(j,n_poly) { if(Is_In_Polygon(ldsk_a_pop[i]->coord,poly[permut[j]]) == YES) { char *s; int k; s = (char *)mCalloc((int)strlen(ldsk_a_pop[i]->coord->id)+1+20,sizeof(char)); For(k,(int)strlen(ldsk_a_pop[i]->coord->id)+1+20) s[k]='\0'; strcpy(s,ldsk_a_pop[i]->coord->id); Free(ldsk_a_pop[i]->coord->id); strcat(s,"_deme"); sprintf(s+strlen(s),"%d",permut[j]); ldsk_a_pop[i]->coord->id = s; ldsk_a_samp[sample_size] = ldsk_a_pop[i]; sample_size++; PhyML_Printf("\n@ Coord: %f %f %s",ldsk_a_samp[sample_size-1]->coord->lonlat[0],ldsk_a_samp[sample_size-1]->coord->lonlat[1],ldsk_a_pop[i]->coord->id); break; } } if(sample_size == n_otu) break; } Free(permut); area = Area_Of_Poly_Monte_Carlo(poly,n_poly,mmod->lim); For(j,n_poly) Free_Poly(poly[j]); Free(poly); if(i == pop_size) { PhyML_Printf("\n== Not enough individuals in polygon(s) (only %d found).",sample_size); /* Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ } else break; } while(1); For(i,n_otu) ldsk_a_tips[i] = ldsk_a_samp[i]; tree->disk = disk; disk->ldsk_a = ldsk_a_tips; disk->mmod = tree->mmod; disk->centr->lonlat[0] = .5*tree->mmod->lim->lonlat[0]; disk->centr->lonlat[1] = .5*tree->mmod->lim->lonlat[1]; disk->n_ldsk_a = n_otu; int n_discs = 0; n_lineages = n_otu; do { /* printf("\n [%s %f]",disk->id,disk->time); */ n_remain = 0; For(i,n_lineages) { /* printf(" %s",ldsk_a_samp[i]->coord->id); */ if((disk->prev->ldsk != NULL) && (disk->prev->ldsk == ldsk_a_samp[i]->prev)) /* Coalescent event is sampled */ { /* printf("*"); */ PHYREX_Make_Lindisk_Next(disk->prev->ldsk); disk->prev->ldsk->next[disk->prev->ldsk->n_next-1] = ldsk_a_samp[i]; } else { ldsk_a_tmp[n_remain] = ldsk_a_samp[i]; n_remain++; } } For(i,n_remain) ldsk_a_samp[i] = ldsk_a_tmp[i]; if((disk->prev->ldsk != NULL) && (disk->prev->ldsk->n_next > 0)) ldsk_a_samp[i] = disk->prev->ldsk; if((disk->prev->ldsk != NULL) && (disk->prev->ldsk->n_next > 0)) { n_lineages -= (disk->prev->ldsk->n_next); n_lineages += 1; } if(n_lineages != n_remain+(disk->prev->ldsk && disk->prev->ldsk->n_next>0)?1:0) { PhyML_Printf("\n== n_lineages: %d n_remain: %d n_next: %d", n_lineages, n_remain, disk->prev->ldsk->n_next); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } /* None of the sampled lineages was hit */ if((disk->prev->ldsk != NULL) && (disk->prev->ldsk->n_next == 0)) { /* printf("\n. free %s @ %f",disk->ldsk->coord->id,disk->time); */ Free_Ldisk(disk->prev->ldsk); disk->prev->ldsk = NULL; } disk = disk->prev; if(disk->prev == NULL) { PhyML_Printf("\n== # lineages left: %d",n_remain); PhyML_Printf("\n== Sample has not coalesced completely."); fflush(NULL); Exit("\n"); } } while(n_lineages > 1); /* For(i,n_otu) printf("\n> %s",tree->disk->ldsk_a[i]->coord->id); */ disk->prev = NULL; disk = tree->disk; tree_height = disk->time; n_discs = 0; while(disk) { disk->time -= tree_height; disk = disk->prev; n_discs++; } Free(ldsk_a_tmp); Free(ldsk_a_samp); Free(ldsk_a_pop); Free(parent_prob); /* PHYREX_Print_Struct('#',tree); */ /* Exit("\n"); */ return(area); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Test whether coord is in disk. Will actually only works in disk */ /* is a rectangle... */ int PHYREX_Is_In_Disk(t_geo_coord *coord, t_dsk *disk, t_phyrex_mod *mmod) { int i; assert(disk->centr->dim); if(mmod->name == PHYREX_UNIFORM) { For(i,disk->centr->dim) { if(FABS(coord->lonlat[i] - disk->centr->lonlat[i]) > disk->mmod->rad + 1.E-20) { return(NO); } } return(YES); } else if(mmod->name == PHYREX_NORMAL) { return(YES); } return(-1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PHYREX_Lk(t_tree *tree) { phydbl lnL; phydbl log_lbda; t_dsk *disk; assert(!tree->disk->next); assert(tree->disk->prev); tree->mmod->c_lnL = 0.0; log_lbda = LOG(tree->mmod->lbda); /* TO DO: create a proper PHYREX_LogPost() function */ tree->mmod->c_lnL += PHYREX_LnPrior_Radius(tree); tree->mmod->c_lnL += PHYREX_LnPrior_Mu(tree); tree->mmod->c_lnL += PHYREX_LnPrior_Lbda(tree); if(isinf(tree->mmod->c_lnL) || isnan(tree->mmod->c_lnL)) { tree->mmod->c_lnL = UNLIKELY; return tree->mmod->c_lnL; } PHYREX_Update_Lindisk_List(tree); disk = tree->disk->prev; assert(disk); do { lnL = PHYREX_Lk_Core(disk,tree); lnL += log_lbda - tree->mmod->lbda * FABS(disk->time - disk->next->time); tree->mmod->c_lnL += lnL; disk->c_lnL = tree->mmod->c_lnL; disk = disk->prev; } while(disk); if(isinf(tree->mmod->c_lnL) || isnan(tree->mmod->c_lnL)) tree->mmod->c_lnL = UNLIKELY; return(tree->mmod->c_lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree) { phydbl lnL,log_prob_hit,log_mu,log_dens_coal; int was_hit,i,j,k,err; phydbl two_theta_two; two_theta_two = 2.*POW(tree->mmod->rad,2); lnL = 0.0; log_mu = LOG(tree->mmod->mu); was_hit = (disk->ldsk != NULL); For(i,disk->n_ldsk_a) { if(PHYREX_Is_In_Ldscape(disk->ldsk_a[i],tree->mmod) == NO) return(UNLIKELY); if(was_hit && disk->ldsk_a[i] == disk->ldsk) { For(k,disk->ldsk->n_next) { log_prob_hit = log_mu; For(j,tree->mmod->n_dim) log_prob_hit += -POW(disk->ldsk->next[k]->coord->lonlat[j] - disk->centr->lonlat[j],2)/two_theta_two; lnL += log_prob_hit; } } else { log_prob_hit = log_mu; For(j,tree->mmod->n_dim) log_prob_hit += -POW(disk->ldsk_a[i]->coord->lonlat[j] - disk->centr->lonlat[j],2)/two_theta_two; lnL += LOG(1. - EXP(log_prob_hit)); } } /* a hit occurred */ if(was_hit == TRUE) { err = NO; log_dens_coal = 0.0; For(j,tree->mmod->n_dim) log_dens_coal += Log_Dnorm_Trunc(disk->ldsk->coord->lonlat[j], disk->centr->lonlat[j], tree->mmod->rad, 0.0, tree->mmod->lim->lonlat[j],&err); lnL += log_dens_coal; } /* Likelihood for the disk center */ For(i,disk->mmod->n_dim) lnL -= LOG(tree->mmod->lim->lonlat[i]); return(lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PHYREX_Lk_Range(t_dsk *young, t_dsk *old, t_tree *tree) { t_dsk *disk; phydbl lnL,log_lbda; assert(young); assert(young->next); log_lbda = LOG(tree->mmod->lbda); lnL = 0.0; disk = young; do { PHYREX_Update_Lindisk_List_Core(disk,tree); lnL += PHYREX_Lk_Core(disk,tree); lnL += log_lbda - tree->mmod->lbda * FABS(disk->time - disk->next->time); if(disk == old) break; disk = disk->prev; } while(disk); return(lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *PHYREX_MCMC(t_tree *tree) { t_mcmc *mcmc; int move,i,n_vars,burnin,true_ncoal,true_nint,true_nhits; phydbl u; t_dsk *disk; FILE *fp_tree,*fp_stats,*fp_summary; phydbl *res; phydbl true_root_x, true_root_y,true_lbda,true_mu,true_sigsq,true_neigh,fst_neigh,diversity,true_rad,true_height,true_rhoe; int adjust_len; fp_tree = tree->io->fp_out_tree; fp_stats = tree->io->fp_out_stats; fp_summary = tree->io->fp_out_summary; mcmc = MCMC_Make_MCMC_Struct(); disk = tree->disk; while(disk->prev) disk = disk->prev; tree->mcmc = mcmc; mcmc->io = NULL; mcmc->is = NO; mcmc->use_data = YES; mcmc->run = 0; mcmc->chain_len_burnin = 1E+5; mcmc->randomize = YES; mcmc->norm_freq = 1E+3; mcmc->max_tune = 1.E+20; mcmc->min_tune = 1.E-10; mcmc->print_every = 2; mcmc->is_burnin = NO; mcmc->nd_t_digits = 1; mcmc->chain_len = 1E+8; mcmc->sample_interval = 1E+3; mcmc->max_lag = 1000; mcmc->sample_size = mcmc->chain_len/mcmc->sample_interval; mcmc->sample_num = 0; adjust_len = 1E+6; MCMC_Complete_MCMC(mcmc,tree); n_vars = 12; true_root_x = disk->ldsk->coord->lonlat[0]; true_root_y = disk->ldsk->coord->lonlat[1]; res = (phydbl *)mCalloc(tree->mcmc->chain_len / tree->mcmc->sample_interval * n_vars,sizeof(phydbl)); PHYREX_Lk(tree); Lk(NULL,tree); true_lbda = tree->mmod->lbda; true_mu = tree->mmod->mu; true_sigsq = tree->mmod->sigsq; true_rad = tree->mmod->rad; true_neigh = PHYREX_Neighborhood_Size(tree); fst_neigh = PHYREX_Neighborhood_Size_Regression(tree); diversity = Nucleotide_Diversity(tree->data); true_ncoal = PHYREX_Total_Number_Of_Coal_Disks(tree); true_nint = PHYREX_Total_Number_Of_Intervals(tree); true_nhits = PHYREX_Total_Number_Of_Hit_Disks(tree); true_height = PHYREX_Tree_Height(tree); true_rhoe = PHYREX_Effective_Density(tree); PhyML_Fprintf(fp_stats,"\n# before rand glnL: %f alnL: %f",tree->mmod->c_lnL,tree->c_lnL); PhyML_Fprintf(fp_stats,"\n# ninter: %d",PHYREX_Total_Number_Of_Intervals(tree)); PhyML_Fprintf(fp_stats,"\n# ncoal: %d",PHYREX_Total_Number_Of_Coal_Disks(tree)); PhyML_Fprintf(fp_stats,"\n# nhits: %d",PHYREX_Total_Number_Of_Hit_Disks(tree)); PhyML_Fprintf(fp_stats,"\n# root pos: %f %f",true_root_x,true_root_y); PhyML_Fprintf(fp_stats,"\n# root time: %f",disk->time); PhyML_Fprintf(fp_stats,"\n# true lbda: %f",tree->mmod->lbda); PhyML_Fprintf(fp_stats,"\n# true mu: %f",tree->mmod->mu); PhyML_Fprintf(fp_stats,"\n# true rad: %f",PHYREX_Update_Radius(tree)); PhyML_Fprintf(fp_stats,"\n# true sigsq: %f",tree->mmod->sigsq); PhyML_Fprintf(fp_stats,"\n# true neigh. size: %f",PHYREX_Neighborhood_Size(tree)); PhyML_Fprintf(fp_stats,"\n# fst-based estimate of neighborhood size: %f",PHYREX_Neighborhood_Size_Regression(tree)); PhyML_Fprintf(fp_stats,"\n# true pop. density: %f",true_rhoe); PhyML_Fprintf(fp_stats,"\n# nucleotide diversity: %f",Nucleotide_Diversity(tree->data)); PhyML_Fprintf(fp_stats,"\n# length of a generation: %G time units",PHYREX_Generation_Length(tree)); PhyML_Fprintf(fp_stats,"\n# clock rate: %G subst. per time unit",tree->rates->clock_r); PhyML_Fprintf(fp_stats,"\n# proportion of sampled area: %f",tree->mmod->sampl_area); /* Starting parameter values */ tree->mmod->lbda = Uni()*(0.5 - 0.2) + 0.2; tree->mmod->mu = Uni()*(0.6 - 0.3) + 0.3; tree->mmod->rad = Uni()*(4.0 - 2.0) + 2.0; PHYREX_Update_Sigsq(tree); /* tree->mmod->lbda = Uni()*(0.50 - 0.20) + 0.20; */ /* tree->mmod->mu = Uni()*(0.30 - 0.05) + 0.05; */ /* tree->mmod->rad = Uni()*(3.00 - 1.00) + 1.00; */ /* PHYREX_Update_Sigsq(tree); */ /* MCMC_Randomize_Rate_Across_Sites(tree); */ MCMC_Randomize_Kappa(tree); /* Random genealogy */ PHYREX_Simulate_Backward_Core(NO,tree->disk,tree); PHYREX_Lk(tree); Switch_Eigen(YES,tree->mod); Lk(NULL,tree); Switch_Eigen(NO,tree->mod); disk = tree->disk; while(disk->prev) disk = disk->prev; PhyML_Fprintf(fp_stats,"\n# after rand glnL: %f alnL: %f",tree->mmod->c_lnL,tree->c_lnL); PhyML_Fprintf(fp_stats,"\n# ninter: %d",PHYREX_Total_Number_Of_Intervals(tree)); PhyML_Fprintf(fp_stats,"\n# ncoal: %d",PHYREX_Total_Number_Of_Coal_Disks(tree)); PhyML_Fprintf(fp_stats,"\n# nhits: %d",PHYREX_Total_Number_Of_Hit_Disks(tree)); PhyML_Fprintf(fp_stats,"\n# root pos: %f %f",true_root_x,true_root_y); PhyML_Fprintf(fp_stats,"\n# root time: %f",disk->time); PhyML_Fprintf(fp_stats,"\n# start lbda: %f",tree->mmod->lbda); PhyML_Fprintf(fp_stats,"\n# start mu: %f",tree->mmod->mu); PhyML_Fprintf(fp_stats,"\n# start rad: %f",tree->mmod->rad); fflush(NULL); PhyML_Fprintf(fp_stats,"\n%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", "sample", "lnP", "alnL", "glnL", "lbda", "modLbda", "mu", "modNeigh", "sigsq", "modSigsq", "rad", "neigh", "rhoe", "nInt", "nCoal", "nHit", "rootTime", "tstv", "alpha", "accLbda", "accMu", "accRad", "accInDelDisk", "accInDelHit", "accScaleTime", "accSPR", "accPath", "accSim", "accLbdaTimes", "accSimPlus", "accIndelSerial", "accLdskGivenDisk", "accDiskGivenLdsk", "accDiskAndLdsk", "accLdskMulti", "accDiskMulti", "tuneLbda", "tuneRad", "tuneMu"); For(i,mcmc->n_moves) tree->mcmc->start_ess[i] = YES; Set_Both_Sides(NO,tree); mcmc->use_data = YES; mcmc->always_yes = NO; move = -1; do { /* tree->mcmc->adjust_tuning[i] = NO; */ if(mcmc->run > adjust_len) For(i,mcmc->n_moves) tree->mcmc->adjust_tuning[i] = NO; if(tree->mmod->c_lnL < UNLIKELY + 0.1) { PhyML_Printf("\n== Move '%s' failed\n",tree->mcmc->move_name[move]); assert(FALSE); } u = Uni(); For(move,tree->mcmc->n_moves) if(tree->mcmc->move_weight[move] > u-1.E-10) break; assert(!(move == tree->mcmc->n_moves)); /* printf("\n. %10d %30s %f",tree->mcmc->run,tree->mcmc->move_name[move],tree->mmod->c_lnL); fflush(NULL); */ /* printf("\n. %10d %30s %f",tree->mcmc->run,tree->mcmc->move_name[move],PHYREX_Lk(tree)); */ if(!strcmp(tree->mcmc->move_name[move],"phyrex_lbda")) MCMC_PHYREX_Lbda(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_mu")) MCMC_PHYREX_Mu(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_rad")) MCMC_PHYREX_Radius(tree); /* /\* if(!strcmp(tree->mcmc->move_name[move],"phyrex_sigsq")) *\/ */ /* /\* MCMC_PHYREX_Sigsq(tree); *\/ */ if(!strcmp(tree->mcmc->move_name[move],"phyrex_indel_disk")) MCMC_PHYREX_Indel_Disk(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_indel_hit")) MCMC_PHYREX_Indel_Hit(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_move_disk_ud")) MCMC_PHYREX_Move_Disk_Updown(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_swap_disk")) MCMC_PHYREX_Swap_Disk(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_spr")) MCMC_PHYREX_Prune_Regraft(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_scale_times")) MCMC_PHYREX_Scale_Times(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_sim")) MCMC_PHYREX_Simulate_Backward(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_sim_plus")) MCMC_PHYREX_Simulate_Backward_Plus(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_traj")) MCMC_PHYREX_Lineage_Traj(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_lbda_times")) MCMC_PHYREX_Lbda_Times(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_disk_multi")) MCMC_PHYREX_Disk_Multi(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_ldsk_multi")) MCMC_PHYREX_Ldsk_Multi(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_ldsk_and_disk")) MCMC_PHYREX_Ldsk_And_Disk(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_ldsk_given_disk")) MCMC_PHYREX_Ldsk_Given_Disk(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_disk_given_ldsk")) MCMC_PHYREX_Disk_Given_Ldsk(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_indel_disk_serial")) MCMC_PHYREX_Indel_Disk_Serial(tree); if(!strcmp(tree->mcmc->move_name[move],"phyrex_indel_hit_serial")) MCMC_PHYREX_Indel_Hit_Serial(tree); if(!strcmp(tree->mcmc->move_name[move],"kappa")) MCMC_Kappa(tree); if(!strcmp(tree->mcmc->move_name[move],"ras")) MCMC_Rate_Across_Sites(tree); /* /\* if(!strcmp(tree->mcmc->move_name[move],"phyrex_ldscape_lim")) *\/ */ /* /\* MCMC_PHYREX_Ldscape_Limits(tree); *\/ */ tree->mcmc->run++; MCMC_Get_Acc_Rates(tree->mcmc); if(!(tree->mcmc->run%tree->mcmc->sample_interval)) { /* Lk(NULL,tree); */ /* RATES_Update_Cur_Bl(tree); */ /* char *s = Write_Tree(tree,NO); */ /* PhyML_Fprintf(fp_tree,"\n[%f %f] %s",s,tree->rates->nd_t[tree->n_root->num],tree->c_lnL); */ /* Free(s); */ /* fflush(NULL); */ disk = tree->disk; while(disk->prev) disk = disk->prev; PhyML_Fprintf(fp_stats,"\n%6d\t%9.1f\t%9.1f\t%9.1f\t%6.3f\t%6.3f\t%6.3f\t%6.3f\t%6.3f\t%6.3f\t%6.3f\t%6.3f\t%G\t%6d\t%6d\t%6d\t%8.1f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%6.2f\t%G\t%G\t%G", tree->mcmc->run, tree->c_lnL+tree->mmod->c_lnL, tree->c_lnL, tree->mmod->c_lnL, tree->mmod->lbda, tree->mcmc->mode[tree->mcmc->num_move_phyrex_lbda], tree->mmod->mu, tree->mcmc->mode[tree->mcmc->num_move_phyrex_mu], PHYREX_Update_Sigsq(tree), tree->mcmc->mode[tree->mcmc->num_move_phyrex_sigsq], tree->mmod->rad, PHYREX_Neighborhood_Size(tree), PHYREX_Effective_Density(tree), PHYREX_Total_Number_Of_Intervals(tree), PHYREX_Total_Number_Of_Coal_Disks(tree), PHYREX_Total_Number_Of_Hit_Disks(tree), disk->time, tree->mod->kappa->v, tree->mod->ras->alpha->v, tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_lbda], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_mu], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_rad], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_indel_disk], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_indel_hit], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_scale_times], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_spr], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_traj], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_sim], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_lbda_times], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_sim_plus], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_indel_hit_serial], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_ldsk_given_disk], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_disk_given_ldsk], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_ldsk_and_disk], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_ldsk_multi], tree->mcmc->acc_rate[tree->mcmc->num_move_phyrex_disk_multi], tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_lbda], tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_rad], tree->mcmc->tune_move[tree->mcmc->num_move_phyrex_mu]); fflush(fp_stats); res[0 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = tree->mmod->lbda; res[1 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = tree->mmod->mu; res[2 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Update_Sigsq(tree); res[3 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Neighborhood_Size(tree); res[4 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = tree->mmod->rad; res[5 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Total_Number_Of_Intervals(tree); res[6 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Total_Number_Of_Coal_Disks(tree); res[7 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Total_Number_Of_Hit_Disks(tree); res[8 * tree->mcmc->chain_len / tree->mcmc->sample_interval + tree->mcmc->run / tree->mcmc->sample_interval] = PHYREX_Effective_Density(tree); MCMC_Copy_To_New_Param_Val(tree->mcmc,tree); For(i,tree->mcmc->n_moves) if(tree->mcmc->start_ess[i] == YES) MCMC_Update_Effective_Sample_Size(i,tree->mcmc,tree); For(i,tree->mcmc->n_moves) MCMC_Update_Mode(i,tree->mcmc,tree); burnin = (int)(0.5*(tree->mcmc->run / tree->mcmc->sample_interval)); rewind(fp_summary); PhyML_Fprintf(fp_summary,"\n# SampArea\t TrueLbda\t TrueMu\t TrueSig\t TrueRad\t TrueNeigh\t TrueRhoe\t Diversity\t TrueInt\t TrueCoal\t TrueHits\t RegNeigh\t TrueXroot\t TrueYroot\t TrueHeight\t Lbda5\t Lbda50\t Lbda95\t LbdaMod \t Mu5\t Mu50\t Mu95\t MuMod \t Sig5\t Sig50\t Sig95\t SigMod \t Neigh5\t Neigh50\t Neigh95\t NeighMod \t Rad5\t Rad50\t Rad95\t Int5\t Int50\t Int95\t Coal5\t Coal50\t Coal95\t Hit5\t Hit50\t Hit95\t Rhoe5\t Rhoe50\t Rhoe95\t ESSLbda \t ESSMu \t ESSSig \t Run"); PhyML_Fprintf(fp_summary,"\n %f\t %f\t %f\t %f\t %f\t %f\t %f\t %f\t %d\t %d\t %d\t %f\t %f\t %f\t %f\t ", tree->mmod->sampl_area, true_lbda, true_mu, true_sigsq, true_rad, true_neigh, true_rhoe, diversity, true_nint, true_ncoal, true_nhits, fst_neigh, true_root_x, true_root_y, true_height); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t", /* Lbda5 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Lbda50 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Lbda95 */ Quantile(res+0*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975), /* LbdaMod*/ tree->mcmc->mode[tree->mcmc->num_move_phyrex_lbda]); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t", /* mu5 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* mu50 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* mu95 */ Quantile(res+1*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975), /* muMod */ 2./tree->mcmc->mode[tree->mcmc->num_move_phyrex_mu]); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t", /* sig5 */ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* sig50*/ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* sig95*/ Quantile(res+2*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975), /* sigMod */ tree->mcmc->mode[tree->mcmc->num_move_phyrex_sigsq]); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t %f\t", /* Neigh5 */ Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Neigh50*/ Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Neigh95*/ Quantile(res+3*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975), /* NeighMod */ tree->mcmc->mode[tree->mcmc->num_move_phyrex_mu]); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", /* Rad5 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Rad50 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Rad95 */ Quantile(res+4*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975)); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", /* Int5 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Int50 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Int95 */ Quantile(res+5*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975)); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", /* Coal5 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Coal50 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Coal95 */ Quantile(res+6*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975)); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", /* Hit5 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* Hit50 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* Hit95 */ Quantile(res+7*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975)); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", /* rhoe5 */ Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.025), /* rhoe50 */ Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.50), /* rhoe95 */ Quantile(res+8*tree->mcmc->chain_len / tree->mcmc->sample_interval+burnin,tree->mcmc->run / tree->mcmc->sample_interval+1-burnin,0.975)); PhyML_Fprintf(fp_summary,"%f\t %f\t %f\t", tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda], tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu], tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq]); PhyML_Fprintf(fp_summary,"%d\t",tree->mcmc->run); PhyML_Fprintf(fp_summary,"\n\n"); fflush(NULL); tree->mcmc->sample_num++; } if(tree->mcmc->run > 2*adjust_len && tree->mcmc->sample_num > 1E+2 && tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda] > 100. && tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu] > 100. && tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq] > 100.) break; /* if(tree->mcmc->run > tree->mcmc->sample_interval && */ /* tree->mcmc->ess[tree->mcmc->num_move_phyrex_lbda] > 1. && */ /* tree->mcmc->ess[tree->mcmc->num_move_phyrex_mu] > 1. && */ /* tree->mcmc->ess[tree->mcmc->num_move_phyrex_sigsq] > 1.) break; */ (void)signal(SIGINT,MCMC_Terminate); } while(tree->mcmc->run < tree->mcmc->chain_len); fclose(fp_tree); fclose(fp_stats); fclose(fp_summary); return(res); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PHYREX_Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree) { return PHYREX_Lk(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree) { t_dsk *disk; int i,j; int n_hit_up,n_hit_tot; /* phydbl min_up, min_do; */ /* phydbl max_up, max_do; */ For(i,start->n_ldsk_a) { /* printf("\n<><><>"); */ disk = end; while(disk != start) { /* disk->ldsk_a[i]->min_coord = GEO_Make_Geo_Coord(disk->mmod->n_dim); */ /* disk->ldsk_a[i]->max_coord = GEO_Make_Geo_Coord(disk->mmod->n_dim); */ disk = disk->prev; } disk = end; n_hit_tot = 0; while(disk != start) { if(disk->ldsk_a[i]->is_hit == YES) n_hit_tot++; disk = disk->prev; } /* printf("\n. n_hit_tot: %d",n_hit_tot); */ /* fflush(NULL); */ /* printf("\n. Start disk name: %s lindisk %s at %.2f [%.2f %.2f] end disk: %s lindisk %s at %.2f [%.2f %.2f]", */ /* start->id, */ /* start->ldsk_a[i]->coord->id, */ /* start->time, */ /* start->ldsk_a[i]->coord->lonlat[0], */ /* start->ldsk_a[i]->coord->lonlat[1], */ /* end->id, */ /* end->ldsk_a[i]->coord->id, */ /* end->time, */ /* end->ldsk_a[i]->coord->lonlat[0], */ /* end->ldsk_a[i]->coord->lonlat[1] */ /* ); */ /* disk = end; */ /* while(disk != start) */ /* { */ /* printf("\n. %d %s %.2f %.2f", */ /* i, */ /* disk->ldsk_a[i]->coord->id, */ /* disk->ldsk_a[i]->coord->lonlat[0], */ /* disk->ldsk_a[i]->coord->lonlat[1]); */ /* disk = disk->prev; */ /* } */ n_hit_up = 0; disk = end; while(disk->prev != start) { if(disk->ldsk_a[i]->is_hit == YES) { n_hit_up++; For(j,disk->mmod->n_dim) { /* min_up = end->ldsk_a[i]->coord->lonlat[j] - n_hit_up * 2. * disk->mmod->rad; */ /* min_do = start->ldsk_a[i]->coord->lonlat[j] - (n_hit_tot - n_hit_up) * 2. * disk->mmod->rad; */ /* disk->ldsk_a[i]->prev->min_coord->lonlat[j] = */ /* MAX(MAX(MAX(min_up,min_do),0.0),disk->prev->centr->lonlat[j] - disk->mmod->rad); */ /* max_up = end->ldsk_a[i]->coord->lonlat[j] + n_hit_up * 2. * disk->mmod->rad; */ /* max_do = start->ldsk_a[i]->coord->lonlat[j] + (n_hit_tot - n_hit_up) * 2. * disk->mmod->rad; */ /* disk->ldsk_a[i]->prev->max_coord->lonlat[j] = */ /* MIN(MIN(MIN(max_up,max_do),disk->mmod->lim->lonlat[j]),disk->prev->centr->lonlat[j] + disk->mmod->rad); */ /* printf("\n. curr: %s min_up: %.2f min_do: %.2f max_up: %.2f max_do: %.2f %d %d start: %.2f [%.2f %.2f]", */ /* disk->ldsk_a[i]->prev->coord->id, */ /* min_up,min_do,max_up,max_do, */ /* n_hit_tot,n_hit_up, */ /* start->ldsk_a[i]->coord->lonlat[j], */ /* disk->ldsk_a[i]->prev->min_coord->lonlat[j], */ /* disk->ldsk_a[i]->prev->max_coord->lonlat[j]); */ } } disk = disk->prev; } disk = end; while(disk->prev != start) { if(disk->ldsk_a[i]->is_hit == YES) { /* For(j,disk->mmod->n_dim) */ /* disk->ldsk_a[i]->prev->coord->lonlat[j] = */ /* Uni()* */ /* (disk->ldsk_a[i]->prev->max_coord->lonlat[j] - */ /* disk->ldsk_a[i]->prev->min_coord->lonlat[j]) + */ /* disk->ldsk_a[i]->prev->min_coord->lonlat[j]; */ } else { For(j,disk->mmod->n_dim) disk->ldsk_a[i]->prev->coord->lonlat[j] = disk->ldsk_a[i]->coord->lonlat[j]; } disk = disk->prev; } disk = end; while(disk != start) { /* Free_Geo_Coord(disk->ldsk_a[i]->min_coord); */ /* Free_Geo_Coord(disk->ldsk_a[i]->max_coord); */ disk = disk->prev; } } /* gtk_widget_queue_draw(tree->draw_area); */ /* For(i,start->n_ldsk_a) */ /* { */ /* printf("\n<><><>"); */ /* disk = end; */ /* while(disk != start) */ /* { */ /* printf("\nx %s %.2f %.2f centr: %.2f %.2f", */ /* disk->ldsk_a[i]->coord->id, */ /* disk->ldsk_a[i]->coord->lonlat[0], */ /* disk->ldsk_a[i]->coord->lonlat[1], */ /* disk->centr->lonlat[0], */ /* disk->centr->lonlat[1]); */ /* disk = disk->prev; */ /* } */ /* fflush(NULL); */ /* } */ /* PHYREX_Lk(tree); */ /* printf("\n. >> Lk: %f rad: %f",tree->mmod->c_lnL,tree->mmod->rad); */ /* sleep(5); */ } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Remove_Disk(t_dsk *disk) { t_dsk *prev; t_dsk *next; prev = disk->prev; next = disk->next; assert(!(prev == NULL)); assert(!(next == NULL)); prev->next = next; next->prev = prev; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Insert disk event based on its time. Insertion above the root is not permitted */ void PHYREX_Insert_Disk(t_dsk *ins, t_tree *tree) { t_dsk *disk; assert(!(ins == NULL)); disk = tree->disk->prev; while(disk != NULL && disk->time > ins->time) disk = disk->prev; assert(!(disk == NULL)); ins->prev = disk; ins->next = disk->next; disk->next = ins; ins->next->prev = ins; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ t_ldsk *PHYREX_Prev_Coal_Lindisk(t_ldsk *t) { if(t == NULL) return NULL; if(t->n_next > 1) { return t; } else { return PHYREX_Prev_Coal_Lindisk(t->prev); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_ldsk *PHYREX_Next_Coal_Lindisk(t_ldsk *t) { assert(!(t == NULL)); if(t->n_next > 1 || t->next == NULL) return t; else { if(t->n_next > 1) // Should have t->is_coal = YES { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } return PHYREX_Next_Coal_Lindisk(t->next[0]); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Generate a new trajectory, including disk event centers, between 'y_ldsk' a ``young'' lindisk event and 'o_ldsk' an old one. 'y_ldsk and 'o_ldsk' remain unaffected. No disk events should be present between y_ldsk and o_ldsk: we need to generate some first. n_cur_disk is the current number of disks between y_ldsk and o_ldsk. */ int PHYREX_One_New_Traj(t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y, t_dsk *xtra_dsk, int n_cur_disk, t_tree *tree) { t_phyrex_mod *mmod; t_dsk *disk,**disk_new; int i,n,K; int min_n_disk,n_new_disk,n_disk; mmod = tree->mmod; disk = NULL; disk_new = NULL; K = 2; /* printf("\n# New traj from %s to %s",y_ldsk->coord->id,o_ldsk->coord->id); */ /* fflush(NULL); */ /* Minimum number of disks between y_ldsk and o_ldsk */ min_n_disk = 0; For(i,mmod->n_dim) { /* PhyML_Printf("\n# y_ldsk %s : %f o_ldsk->disk->centr: %f rad: %f", */ /* y_ldsk->coord->id, */ /* y_ldsk->coord->lonlat[i], */ /* o_ldsk->disk->centr->lonlat[i], */ /* mmod->rad); */ if(y_ldsk->coord->lonlat[i] < o_ldsk->disk->centr->lonlat[i]) { n_disk = 0; while(y_ldsk->coord->lonlat[i] + (2*n_disk-1)*mmod->rad < o_ldsk->disk->centr->lonlat[i] - mmod->rad) n_disk++; if(n_disk > min_n_disk) min_n_disk = n_disk; } else { n_disk = 0; while(y_ldsk->coord->lonlat[i] - (2*n_disk-1)*mmod->rad > o_ldsk->disk->centr->lonlat[i] + mmod->rad) n_disk++; if(n_disk > min_n_disk) min_n_disk = n_disk; } /* printf(" -- min_n_disk: %d",min_n_disk); */ } /* printf("\n# min_n_disk: %d cur_n_disk: %d",min_n_disk,n_cur_disk); */ /* fflush(NULL); */ /* How many disks along the new path between y_ldsk and o_ldsk */ n_new_disk = Rand_Int(n_cur_disk-K,n_cur_disk+K); if(n_new_disk < min_n_disk) n_new_disk = min_n_disk; if(xtra_dsk != NULL) n_new_disk++; /* printf("\n# Add n_new_disk: %d",n_new_disk); fflush(NULL); */ if(n_new_disk > 0) { /* Make new disks to create a new path between ldsk_left and ldsk_up */ disk_new = (t_dsk **)mCalloc(n_new_disk,sizeof(t_dsk *)); For(i,n_new_disk-1) disk_new[i] = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu); if(xtra_dsk != NULL) disk_new[n_new_disk-1] = xtra_dsk; else disk_new[n_new_disk-1] = PHYREX_Make_Disk_Event(mmod->n_dim,tree->n_otu); For(i,n_new_disk) PHYREX_Init_Disk_Event(disk_new[i],mmod->n_dim,mmod); /* Times of these new disks. If xtra_dsk != NULL, then make sure you do not */ /* reset the time of that disk */ n = (xtra_dsk != NULL) ? (n_new_disk-1) : (n_new_disk); For(i,n) disk_new[i]->time = Uni()*(y_ldsk->disk->time - o_ldsk->disk->time) + o_ldsk->disk->time; /* Insert these events */ For(i,n_new_disk) { assert(!tree->disk->next); disk = tree->disk; while(disk->time > disk_new[i]->time) disk = disk->prev; PHYREX_Insert_Disk(disk_new[i],tree); } /* For(i,n_new_disk) */ /* { */ /* printf("\n> disk_new: %f [%s]",disk_new[i]->time,disk_new[i]->id); fflush(NULL); */ /* } */ /* Add new lindisks to the new disk events */ For(i,n_new_disk) { disk_new[i]->ldsk = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim); PHYREX_Init_Lindisk_Node(disk_new[i]->ldsk,disk_new[i],tree->mmod->n_dim); PHYREX_Make_Lindisk_Next(disk_new[i]->ldsk); /* printf("\n# Add ldsk %s to %s",disk_new[i]->ldsk->coord->id,disk_new[i]->id); fflush(NULL); */ } /* Connect them */ PHYREX_Connect_Ldsk_Given_Disk(disk_new,n_new_disk,y_ldsk,o_ldsk,dir_o_y); Free(disk_new); } else { o_ldsk->next[dir_o_y] = y_ldsk; y_ldsk->prev = o_ldsk; } /* Generate a trajectory */ PHYREX_One_New_Traj_Given_Disk(y_ldsk,o_ldsk,tree); return(n_new_disk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Generate a new trajectory, including disk event centers, between 'y_ldsk' a ``young'' lindisk event and 'o_ldsk' an old one. 'y_ldsk and 'o_ldsk' remain unaffected. Disk events between these two ldsk should already be set. */ void PHYREX_One_New_Traj_Given_Disk(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree) { int n_disk_btw; t_ldsk *ldsk; phydbl min, max; phydbl *min_disk_coord, *max_disk_coord; int i,k; phydbl rad; /* Number of disks between y_ldsk and o_ldsk */ ldsk = y_ldsk; n_disk_btw = 0; while(ldsk->prev != o_ldsk) { n_disk_btw++; ldsk = ldsk->prev; } if(n_disk_btw == 0) return; ldsk = y_ldsk; rad = ldsk->disk->mmod->rad; k = 0; while(ldsk != o_ldsk) { if(!ldsk->disk->next) /* Don't change location at tip node */ { ldsk = ldsk->prev; continue; } PHYREX_Store_Geo_Coord(ldsk->coord); PHYREX_Store_Geo_Coord(ldsk->disk->centr); For(i,tree->mmod->n_dim) { min = MAX(0.0, MAX(ldsk->coord->lonlat[i] - 2.*rad, o_ldsk->disk->centr->lonlat[i] - rad*(2.*(n_disk_btw-k)-1.))); max = MIN(ldsk->disk->mmod->lim->lonlat[i], MIN(ldsk->coord->lonlat[i] + 2.*rad, o_ldsk->disk->centr->lonlat[i] + rad*(2.*(n_disk_btw-k)-1.))); assert(!(max < min)); /* New coordinates for the lindisk */ ldsk->coord->lonlat[i] = Uni()*(max - min) + min; } /* New coordinate for the centre of the corresponding disk event */ PHYREX_Get_Min_Max_Disk_Given_Ldsk(ldsk->disk,&min_disk_coord,&max_disk_coord,tree); For(i,tree->mmod->n_dim) ldsk->disk->centr->lonlat[i] = Uni()*(max_disk_coord[i] - min_disk_coord[i]) + min_disk_coord[i]; Free(min_disk_coord); Free(max_disk_coord); ldsk = ldsk->prev; k++; } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Uniform_Path_Density(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree) { int n_disk_btw; t_ldsk *ldsk; phydbl min, max; int i,k; phydbl rad; phydbl log_dens; phydbl *min_disk_coord, *max_disk_coord; if(y_ldsk == o_ldsk) return .0; /* Number of disks between y_ldsk and o_ldsk */ ldsk = y_ldsk; n_disk_btw = 0; while(ldsk->prev != o_ldsk) { n_disk_btw++; ldsk = ldsk->prev; } if(n_disk_btw == 0) return .0; log_dens = 0.0; ldsk = y_ldsk; rad = ldsk->disk->mmod->rad; k = 0; while(ldsk != o_ldsk) { if(!ldsk->disk->next) { ldsk = ldsk->prev; continue; } For(i,ldsk->disk->mmod->n_dim) { min = MAX(0.0, MAX(ldsk->coord->lonlat[i] - 2.*rad, o_ldsk->disk->centr->lonlat[i] - rad*(2.*(n_disk_btw-k)-1.))); max = MIN(ldsk->disk->mmod->lim->lonlat[i], MIN(ldsk->coord->lonlat[i] + 2.*rad, o_ldsk->disk->centr->lonlat[i] + rad*(2.*(n_disk_btw-k)-1.))); assert(!(max < min)); log_dens -= LOG(max - min); } PHYREX_Get_Min_Max_Disk_Given_Ldsk(ldsk->disk,&min_disk_coord,&max_disk_coord,tree); For(i,tree->mmod->n_dim) log_dens -= LOG(max_disk_coord[i] - min_disk_coord[i]); Free(min_disk_coord); Free(max_disk_coord); ldsk = ldsk->prev; k++; } return(log_dens); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Return the index of the 'next' element of 'old' that should be used in order to reach 'young'. */ int PHYREX_Get_Next_Direction(t_ldsk *young, t_ldsk *old) { if(young->disk->time < old->disk->time) { PhyML_Printf("\n== young (%s) @ time %f; old (%s) @ time %f", young->coord->id,young->disk->time, old->coord->id,old->disk->time); fflush(NULL); return(-1); } assert(!(young == NULL)); if(young->prev == old) { int i; For(i,old->n_next) if(old->next[i] == young) return i; } else { return PHYREX_Get_Next_Direction(young->prev,old); } return(-1); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* void PHYREX_Update_Lindisk_List(phydbl time, t_ldsk **list, int *pos, t_dsk *disk) */ /* { */ /* t_dsk *root_dsk; */ /* *pos = 0; */ /* root_dsk = disk; */ /* while(root_dsk->prev) root_dsk = root_dsk->prev; */ /* /\* printf("\n. root_dsk: %s",root_dsk?root_dsk->id:"xx"); *\/ */ /* PHYREX_Update_Lindisk_List_Pre(root_dsk->ldsk,time,list,pos); */ /* } */ /* /\*\//////////////////////////////////////////////////////////// */ /* ////////////////////////////////////////////////////////////\*\/ */ /* void PHYREX_Update_Lindisk_List_Pre(t_ldsk *ldsk, phydbl time, t_ldsk **list, int *pos) */ /* { */ /* /\* printf("\n. time: %f pos: %d ldsk: %s disk: %s n_next: %d ldsk->disk->time: %f disk: %s", *\/ */ /* /\* time, *\/ */ /* /\* *pos, *\/ */ /* /\* ldsk ? ldsk->coord->id : "xx", *\/ */ /* /\* ldsk ? ldsk->disk->id : "zz", *\/ */ /* /\* ldsk ? ldsk->n_next : -1, *\/ */ /* /\* ldsk ? ldsk->disk->time : -1., *\/ */ /* /\* ldsk ? ldsk->disk->id : "yy"); fflush(NULL); *\/ */ /* if(ldsk == NULL) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ /* if((ldsk->prev != NULL) && (ldsk->disk->time > time) && (ldsk->prev->disk->time < time)) */ /* { */ /* list[*pos] = ldsk; */ /* *pos = *pos + 1; */ /* } */ /* else if(Are_Equal(ldsk->disk->time,time,1.E-10)) */ /* { */ /* list[*pos] = ldsk; */ /* *pos = *pos + 1; */ /* } */ /* else if(ldsk->disk->time < time) */ /* { */ /* int i; */ /* For(i,ldsk->n_next) */ /* PHYREX_Update_Lindisk_List_Pre(ldsk->next[i],time,list,pos); */ /* } */ /* else Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ /* } */ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Update_Lindisk_List(t_tree *tree) { PHYREX_Update_Lindisk_List_Pre(tree->disk->prev,tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Update_Lindisk_List_Pre(t_dsk *disk, t_tree *tree) { if(!disk) return; else { PHYREX_Update_Lindisk_List_Core(disk,tree); PHYREX_Update_Lindisk_List_Pre(disk->prev,tree); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Update_Lindisk_List_Core(t_dsk *disk, t_tree *tree) { int i; if(!disk->next) return; For(i,tree->n_otu) disk->ldsk_a[i] = NULL; disk->n_ldsk_a = 0; For(i,disk->next->n_ldsk_a) { if(disk->next->ldsk_a[i]->prev != disk->ldsk) { disk->ldsk_a[disk->n_ldsk_a] = disk->next->ldsk_a[i]; disk->n_ldsk_a++; } } if(disk->ldsk) { disk->ldsk_a[disk->n_ldsk_a] = disk->ldsk; disk->n_ldsk_a++; } /* if(disk->n_ldsk_a == 0 || disk->n_ldsk_a > tree->n_otu || (!disk->prev && disk->n_ldsk_a != 1)) */ if(disk->n_ldsk_a == 0 || disk->n_ldsk_a > tree->n_otu) { PhyML_Printf("\n== disk %s %d %s",disk->id, disk->n_ldsk_a, disk->ldsk?disk->ldsk->coord->id:"xx"); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Connect all the ldsk between y_ldsk (young ldsk) and o_ldsk (old ldsk). The disk between y_ldsk and o_ldsk should have all been set already Note: the disks in **disk are sorted in ascending order of their times */ void PHYREX_Connect_Ldsk_Given_Disk(t_dsk **disk, int n_disk, t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y) { int i,j; t_dsk *disk_tmp; /* Sort these events by ascending order of their times */ For(i,n_disk-1) { for(j=i+1;jtime > disk[i]->time) { disk_tmp = disk[i]; disk[i] = disk[j]; disk[j] = disk_tmp; } } } For(i,n_disk) { if(!i) { disk[i]->ldsk->next[0] = y_ldsk; y_ldsk->prev = disk[i]->ldsk; /* printf("\n. connect %s to %s",disk[i]->ldsk->coord->id,y_ldsk->coord->id); fflush(NULL); */ } else { disk[i]->ldsk->next[0] = disk[i-1]->ldsk; disk[i-1]->ldsk->prev = disk[i]->ldsk; /* printf("\n. connect %s to %s",disk[i]->ldsk->coord->id,disk[i-1]->ldsk->coord->id); fflush(NULL); */ } } /* printf("\n. connect %s next dir: %d [%d] to %s",o_ldsk->coord->id,dir_o_y,o_ldsk->n_next,disk[n_disk-1]->ldsk->coord->id); fflush(NULL); */ o_ldsk->next[dir_o_y] = disk[n_disk-1]->ldsk; disk[n_disk-1]->ldsk->prev = o_ldsk; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Print_Struct(char sign, t_tree *tree) { t_dsk *disk; int i,j; t_ldsk *ldisk; PHYREX_Update_Lindisk_List(tree); disk = tree->disk; while(disk->prev) disk = disk->prev; do { PhyML_Printf("\n%c Disk: %s @ %7.3f has %3s on it is_coal? %2d rad: %f coord ", sign, disk->id, disk->time,disk->ldsk?disk->ldsk->coord->id:NULL, disk->ldsk?disk->ldsk->n_next:-1, tree->mmod->rad); fflush(NULL); For(j,tree->mmod->n_dim) PhyML_Printf(" %f",disk->centr->lonlat[j]); fflush(NULL); For(i,disk->n_ldsk_a) { ldisk = disk->ldsk_a[i]; PhyML_Printf("\n%c ldisk: %s prev: %s", sign, ldisk->coord->id, ldisk->prev ? ldisk->prev->coord->id : NULL); fflush(NULL); For(j,tree->mmod->n_dim) { PhyML_Printf(" %f",ldisk->coord->lonlat[j]); fflush(NULL); if(FABS(ldisk->coord->lonlat[j] - ldisk->disk->centr->lonlat[j]) > 2.*tree->mmod->rad && ldisk->disk->ldsk == ldisk) PhyML_Printf(" ! "); if(ldisk->prev) { if(ldisk->coord->lonlat[j] < ldisk->prev->disk->centr->lonlat[j] - tree->mmod->rad) PhyML_Printf(" #a "); if(ldisk->coord->lonlat[j] > ldisk->prev->disk->centr->lonlat[j] + tree->mmod->rad) PhyML_Printf(" #b "); } if(ldisk->next) { if(ldisk->coord->lonlat[j] < ldisk->disk->centr->lonlat[j] - tree->mmod->rad) PhyML_Printf(" $a "); if(ldisk->coord->lonlat[j] > ldisk->disk->centr->lonlat[j] + tree->mmod->rad) PhyML_Printf(" $b "); } } } fflush(NULL); disk = disk->next; } while(disk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Check_Struct(t_tree *tree) { t_dsk *disk; int i,j; t_ldsk *ldisk; disk = tree->disk; while(disk->prev) disk = disk->prev; do { /* PHYREX_Update_Lindisk_List(disk->time,disk->ldsk_a,&(disk->n_ldsk_a),disk); */ PHYREX_Update_Lindisk_List(tree); For(i,disk->n_ldsk_a) { ldisk = disk->ldsk_a[i]; if(ldisk->prev != NULL) { For(j,tree->mmod->n_dim) { if(FABS(ldisk->coord->lonlat[j] - ldisk->prev->coord->lonlat[j]) > 2.*tree->mmod->rad) { PHYREX_Print_Struct('=',tree); PhyML_Printf("\n== %f %f %f", ldisk->coord->lonlat[j], ldisk->prev->coord->lonlat[j], 2.*tree->mmod->rad); PhyML_Printf("\n== Radius: %f",tree->mmod->rad); PhyML_Printf("\n== Check ldsk %s",ldisk->coord->id); PhyML_Printf("\n== Centr: %f",ldisk->prev->disk->centr->lonlat[j]); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } } } disk = disk->next; } while(disk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Store_Geo_Coord(t_geo_coord *t) { int i; For(i,t->dim) t->cpy->lonlat[i] = t->lonlat[i]; t->cpy->dim = t->dim; strcpy(t->cpy->id,t->id); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Restore_Geo_Coord(t_geo_coord *t) { int i; For(i,t->dim) t->lonlat[i] = t->cpy->lonlat[i]; t->dim = t->cpy->dim; strcpy(t->id,t->cpy->id); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Total_Number_Of_Intervals(t_tree *tree) { t_dsk *disk; int n_intervals; assert(!(tree->disk->next)); disk = tree->disk; n_intervals = 0; while(disk->prev) { n_intervals++; disk = disk->prev; } return(n_intervals); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Total_Number_Of_Hit_Disks(t_tree *tree) { t_dsk *disk; int n_hit_disks; assert(!(tree->disk->next)); disk = tree->disk; n_hit_disks = 0; while(disk) { if(disk->ldsk) n_hit_disks++; disk = disk->prev; } return(n_hit_disks); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Total_Number_Of_Coal_Disks(t_tree *tree) { t_dsk *disk; int n_coal_disks; assert(!(tree->disk->next)); disk = tree->disk; n_coal_disks = 0; while(disk) { if(disk->ldsk && disk->ldsk->n_next > 1) n_coal_disks++; disk = disk->prev; } return(n_coal_disks); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Log_Dunif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mmod) { phydbl up, down, left, rght; phydbl log_dens; /* phydbl main_mass,l; */ log_dens = 0.0; /* main_mass = 1. - mmod->soft_bound_area; */ up = MIN(disk->centr->lonlat[0] + mmod->rad, mmod->lim->lonlat[0]); down = MAX(disk->centr->lonlat[0] - mmod->rad, 0.0); rght = MIN(disk->centr->lonlat[1] + mmod->rad, mmod->lim->lonlat[1]); left = MAX(disk->centr->lonlat[1] - mmod->rad, 0.0); /* l = main_mass / (.5*(1.-main_mass)*(up - down)); */ /* if(ldsk->coord->lonlat[0] < down) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(down - ldsk->coord->lonlat[0]); */ /* else if(ldsk->coord->lonlat[0] > up) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(ldsk->coord->lonlat[0] - up); */ /* else log_dens += LOG(main_mass) - LOG(up - down); */ /* l = main_mass / (.5*(1.-main_mass)*(rght - left)); */ /* if(ldsk->coord->lonlat[1] < left) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(left - ldsk->coord->lonlat[1]); */ /* else if(ldsk->coord->lonlat[1] > rght) log_dens += LOG(.5*(1.-main_mass)) + LOG(l) - l*(ldsk->coord->lonlat[1] - rght); */ /* else log_dens += LOG(main_mass) - LOG(rght - left); */ if(ldsk->coord->lonlat[0] < down) return UNLIKELY; if(ldsk->coord->lonlat[0] > up) return UNLIKELY; if(ldsk->coord->lonlat[1] < left) return UNLIKELY; if(ldsk->coord->lonlat[1] > rght) return UNLIKELY; log_dens = -LOG(up-down)-LOG(rght-left); return(log_dens); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Samples uniformly within a rectangle (with truncation for border) */ /* and returns the corresponding log density */ phydbl PHYREX_Runif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mmod) { phydbl up, down, left, rght; up = MIN(disk->centr->lonlat[0] + mmod->rad, mmod->lim->lonlat[0]); down = MAX(disk->centr->lonlat[0] - mmod->rad, 0.0); rght = MIN(disk->centr->lonlat[1] + mmod->rad, mmod->lim->lonlat[1]); left = MAX(disk->centr->lonlat[1] - mmod->rad, 0.0); ldsk->coord->lonlat[0] = Uni()*(up - down) + down; ldsk->coord->lonlat[1] = Uni()*(rght - left) + left; /* printf("\n. disk %s (%f %f) rad: %f up: %f down: %f rght: %f left: %f", */ /* disk->id, */ /* disk->centr->lonlat[0], */ /* disk->centr->lonlat[1], */ /* mmod->rad, */ /* up,down,rght,left); */ return(LOG(up-down)+LOG(rght-left)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Rnorm_Trunc(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mmod) { phydbl up, down, left, rght; int err; up = mmod->lim->lonlat[0]; down = 0.0; rght = mmod->lim->lonlat[1]; left = 0.0; err = NO; ldsk->coord->lonlat[0] = Rnorm_Trunc(disk->centr->lonlat[0],mmod->rad,down,up,&err); ldsk->coord->lonlat[1] = Rnorm_Trunc(disk->centr->lonlat[1],mmod->rad,left,rght,&err); return(0.0); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Wrap_Prior_Radius(t_edge *e, t_tree *tree, supert_tree *st) { return PHYREX_LnPrior_Radius(tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_LnPrior_Lbda(t_tree *tree) { if(tree->mmod->lbda < tree->mmod->min_lbda) return UNLIKELY; if(tree->mmod->lbda > tree->mmod->max_lbda) return UNLIKELY; /* tree->mmod->c_ln_prior_lbda = */ /* LOG(tree->mmod->prior_param_lbda) - */ /* tree->mmod->prior_param_lbda*tree->mmod->lbda; */ /* tree->mmod->c_ln_prior_lbda -= LOG(EXP(-tree->mmod->prior_param_lbda*tree->mmod->min_lbda)- */ /* EXP(-tree->mmod->prior_param_lbda*tree->mmod->max_lbda)); */ tree->mmod->c_ln_prior_lbda = -LOG(tree->mmod->max_lbda - tree->mmod->min_lbda);; return(tree->mmod->c_ln_prior_lbda); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_LnPrior_Mu(t_tree *tree) { if(tree->mmod->mu < tree->mmod->min_mu) return UNLIKELY; if(tree->mmod->mu > tree->mmod->max_mu) return UNLIKELY; tree->mmod->c_ln_prior_mu = -LOG(tree->mmod->max_mu - tree->mmod->min_mu); /* tree->mmod->c_ln_prior_mu = -2.*LOG(tree->mmod->mu); */ return(tree->mmod->c_ln_prior_mu); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_LnPrior_Radius(t_tree *tree) { if(tree->mmod->rad < tree->mmod->min_rad) return UNLIKELY; if(tree->mmod->rad > tree->mmod->max_rad) return UNLIKELY; /* tree->mmod->c_ln_prior_rad = */ /* LOG(tree->mmod->prior_param_rad) - */ /* tree->mmod->prior_param_rad*tree->mmod->rad; */ /* tree->mmod->c_ln_prior_rad -= LOG(EXP(-tree->mmod->prior_param_lbda*tree->mmod->min_rad)- */ /* EXP(-tree->mmod->prior_param_lbda*tree->mmod->max_rad)); */ tree->mmod->c_ln_prior_rad = -LOG(tree->mmod->max_rad - tree->mmod->min_rad); return(tree->mmod->c_ln_prior_rad); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_LnPrior_Sigsq(t_tree *tree) { tree->mmod->c_ln_prior_sigsq = LOG(tree->mmod->prior_param_sigsq) - tree->mmod->prior_param_sigsq*tree->mmod->sigsq; return(tree->mmod->c_ln_prior_sigsq); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Initial_Ldsk_Pos(t_tree *tree) { t_dsk *disk; int i,j; phydbl mean; disk = tree->disk->prev; do { if(disk->ldsk) { For(i,tree->mmod->n_dim) { mean = 0.0; For(j,disk->ldsk->n_next) mean += disk->ldsk->next[j]->coord->lonlat[i]; disk->ldsk->coord->lonlat[i] = mean / (phydbl)disk->ldsk->n_next; } } disk = disk->prev; } while(disk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Min_Radius(t_tree *tree) { phydbl ori_rad, min_rad; ori_rad = tree->mmod->rad; tree->mmod->rad = tree->mmod->max_rad; do { PHYREX_Lk(tree); tree->mmod->rad -= 1.0; } while(tree->mmod->c_lnL > UNLIKELY + 0.1); min_rad = tree->mmod->rad + 2.0; tree->mmod->rad = ori_rad; PHYREX_Lk(tree); return(min_rad); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Get the minimum and maximum values a ldsk can take, given the position of the disk centre */ void PHYREX_Get_Min_Max_Ldsk_Given_Disk(t_ldsk *ldsk, phydbl **min, phydbl **max, t_tree *tree) { phydbl *loc_min,*loc_max; int i; if(!ldsk->disk->next) return; loc_min = (phydbl *)mCalloc(tree->mmod->n_dim, sizeof(phydbl)); loc_max = (phydbl *)mCalloc(tree->mmod->n_dim, sizeof(phydbl)); For(i,tree->mmod->n_dim) { loc_min[i] = ldsk->disk->centr->lonlat[i] - tree->mmod->rad; loc_max[i] = ldsk->disk->centr->lonlat[i] + tree->mmod->rad; if(ldsk->prev) { loc_min[i] = MAX(loc_min[i],ldsk->prev->disk->centr->lonlat[i] - tree->mmod->rad); loc_max[i] = MIN(loc_max[i],ldsk->prev->disk->centr->lonlat[i] + tree->mmod->rad); } loc_min[i] = MAX(0.0,loc_min[i]); loc_max[i] = MIN(tree->mmod->lim->lonlat[i],loc_max[i]); } (*min) = loc_min; (*max) = loc_max; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Get the minimum and maximum values a disk centre can take, given the position of the ldsk */ void PHYREX_Get_Min_Max_Disk_Given_Ldsk(t_dsk *disk, phydbl **min, phydbl **max, t_tree *tree) { phydbl *loc_min,*loc_max; int i,j; phydbl tmp_min, tmp_max; if(!disk->next) return; loc_min = (phydbl *)mCalloc(tree->mmod->n_dim,sizeof(phydbl)); loc_max = (phydbl *)mCalloc(tree->mmod->n_dim,sizeof(phydbl)); if(!disk->ldsk || tree->mmod->name == PHYREX_NORMAL) { For(i,tree->mmod->n_dim) { loc_min[i] = 0.0; loc_max[i] = tree->mmod->lim->lonlat[i]; } } else { For(i,tree->mmod->n_dim) { tmp_min = +INFINITY; tmp_max = -INFINITY; For(j,disk->ldsk->n_next) { if(disk->ldsk->next[j]->coord->lonlat[i] < tmp_min) tmp_min = disk->ldsk->next[j]->coord->lonlat[i]; if(disk->ldsk->next[j]->coord->lonlat[i] > tmp_max) tmp_max = disk->ldsk->next[j]->coord->lonlat[i]; } if(disk->ldsk->coord->lonlat[i] < tmp_min) tmp_min = disk->ldsk->coord->lonlat[i]; if(disk->ldsk->coord->lonlat[i] > tmp_max) tmp_max = disk->ldsk->coord->lonlat[i]; loc_min[i] = MAX(0.0, tmp_max - tree->mmod->rad); loc_max[i] = MIN(tree->mmod->lim->lonlat[i], tmp_min + tree->mmod->rad); assert(!(loc_max[i] < loc_min[i])); } } (*min) = loc_min; (*max) = loc_max; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Update_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree) { int i; For(i,root_ldsk->n_next) PHYREX_Update_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Update_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_ldsk *root_ldsk, t_tree *tree) { if(!young_ldsk->disk->next) { PHYREX_One_New_Traj_Given_Disk(young_ldsk,root_ldsk,tree); return; } else { int i; PHYREX_Update_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[0],root_ldsk,tree); if(young_ldsk->n_next > 1) { for(i=1;in_next;i++) PHYREX_Update_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[i],young_ldsk,tree); } } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Restore_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree) { int i; For(i,root_ldsk->n_next) PHYREX_Restore_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Restore_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_tree *tree) { if(!young_ldsk->disk->next) return; else { int i; PHYREX_Restore_Geo_Coord(young_ldsk->coord); PHYREX_Restore_Geo_Coord(young_ldsk->disk->centr); For(i,young_ldsk->n_next) { PHYREX_Restore_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[i],tree); } } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Proposal_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, phydbl *logdens, t_tree *tree) { int i; (*logdens) = 0.0; For(i,root_ldsk->n_next) PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(root_ldsk,root_ldsk->next[i],root_ldsk,logdens,tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_ldsk *root_ldsk, phydbl *logdens, t_tree *tree) { if(!young_ldsk->disk->next) { (*logdens) += PHYREX_Uniform_Path_Density(young_ldsk,root_ldsk,tree); return; } else { int i; For(i,young_ldsk->n_next) { PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(young_ldsk,young_ldsk->next[i],root_ldsk,logdens,tree); } } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Update the tree structure given the whole set of ldsk events */ /* Coalescent events involving multiple lineages are resolved using */ /* very short internal edges */ void PHYREX_Ldsk_To_Tree(t_tree *tree) { int i,j; t_dsk *disk; /* Reset */ For(i,2*tree->n_otu-1) { For(j,3) { tree->a_nodes[i]->v[j] = NULL; tree->a_nodes[i]->b[j] = NULL; } } disk = tree->disk->prev; while(disk) { if(disk->ldsk) disk->ldsk->nd = NULL; disk = disk->prev; } /* Connect tips */ For(i,tree->n_otu) { tree->disk->ldsk_a[i]->nd = tree->a_nodes[i]; tree->a_nodes[i]->coord = tree->disk->ldsk_a[i]->coord; } disk = tree->disk; while(disk->prev) disk = disk->prev; tree->n_root = tree->a_nodes[2*tree->n_otu-2]; i = 2*tree->n_otu-3; tree->num_curr_branch_available = 0; PHYREX_Ldsk_To_Tree_Post(tree->n_root,disk->ldsk,&i,tree); For(i,tree->n_otu) assert(!(tree->a_nodes[i]->v[0] == NULL)); For(i,3) if(tree->n_root->v[2]->v[i] == tree->n_root) { tree->n_root->v[2]->v[i] = tree->n_root->v[1]; break; } For(i,3) if(tree->n_root->v[1]->v[i] == tree->n_root) { tree->n_root->v[1]->v[i] = tree->n_root->v[2]; break; } Connect_Edges_To_Nodes_Serial(tree); /* tree->num_curr_branch_available = 0; */ /* Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */ tree->e_root = NULL; For(i,2*tree->n_otu-3) { /* printf("\n %d %d",tree->a_edges[i]->left->num,tree->a_edges[i]->rght->num); */ if((tree->a_edges[i]->left == tree->n_root->v[1] && tree->a_edges[i]->rght == tree->n_root->v[2]) || (tree->a_edges[i]->left == tree->n_root->v[2] && tree->a_edges[i]->rght == tree->n_root->v[1])) { tree->e_root = tree->a_edges[i]; break; } } assert(!(tree->e_root == NULL)); tree->n_root->b[1] = tree->a_edges[2*tree->n_otu-3]; tree->n_root->b[2] = tree->a_edges[2*tree->n_otu-2]; /* For(i,2*tree->n_otu-1) */ /* { */ /* printf("\n. * Edge %d %p", */ /* tree->a_edges[i]->num, */ /* tree->a_edges[i]); */ /* } */ /* PhyML_Printf("\n. tree->n_root->b[1]: %p",tree->n_root->b[1]); */ /* PhyML_Printf("\n. tree->n_root->b[2]: %p",tree->n_root->b[2]); */ /* fflush(NULL); */ /* Exit("\n"); */ } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *tree) { assert(!(ldsk == NULL)); assert(!(a == NULL)); ldsk->nd = a; tree->rates->nd_t[a->num] = ldsk->disk->time; a->coord = ldsk->coord; if(!ldsk->next) return; else { t_node *parent,*son; int n_next; t_ldsk *t; parent = a; parent->v[1] = NULL; parent->v[2] = NULL; n_next = 0; do { t = ldsk->next[n_next]; /* if(t == NULL) */ /* { */ /* PhyML_Printf("\n. ldsk:%p ldsk->next:%p n_next:%d", */ /* ldsk,ldsk?ldsk->next:NULL,n_next); */ /* Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ /* } */ while(t->next && t->n_next == 1) t = t->next[0]; if(t->nd == NULL) { son = tree->a_nodes[*available]; (*available) = (*available)-1; } else { son = t->nd; } PHYREX_Ldsk_To_Tree_Post(son,t,available,tree); if(parent->v[2] != NULL && n_next >= 2) { t_node *new_parent; /* phydbl orig_l2; */ new_parent = tree->a_nodes[*available]; (*available) = (*available)-1; new_parent->v[0] = parent; new_parent->v[1] = parent->v[2]; new_parent->v[2] = son; parent->v[2] = new_parent; son->v[0] = new_parent; new_parent->v[1]->v[0] = new_parent; /* printf("\n# connect %d to %d",parent->num,new_parent->num); */ /* printf("\n# connect %d to %d",new_parent->num,new_parent->v[1]->num); */ /* printf("\n# connect %d to %d",new_parent->num,new_parent->v[2]->num); */ /* fflush(NULL); */ tree->rates->nd_t[new_parent->num] = ldsk->disk->time; parent = new_parent; } else { son->v[0] = parent; if(!parent->v[1]) parent->v[1] = son; else parent->v[2] = son; /* printf("\n. connect %d to %d",parent->num,son->num); */ } n_next++; } while(n_next != ldsk->n_next); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Remove_Lindisk_Next(t_ldsk *ldsk, t_ldsk *rm) { t_ldsk **new_next; int i,pos; new_next = (t_ldsk **)mCalloc(ldsk->n_next-1+NEXT_BLOCK_SIZE,sizeof(t_ldsk *)); pos = 0; For(i,ldsk->n_next) { if(ldsk->next[i] != rm) { new_next[pos] = ldsk->next[i]; pos++; } } ldsk->n_next--; Free(ldsk->next); ldsk->next = new_next; /* printf("\n. remove next for ldsk %s n_next set to %d",ldsk->coord->id,ldsk->n_next); */ /* fflush(NULL); */ } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Returns the vector of average pairwise distances between ldsk on each disk */ phydbl *PHYREX_Mean_Pairwise_Distance_Between_Lineage_Locations(t_tree *tree) { phydbl *dist; int block,n_disks,i,j, k; t_dsk *disk; PHYREX_Update_Lindisk_List(tree); dist = NULL; block = 100; disk = tree->disk; n_disks = 0; do { if(!n_disks) dist = (phydbl *)mCalloc(block,sizeof(phydbl)); else if(!(n_disks%block)) dist = (phydbl *)mRealloc(dist,n_disks+block,sizeof(phydbl)); dist[n_disks] = 0.0; For(i,disk->n_ldsk_a-1) { for(j=i+1;jn_ldsk_a;j++) { For(k,tree->mmod->n_dim) { dist[n_disks] += FABS(disk->ldsk_a[i]->coord->lonlat[k] - disk->ldsk_a[j]->coord->lonlat[k]); printf("\n * %d %f %f %f", k, disk->ldsk_a[i]->coord->lonlat[k], disk->ldsk_a[j]->coord->lonlat[k], tree->mmod->lim->lonlat[k]); } } } dist[n_disks] /= (phydbl)(disk->n_ldsk_a * (disk->n_ldsk_a-1) / 2.); printf("\n %d %f %f",disk->n_ldsk_a,disk->time,dist[n_disks]); n_disks++; disk = disk->prev; } while(disk->prev); return(dist); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Random_Select_Time_Between_Jumps(t_tree *tree) { t_dsk *disk,**valid_disks; int n_valid_disks,block,select; phydbl time; valid_disks = NULL; disk = NULL; block = 100; assert(!(tree->disk->next)); disk = tree->disk->prev; n_valid_disks = 0; do { if(disk->ldsk != NULL && disk->prev != NULL) { if(!n_valid_disks) valid_disks = (t_dsk **)mCalloc(block,sizeof(t_dsk *)); else if(!(n_valid_disks%block)) valid_disks = (t_dsk **)mRealloc(valid_disks,n_valid_disks+block,sizeof(t_dsk *)); valid_disks[n_valid_disks] = disk; n_valid_disks++; } disk = disk->prev; } while(disk->prev); if(!n_valid_disks) return -1.0; select = Rand_Int(0,n_valid_disks-1); time = valid_disks[select]->time - valid_disks[select]->ldsk->prev->disk->time; Free(valid_disks); return(time); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Is_In_Ldscape(t_ldsk *ldsk, t_phyrex_mod *mmod) { int j; For(j,mmod->n_dim) if(ldsk->coord->lonlat[j] > mmod->lim->lonlat[j] || ldsk->coord->lonlat[j] < 0.0) return NO; return YES; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Mean_Time_Between_Events(t_tree *tree) { int n_inter; phydbl T; n_inter = PHYREX_Total_Number_Of_Intervals(tree); T = -tree->rates->nd_t[tree->n_root->num]; return((phydbl)(T/n_inter)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Uses the regression technique described in Barton et al. TPB (2013) to estimate the size of the neighborhood when the population evolve according to a spatial Lambda-Fleming-Viot process. */ phydbl PHYREX_Neighborhood_Size_Regression(t_tree *tree) { int i,j,pair; t_node *anc; phydbl *dist,min_dist; phydbl QA,Qr,*fst,fst0,fst_min_dist; phydbl cov_fst_dist,var_dist,slope; phydbl eps; eps = 1.E-10; QA = Mean_Identity(tree->data); fst = (phydbl *)mCalloc(tree->n_otu*(tree->n_otu-1)/2,sizeof(phydbl)); dist = (phydbl *)mCalloc(tree->n_otu*(tree->n_otu-1)/2,sizeof(phydbl)); pair = 0; fst0 = 0.0; For(i,tree->n_otu-1) { fst_min_dist = 0.0; min_dist = MDBL_MAX; for(j=i+1;jn_otu;j++) { anc = Find_Lca_Pair_Of_Nodes(tree->a_nodes[i],tree->a_nodes[j],tree); if(anc == NULL) { PhyML_Printf("\n. %s",Write_Tree(tree,NO)); PhyML_Printf("\n. %s %s",tree->a_nodes[i]->name,tree->a_nodes[j]->name); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } dist[pair] = Euclidean_Dist(tree->a_nodes[i]->coord,tree->a_nodes[j]->coord); dist[pair] = LOG(dist[pair]); Qr = Pairwise_Identity(i,j,tree->data); fst[pair] = (Qr-QA)/(1.-QA); if(dist[pair] < min_dist) { min_dist = dist[pair]; fst_min_dist = fst[pair]; } pair++; } fst0 += fst_min_dist; } fst0 /= (phydbl)(tree->n_otu); cov_fst_dist = Covariance(dist,fst,pair); var_dist = Variance(dist,pair); slope = cov_fst_dist / var_dist; Free(dist); Free(fst); return((fst0-1.+eps)/(slope+eps)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Rand_Pairs_Coal_Times_Dist(t_tree *tree) { t_node *anc; phydbl dist; int i, j; i = Rand_Int(0,tree->n_otu-1); j = Rand_Int(0,tree->n_otu-1); if(i == j) PhyML_Printf("\nxxWxx 0.0 0.0"); else { anc = Find_Lca_Pair_Of_Nodes(tree->a_nodes[i],tree->a_nodes[j],tree); if(anc == NULL) { PhyML_Printf("\n. %s",Write_Tree(tree,NO)); PhyML_Printf("\n. %s %s",tree->a_nodes[i]->name,tree->a_nodes[j]->name); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } PhyML_Printf("\nxxWxx %12f",tree->rates->nd_t[anc->num]); dist = Euclidean_Dist(tree->a_nodes[i]->coord,tree->a_nodes[j]->coord); PhyML_Printf(" %f",dist); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Generation_Length(t_tree *tree) { return(1./(2.*tree->mmod->mu*POW(tree->mmod->rad,2)*PI*PHYREX_Rate_Per_Unit_Area(tree))); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Neighborhood_Size(t_tree *tree) { switch(tree->mmod->name) { case PHYREX_UNIFORM: { return(1./tree->mmod->mu); break; } case PHYREX_NORMAL: { return(2./tree->mmod->mu); break; } } return(-1.); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Update_Sigsq(t_tree *tree) { switch(tree->mmod->name) { case PHYREX_UNIFORM: { return(-1.0); break;} case PHYREX_NORMAL: { return(4.*PI* PHYREX_Rate_Per_Unit_Area(tree) * POW(tree->mmod->rad,4)* tree->mmod->mu); break; } } return(-1.); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Update_Radius(t_tree *tree) { switch(tree->mmod->name) { case PHYREX_UNIFORM: { return(-1.0); break;} case PHYREX_NORMAL: { return(POW(tree->mmod->sigsq/(PHYREX_Rate_Per_Unit_Area(tree)*4.*PI*tree->mmod->mu),0.25)); break; } } return(-1.); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Sample_Rad_From_Prior(t_tree *tree) { phydbl u,h,w,lbda,mu,b,a; h = tree->mmod->lim->lonlat[0]; w = tree->mmod->lim->lonlat[1]; lbda = tree->mmod->lbda; mu = tree->mmod->mu; a = tree->mmod->min_sigsq; b = tree->mmod->max_sigsq; u = Uni(); return(POW(((b-a)*u+a)*h*w/(4.*PI*lbda*mu),0.25)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree) { char *s; FILE *fp; int i,*done,found_sw,found_ne; phydbl sw_lon, sw_lat, ne_lon, ne_lat; s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); fp = tree->io->fp_in_coord; done = (int *)mCalloc(tree->n_otu,sizeof(int)); found_sw = NO; found_ne = NO; For(i,tree->n_otu) done[i] = NO; do { if(fscanf(fp,"%s",s) == EOF) break; For(i,strlen(s)) if(s[i] == '#') break; /* skip comment */ if(i != strlen(s)) continue; For(i,tree->n_otu) if(strstr(tree->a_nodes[i]->name,s)) break; if(i != tree->n_otu) /* Found a match */ { if(fscanf(fp,"%lf",&(ldsk_a[i]->coord->lonlat[0])) == EOF) break; if(fscanf(fp,"%lf",&(ldsk_a[i]->coord->lonlat[1])) == EOF) break; done[i] = YES; } else { if(!strcmp(s,"|SouthWest|") || !strcmp(s,"|southwest|") || !strcmp(s,"|Southwest|")) { found_sw = YES; if(fscanf(fp,"%lf",&(sw_lon)) == EOF) break; if(fscanf(fp,"%lf",&(sw_lat)) == EOF) break; } else if(!strcmp(s,"|NorthEast|") || !strcmp(s,"|northeast|") || !strcmp(s,"|Northeast|")) { found_ne = YES; if(fscanf(fp,"%lf",&(ne_lon)) == EOF) break; if(fscanf(fp,"%lf",&(ne_lat)) == EOF) break; } } } while(1); if(found_ne == NO) { PhyML_Printf("\n== Could not find coordinates for northernmost point."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } if(found_sw == NO) { PhyML_Printf("\n== Could not find coordinates for southernmost point."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } For(i,tree->n_otu) if(done[i] == NO) { PhyML_Printf("\n== Could not find coordinates for '%s'.",tree->a_nodes[i]->name); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } For(i,tree->n_otu) { ldsk_a[i]->coord->lonlat[0] -= sw_lon; ldsk_a[i]->coord->lonlat[1] -= sw_lat; ldsk_a[i]->coord->lonlat[0] /= (ne_lon - sw_lon); ldsk_a[i]->coord->lonlat[1] /= (ne_lat - sw_lat); ldsk_a[i]->coord->lonlat[0] *= tree->mmod->lim->lonlat[0]; ldsk_a[i]->coord->lonlat[1] *= tree->mmod->lim->lonlat[1]; PhyML_Printf("\n. Scaled coordinates of '%-50s': %12f\t %12f", tree->a_nodes[i]->name, ldsk_a[i]->coord->lonlat[0], ldsk_a[i]->coord->lonlat[1]); } Free(s); Free(done); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Rate_Per_Unit_Area(t_tree *tree) { int i; phydbl denom; denom = tree->mmod->lim->lonlat[0]; for(i=1;immod->n_dim;i++) denom *= tree->mmod->lim->lonlat[i]; return(tree->mmod->lbda / denom); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Tree_Height(t_tree *tree) { t_dsk *disk; disk = tree->disk; while(disk && disk->prev) disk = disk->prev; return(disk->time); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Random_Insert_Ldsk_In_Next_List(t_ldsk *ins, t_ldsk *where) { int size, pos, i, *rk; t_ldsk **next_cpy; size = where->n_next; rk = (int *)mCalloc(size,sizeof(int)); next_cpy = (t_ldsk **)mCalloc(size,sizeof(t_ldsk *)); For(i,size) next_cpy[i] = where->next[i]; pos = Rand_Int(0,size); For(i,size) { if(i < pos) rk[i] = i; else rk[i] = i+1; } PHYREX_Make_Lindisk_Next(where); For(i,size) where->next[rk[i]] = next_cpy[i]; where->next[pos]= ins; Free(rk); Free(next_cpy); return pos; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Insert_Ldsk_In_Next_List(t_ldsk *ins, int pos, t_ldsk *where) { int size, i, *rk; t_ldsk **next_cpy; size = where->n_next; rk = (int *)mCalloc(size,sizeof(int)); next_cpy = (t_ldsk **)mCalloc(size,sizeof(t_ldsk *)); For(i,size) next_cpy[i] = where->next[i]; For(i,size) { if(i < pos) rk[i] = i; else rk[i] = i+1; } PHYREX_Make_Lindisk_Next(where); For(i,size) where->next[rk[i]] = next_cpy[i]; where->next[pos]= ins; Free(rk); Free(next_cpy); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ t_ldsk *PHYREX_Remove_Path(t_ldsk *beg, t_ldsk *end, int *pos_end, t_tree *tree) { t_ldsk *ldsk; int dir_end_beg; dir_end_beg = PHYREX_Get_Next_Direction(beg,end); *pos_end = dir_end_beg; PHYREX_Remove_Lindisk_Next(end,end->next[dir_end_beg]); if(beg->prev == end) return NULL; /* PhyML_Printf("\n- rm beg: %12f %12f %12f %s", */ /* beg->coord->lonlat[0],beg->coord->lonlat[1],beg->disk->time, */ /* beg->coord->id); */ /* PhyML_Printf("\n- rm end: %12f %12f %12f %s", */ /* end->coord->lonlat[0],end->coord->lonlat[1],end->disk->time, */ /* end->coord->id); */ ldsk = beg->prev; while(1) { PHYREX_Remove_Disk(ldsk->disk); /* PhyML_Printf("\n- rm %12f %12f %s",ldsk->coord->lonlat[0],ldsk->coord->lonlat[1],ldsk->coord->id); */ if(ldsk->prev == end) break; ldsk = ldsk->prev; } ldsk->prev = NULL; ldsk = beg->prev; beg->prev = NULL; return(ldsk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Insert_Path(t_ldsk *beg, t_ldsk *end, t_ldsk *path, int pos, t_tree *tree) { t_ldsk *ldsk; assert(!(path == beg || path == end)); if(path == NULL) { beg->prev = end; /* printf("\n. in (beg-end) %12f %12f %12f %12f %s %s", */ /* beg->coord->lonlat[0], */ /* beg->coord->lonlat[1], */ /* end->coord->lonlat[0], */ /* end->coord->lonlat[1], */ /* beg->coord->id,end->coord->id); */ /* PHYREX_Insert_Ldsk_In_Next_List(beg,end->n_next,end); */ PHYREX_Insert_Ldsk_In_Next_List(beg,pos,end); } else { /* printf("\n. in beg %12f %12f %12f %s", */ /* beg->coord->lonlat[0], */ /* beg->coord->lonlat[1], */ /* beg->disk->time, */ /* beg->coord->id); */ /* printf("\n. in end %12f %12f %12f %s", */ /* end->coord->lonlat[0], */ /* end->coord->lonlat[1], */ /* end->disk->time, */ /* end->coord->id); */ ldsk = path; while(1) { PHYREX_Insert_Disk(ldsk->disk,tree); /* printf("\n+ in %12f %12f %12f %s", */ /* ldsk->coord->lonlat[0], */ /* ldsk->coord->lonlat[1], */ /* ldsk->disk->time, */ /* ldsk->coord->id); */ if(ldsk->prev == NULL) break; ldsk = ldsk->prev; } beg->prev = path; ldsk->prev = end; path->next[0] = beg; /* PHYREX_Insert_Ldsk_In_Next_List(ldsk,end->n_next,end); */ PHYREX_Insert_Ldsk_In_Next_List(ldsk,pos,end); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Effective_Density(t_tree *tree) { return(PHYREX_Neighborhood_Size(tree)/(4.*PI*PHYREX_Update_Sigsq(tree))); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl sd, t_tree *tree) { int n_evt,i,j,swap,err; phydbl dt,*time,dum,mode; t_ldsk *path,**ldsk_a; t_dsk *disk; dt = FABS(beg->disk->time - end->disk->time); /* How many hit events ? */ if(cur_n_evt < .0) /* Not sure that rate is ok when considering landscape with boundaries... */ n_evt = Rpois(dt*2.*PHYREX_Rate_Per_Unit_Area(tree)*PI*POW(sd,2)*tree->mmod->mu); else n_evt = Rpois(cur_n_evt); if(n_evt <= 0) return(NULL); time = (phydbl *)mCalloc(n_evt,sizeof(phydbl)); ldsk_a = (t_ldsk **)mCalloc(n_evt,sizeof(t_ldsk *)); For(i,n_evt) time[i] = beg->disk->time - FABS(Uni()*(end->disk->time - beg->disk->time)); /* Invert time direction */ For(i,n_evt) time[i] = -time[i]; /* Bubble sort time in ascending order */ do { swap = NO; For(i,n_evt-1) { if(time[i+1] < time[i]) { swap = YES; dum = time[i+1]; time[i+1] = time[i]; time[i] = dum; } } }while(swap == YES); For(i,n_evt) { ldsk_a[i] = PHYREX_Make_Lindisk_Node(tree->mmod->n_dim); disk = PHYREX_Make_Disk_Event(tree->mmod->n_dim,tree->n_otu); PHYREX_Init_Lindisk_Node(ldsk_a[i],disk,tree->mmod->n_dim); PHYREX_Make_Lindisk_Next(ldsk_a[i]); PHYREX_Init_Disk_Event(disk,tree->mmod->n_dim,tree->mmod); disk->ldsk = ldsk_a[i]; disk->time = -time[i]; /* printf("\n. Generate ldsk %s",ldsk_a[i]->coord->id); */ } For(i,n_evt-1) ldsk_a[i]->prev = ldsk_a[i+1]; ldsk_a[i]->prev = NULL; for(i=1;inext[0] = ldsk_a[i-1]; ldsk_a[0]->next[0] = NULL; path = ldsk_a[0]; /* Generate path */ For(i,tree->mmod->n_dim) { For(j,n_evt) { if(j == 0) mode = (end->coord->lonlat[i] - beg->coord->lonlat[i])/(n_evt+1.) + beg->coord->lonlat[i]; else mode = (end->coord->lonlat[i] - ldsk_a[j-1]->coord->lonlat[i])/(n_evt+1.-j) + ldsk_a[j-1]->coord->lonlat[i]; ldsk_a[j]->coord->lonlat[i] = Rnorm_Trunc(mode, sd, 0.0, tree->mmod->lim->lonlat[i],&err); /* ldsk_a[j]->coord->lonlat[i] = Uni()*tree->mmod->lim->lonlat[i]; */ /* ldsk_a[j]->coord->lonlat[i] = mode; */ ldsk_a[j]->disk->centr->lonlat[i] = Rnorm_Trunc(ldsk_a[j]->coord->lonlat[i], sd, 0.0, tree->mmod->lim->lonlat[i],&err); /* ldsk_a[j]->disk->centr->lonlat[i] = Uni()*tree->mmod->lim->lonlat[i]; */ /* ldsk_a[j]->disk->centr->lonlat[i] = ldsk_a[j]->coord->lonlat[i]; */ } } /* For(j,n_evt) PhyML_Printf("\n. in %12f %12f",ldsk_a[j]->coord->lonlat[0],ldsk_a[j]->coord->lonlat[1]); */ Free(ldsk_a); Free(time); return(path); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl sd, t_tree *tree) { int i,j,err,n_evt; t_ldsk *ldsk; phydbl lnDens,mode,rate; lnDens = 0.0; mode = 0.0; n_evt = 0; ldsk = beg->prev; while(ldsk != end) { n_evt++; ldsk = ldsk->prev; assert(ldsk != NULL); } For(i,tree->mmod->n_dim) { j = 0; ldsk = beg; while(ldsk->prev != end) { assert(!(ldsk == NULL)); mode = (end->coord->lonlat[i] - ldsk->coord->lonlat[i])/(n_evt+1.-j) + ldsk->coord->lonlat[i]; lnDens += Log_Dnorm_Trunc(ldsk->prev->coord->lonlat[i], mode, sd, 0.0, tree->mmod->lim->lonlat[i],&err); /* lnDens += LOG(1./tree->mmod->lim->lonlat[i]); */ lnDens += Log_Dnorm_Trunc(ldsk->prev->disk->centr->lonlat[i], ldsk->prev->coord->lonlat[i], sd, 0.0, tree->mmod->lim->lonlat[i],&err); /* lnDens += LOG(1./tree->mmod->lim->lonlat[i]); */ ldsk = ldsk->prev; j++; } } if(cur_n_evt < 0) rate = 2.*PHYREX_Rate_Per_Unit_Area(tree)*PI*POW(sd,2)*tree->mmod->mu*FABS(end->disk->time - beg->disk->time); else rate = cur_n_evt; lnDens += Dpois(n_evt,rate,YES); lnDens += (n_evt) * LOG(1./FABS(end->disk->time - beg->disk->time)); lnDens += LnFact(n_evt); return(lnDens); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Time_Tree_Length(t_tree *tree) { phydbl len; int i; t_dsk *disk; disk = tree->disk; while(disk->prev) disk = disk->prev; len = 0.0; For(i,disk->ldsk->n_next) PHYREX_Time_Tree_Length_Pre(disk->ldsk,disk->ldsk->next[i],&len,tree); assert(!(isnan(len) || isinf(len))); return(len); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Time_Tree_Length_Pre(t_ldsk *a, t_ldsk *d, phydbl *len, t_tree *tree) { int i; (*len) += FABS(a->disk->time - d->disk->time); if(d->disk->next == NULL) return; else For(i,d->n_next) PHYREX_Time_Tree_Length_Pre(d,d->next[i],len,tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Is_On_Path(t_ldsk *target, t_ldsk *beg, t_ldsk *end) { t_ldsk *ldsk; if(target == beg || target == end) return NO; assert(!(beg->disk->time < end->disk->time)); ldsk = beg->prev; while(ldsk != end) { if(ldsk == target) return YES; ldsk = ldsk->prev; assert(!(ldsk == NULL)); } return NO; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int PHYREX_Path_Len(t_ldsk *beg, t_ldsk *end) { t_ldsk *ldsk; int len; len = 0; ldsk = beg; while(ldsk != end) { len++; ldsk = ldsk->prev; } len++; return len; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Print_Disk_Lk(t_tree *tree) { t_dsk *disk; PHYREX_Update_Lindisk_List(tree); disk = tree->disk->prev; do { PhyML_Printf("\n. Disk: %p time: %12f lk: %12f cumlk: %12f", disk, disk->time, PHYREX_Lk_Core(disk,tree), disk->c_lnL); disk = disk->prev; } while(disk->prev); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ t_ldsk *PHYREX_Find_Lca_Pair_Of_Ldsk(t_ldsk *n1, t_ldsk *n2, t_tree *tree) { t_ldsk **list1, **list2, *lca; int len1, len2; assert(n1); assert(n2); if(n1 == n2) return(n1); PHYREX_Get_List_Of_Ancestors(n1,&list1,&len1,tree); PHYREX_Get_List_Of_Ancestors(n2,&list2,&len2,tree); len1 = len1-1; len2 = len2-1; /* printf("\n. len1: %d len2: %d",len1,len2); fflush(NULL); */ /* printf("\n. %f %f %d %d [%f %f]", */ /* list1[1]->disk->time, */ /* list2[1]->disk->time, */ /* len1,len2, */ /* n1->disk->time, */ /* n2->disk->time); */ assert(list1[len1] == list2[len2]); do { if((len1 < 0 || len2 < 0) || (list1[len1] != list2[len2])) break; len1--; len2--; } while(len1 && len2); lca = list1[len1+1]; Free(list1); Free(list2); assert(lca); return(lca); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Get_List_Of_Ancestors(t_ldsk *start, t_ldsk ***list, int *len, t_tree *tree) { int block,i; t_ldsk *ldsk; assert(start); block = 100; *list = (t_ldsk **)mCalloc(block,sizeof(t_ldsk *)); ldsk = start; i = 0; do { (*list)[i] = ldsk; if(!(i%block)) *list = (t_ldsk **)mRealloc(*list,i+block,sizeof(t_ldsk *)); i++; ldsk = ldsk->prev; } while(ldsk); (*len) = i; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Dist_To_Lca(t_ldsk *d, t_ldsk *lca) { return(FABS(d->disk->time - lca->disk->time)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl PHYREX_Dist_Between_Two_Ldsk(t_ldsk *n1, t_ldsk *n2, t_tree *tree) { t_ldsk *lca; lca = PHYREX_Find_Lca_Pair_Of_Ldsk(n1,n2,tree); return(PHYREX_Dist_To_Lca(n1,lca)+PHYREX_Dist_To_Lca(n2,lca)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree *tree) { int i, j, n_demes; char *s,**deme_names; FILE *fp; fp = Openfile(filename,WRITE); assert(fp); deme_names = (char **)mCalloc(n_sites,sizeof(char *)); n_demes = 0; For(i,tree->n_otu) { s = strrchr(tree->a_nodes[i]->coord->id,'_'); For(j,n_demes) if(!strcmp(s+1,deme_names[j])) break; if(j == n_demes) { deme_names[n_demes] = (char *)mCalloc(strlen(s+1)+1,sizeof(char)); strcpy(deme_names[n_demes],s+1); n_demes++; } } // n_demes is the number of non-empty sampling sites PhyML_Fprintf(fp,""); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); For(i,tree->n_otu) { PhyML_Fprintf(fp,"\n", tree->a_nodes[i]->coord->id, tree->a_nodes[i]->coord->id, tree->a_nodes[i]->c_seq->state); } PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Uniform"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Exponential"); PhyML_Fprintf(fp,"\nbeast.math.distributions.LogNormalDistributionModel"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Normal"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Beta"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Gamma"); PhyML_Fprintf(fp,"\nbeast.math.distributions.LaplaceDistribution"); PhyML_Fprintf(fp,"\nbeast.math.distributions.Prior"); PhyML_Fprintf(fp,"\nbeast.math.distributions.InverseGamma"); PhyML_Fprintf(fp,"\nbeast.math.distributions.OneOnX"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); For(i,n_demes*(n_demes-1)) strcat(s,"1.0 "); PhyML_Fprintf(fp,"\n%s",n_demes*(n_demes-1),s); Free(s); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); For(i,n_demes) strcat(s,"1.0 "); PhyML_Fprintf(fp,"\n%s",n_demes,s); Free(s); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\nn_otu) { s = strchr(tree->a_nodes[i]->coord->id,'_'); PhyML_Fprintf(fp,"%s=%s", tree->a_nodes[i]->coord->id, s+1); if(i < tree->n_otu-1) PhyML_Fprintf(fp,","); else PhyML_Fprintf(fp,"\">"); } PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n2.0"); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); For(i,n_demes) strcat(s,"1.0 "); PhyML_Fprintf(fp,"\n%s",n_demes,s); Free(s); s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); For(i,n_demes*(n_demes-1)) strcat(s,"1.0 "); PhyML_Fprintf(fp,"\n%s",n_demes*(n_demes-1),s); Free(s); PhyML_Fprintf(fp,"\n0.25"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n1.0"); PhyML_Fprintf(fp,"\n1.25"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n1.0"); PhyML_Fprintf(fp,"\n1.25"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n1.0"); PhyML_Fprintf(fp,"\n1.25"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n1.0"); PhyML_Fprintf(fp,"\n1.0"); PhyML_Fprintf(fp,"\n0.0"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n%G",1.0); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); /* PhyML_Fprintf(fp,"\n"); */ /* PhyML_Fprintf(fp,"\n"); */ /* PhyML_Fprintf(fp,"\n"); */ PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); PhyML_Fprintf(fp,"\n"); For(i,n_demes) Free(deme_names[i]); Free(deme_names); fclose(fp); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phyml-3.2.0/src/phyrex.h000066400000000000000000000137541263450375500151500ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef PHYREX_H #define PHYREX_H #include "utilities.h" int PHYREX_Main(int argc, char **argv); int PHYREX_Main_Simulate(int argc, char **argv); int PHYREX_Main_Estimate(int argc, char **argv); t_tree *PHYREX_Simulate(int n_otu, int n_sites, phydbl width, phydbl height, int r_seed); phydbl PHYREX_Lk(t_tree *tree); phydbl PHYREX_Wrap_Lk(t_edge *b, t_tree *tree, supert_tree *stree); phydbl *PHYREX_MCMC(t_tree *tree); int PHYREX_Is_In_Disk(t_geo_coord *coord, t_dsk *disk, t_phyrex_mod *mmod); void PHYREX_New_Traj(t_dsk *start, t_dsk *end, t_tree *tree); void PHYREX_Remove_Disk(t_dsk *disk); void PHYREX_Insert_Disk(t_dsk *ins, t_tree *tree); t_ldsk *PHYREX_Prev_Coal_Lindisk(t_ldsk *t); t_ldsk *PHYREX_Next_Coal_Lindisk(t_ldsk *t); int PHYREX_Get_Next_Direction(t_ldsk *young, t_ldsk *old); void PHYREX_Update_Lindisk_List(t_tree *tree); void PHYREX_Update_Lindisk_List_Pre(t_dsk *disk, t_tree *tree); /* void PHYREX_Update_Lindisk_List(phydbl time, t_ldsk **list, int *pos, t_dsk *disk); */ /* void PHYREX_Update_Lindisk_List_Pre(t_ldsk *ldsk, phydbl time, t_ldsk **list, int *pos); */ void PHYREX_Connect_Ldsk_Given_Disk(t_dsk **disk, int n_disk, t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y); void PHYREX_Print_Struct(char sign, t_tree *tree); phydbl PHYREX_Uniform_Path_Density(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree); void PHYREX_Check_Struct(t_tree *tree); void PHYREX_Store_Geo_Coord(t_geo_coord *t); void PHYREX_Restore_Geo_Coord(t_geo_coord *t); int PHYREX_Total_Number_Of_Intervals(t_tree *tree); int PHYREX_Total_Number_Of_Coal_Disks(t_tree *tree); int PHYREX_Total_Number_Of_Hit_Disks(t_tree *tree); phydbl PHYREX_Log_Dunif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mmod); phydbl PHYREX_Runif_Rectangle_Overlap(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mod); int PHYREX_One_New_Traj(t_ldsk *y_ldsk, t_ldsk *o_ldsk, int dir_o_y, t_dsk *xtra_dsk, int n_cur_disk, t_tree *tree); phydbl PHYREX_Wrap_Prior_Radius(t_edge *e, t_tree *tree, supert_tree *st); phydbl PHYREX_LnPrior_Radius(t_tree *tree); void PHYREX_Initial_Ldsk_Pos(t_tree *tree); phydbl PHYREX_Min_Radius(t_tree *tree); void PHYREX_Get_Min_Max_Disk_Given_Ldsk(t_dsk *disk, phydbl **min, phydbl **max, t_tree *tree); void PHYREX_Get_Min_Max_Ldsk_Given_Disk(t_ldsk *ldsk, phydbl **min, phydbl **max, t_tree *tree); void PHYREX_One_New_Traj_Given_Disk(t_ldsk *y_ldsk, t_ldsk *o_ldsk, t_tree *tree); void PHYREX_Update_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree); void PHYREX_Update_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_ldsk *root_ldsk, t_tree *tree); void PHYREX_Restore_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, t_tree *tree); void PHYREX_Restore_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_tree *tree); void PHYREX_Proposal_Disk_Ldsk_Subtree(t_ldsk *root_ldsk, phydbl *logdens, t_tree *tree); void PHYREX_Proposal_Disk_Ldsk_Subtree_Pre(t_ldsk *old_ldsk, t_ldsk *young_ldsk, t_ldsk *root_ldsk, phydbl *logdens, t_tree *tree); phydbl PHYREX_LnPrior_Lbda(t_tree *tree); phydbl PHYREX_LnPrior_Mu(t_tree *tree); void PHYREX_Ldsk_To_Tree(t_tree *tree); void PHYREX_Ldsk_To_Tree_Post(t_node *a, t_ldsk *ldsk, int *available, t_tree *tree); phydbl PHYREX_Rnorm_Trunc(t_ldsk *ldsk, t_dsk *disk, t_phyrex_mod *mod); void PHYREX_Remove_Lindisk_Next(t_ldsk *ldsk, t_ldsk *rm); phydbl PHYREX_Simulate_Backward_Core(int new_loc, t_dsk *init_disk, t_tree *tree); phydbl *PHYREX_Mean_Pairwise_Distance_Between_Lineage_Locations(t_tree *tree); phydbl PHYREX_Random_Select_Time_Between_Jumps(t_tree *tree); phydbl PHYREX_Simulate_Forward_Core(int n_sites, t_tree *tree); int PHYREX_Is_In_Ldscape(t_ldsk *ldsk, t_phyrex_mod *mmod); void PHYREX_Update_Lindisk_List_Core(t_dsk *disk, t_tree *tree); phydbl PHYREX_Mean_Time_Between_Events(t_tree *tree); void PHYREX_All_Pairs_Coal_Times_Dist(t_tree *tree); void PHYREX_Rand_Pairs_Coal_Times_Dist(t_tree *tree); phydbl PHYREX_Neighborhood_Size_Regression(t_tree *tree); phydbl PHYREX_Neighborhood_Size(t_tree *tree); phydbl PHYREX_Update_Radius(t_tree *tree); phydbl PHYREX_Update_Sigsq(t_tree *tree); void PHYREX_Read_Tip_Coordinates(t_ldsk **ldsk_a, t_tree *tree); phydbl PHYREX_Sample_Rad_From_Prior(t_tree *tree); void MCMC_PHYREX_Sigsq(t_tree *tree); phydbl PHYREX_LnPrior_Sigsq(t_tree *tree); phydbl PHYREX_Rate_Per_Unit_Area(t_tree *tree); phydbl PHYREX_Tree_Height(t_tree *tree); int PHYREX_Random_Insert_Ldsk_In_Next_List(t_ldsk *ins, t_ldsk *where); void PHYREX_Insert_Ldsk_In_Next_List(t_ldsk *ins, int pos, t_ldsk *where); t_ldsk *PHYREX_Remove_Path(t_ldsk *beg, t_ldsk *end, int *pos_end, t_tree *tree); void PHYREX_Insert_Path(t_ldsk *beg, t_ldsk *end, t_ldsk *path, int pos, t_tree *tree); t_ldsk *PHYREX_Generate_Path(t_ldsk *beg, t_ldsk *end, phydbl n_evt, phydbl sd, t_tree *tree); phydbl PHYREX_Path_Logdensity(t_ldsk *beg, t_ldsk *end, phydbl cur_n_evt, phydbl sd, t_tree *tree); phydbl PHYREX_Time_Tree_Length(t_tree *tree); void PHYREX_Time_Tree_Length_Pre(t_ldsk *a, t_ldsk *d, phydbl *len, t_tree *tree); int PHYREX_Is_On_Path(t_ldsk *target, t_ldsk *beg, t_ldsk *end); int PHYREX_Path_Len(t_ldsk *beg, t_ldsk *end); phydbl PHYREX_Lk_Core(t_dsk *disk, t_tree *tree); void PHYREX_Print_Disk_Lk(t_tree *tree); phydbl PHYREX_Lk_Core_Bis(t_dsk *disk, t_tree *tree); t_ldsk *PHYREX_Find_Lca_Pair_Of_Ldsk(t_ldsk *n1, t_ldsk *n2, t_tree *tree); void PHYREX_Get_List_Of_Ancestors(t_ldsk *start, t_ldsk ***list, int *len, t_tree *tree); phydbl PHYREX_Dist_To_Lca(t_ldsk *d, t_ldsk *lca); phydbl PHYREX_Dist_Between_Two_Ldsk(t_ldsk *n1, t_ldsk *n2, t_tree *tree); phydbl PHYREX_Lk_Range(t_dsk *young, t_dsk *old, t_tree *tree); void PHYREX_Print_MultiTypeTree_Config_File(int n_sites, char *filename, t_tree *tree); phydbl PHYREX_Effective_Density(t_tree *tree); phydbl PHYREX_Generation_Length(t_tree *tree); #endif phyml-3.2.0/src/rates.c000066400000000000000000003063431263450375500147410ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Routines for molecular clock trees and molecular dating */ #include "rates.h" #ifdef RWRAPPER #include #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Lk_Rates(t_tree *tree) { tree->rates->c_lnL_rates = .0; RATES_Lk_Rates_Pre(tree->n_root,tree->n_root->v[2],NULL,tree); RATES_Lk_Rates_Pre(tree->n_root,tree->n_root->v[1],NULL,tree); if(isnan(tree->rates->c_lnL_rates) || isinf(tree->rates->c_lnL_rates)) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } return tree->rates->c_lnL_rates; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { int i; phydbl log_dens,mu_a,mu_d,r_a,r_d,dt_a,dt_d; int n_a,n_d; log_dens = -1.; if(d->anc != a) { PhyML_Printf("\n. d=%d d->anc=%d a=%d root=%d",d->num,d->anc->num,a->num,tree->n_root->num); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dt_a = -1.; if(a != tree->n_root) dt_a = tree->rates->nd_t[a->num] - tree->rates->nd_t[a->anc->num]; mu_a = tree->rates->br_r[a->num]; r_a = tree->rates->nd_r[a->num]; n_a = tree->rates->n_jps[a->num]; dt_d = FABS(tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]); mu_d = tree->rates->br_r[d->num]; r_d = tree->rates->nd_r[d->num]; n_d = tree->rates->n_jps[d->num]; log_dens = RATES_Lk_Rates_Core(mu_a,mu_d,r_a,r_d,n_a,n_d,dt_a,dt_d,tree); tree->rates->c_lnL_rates += log_dens; /* printf("\n. a=%3d d=%3d r(a)=%10f r(d)=%10f %f",a->num,d->num,mu_a,mu_d,log_dens); */ if(isnan(tree->rates->c_lnL_rates)) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); MCMC_Print_Param(tree->mcmc,tree); Exit("\n"); } tree->rates->triplet[a->num] += log_dens; if(d->tax) return; else { For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Lk_Rates_Pre(d,d->v[i],d->b[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Lk_Change_One_Rate(t_node *d, phydbl new_rate, t_tree *tree) { tree->rates->br_r[d->num] = new_rate; RATES_Update_Triplet(d,tree); RATES_Update_Triplet(d->anc,tree); return(tree->rates->c_lnL_rates); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Lk_Change_One_Time(t_node *n, phydbl new_t, t_tree *tree) { if(n == tree->n_root) { PhyML_Printf("\n. Moving the time of the root t_node is not permitted."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } else { int i; tree->rates->nd_t[n->num] = new_t; RATES_Update_Triplet(n,tree); For(i,3) { if(n->b[i] != tree->e_root) RATES_Update_Triplet(n->v[i],tree); else RATES_Update_Triplet(tree->n_root,tree); } } return(tree->rates->c_lnL_rates); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Triplet(t_node *n, t_tree *tree) { phydbl curr_triplet,new_triplet; phydbl dt0,dt1,dt2; phydbl mu1_mu0,mu2_mu0; phydbl mu0,mu1,mu2; phydbl r0,r1,r2; int n0,n1,n2; int i; t_node *v1,*v2; if(n->tax) return; curr_triplet = tree->rates->triplet[n->num]; dt0 = dt1 = dt2 = -100.0; r0 = r1 = r2 = 0.0; if(n == tree->n_root) { phydbl log_dens; log_dens = 0.0; dt0 = tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]; dt1 = tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]; mu0 = tree->rates->br_r[tree->n_root->v[2]->num]; mu1 = tree->rates->br_r[tree->n_root->v[1]->num]; r0 = tree->rates->nd_r[tree->n_root->v[2]->num]; r1 = tree->rates->nd_r[tree->n_root->v[1]->num]; n0 = tree->rates->n_jps[tree->n_root->v[2]->num]; n1 = tree->rates->n_jps[tree->n_root->v[1]->num]; switch(tree->rates->model) { case COMPOUND_COR : case COMPOUND_NOCOR : { log_dens = RATES_Dmu(mu0,n0,dt0,tree->rates->nu,1./tree->rates->nu,tree->rates->lexp,0,1); log_dens *= RATES_Dmu(mu1,n1,dt1,tree->rates->nu,1./tree->rates->nu,tree->rates->lexp,0,1); log_dens = LOG(log_dens); break; } case EXPONENTIAL : { log_dens = Dexp(mu0,tree->rates->lexp) * Dexp(mu1,tree->rates->lexp); log_dens = LOG(log_dens); break; } case GAMMA : { log_dens = Dgamma(mu0,tree->rates->nu,1./tree->rates->nu) * Dgamma(mu1,tree->rates->nu,1./tree->rates->nu); log_dens = LOG(log_dens); break; } case THORNE : { int err; phydbl mean0,sd0; phydbl mean1,sd1; sd0 = SQRT(tree->rates->nu*dt0); mean0 = 1.0; sd1 = SQRT(tree->rates->nu*dt1); mean1 = 1.0; log_dens = Log_Dnorm_Trunc(mu0,mean0,sd0,tree->rates->min_rate,tree->rates->max_rate,&err) + Log_Dnorm_Trunc(mu1,mean1,sd1,tree->rates->min_rate,tree->rates->max_rate,&err); break; } case GUINDON : { Exit("\n. Not implemented yet.\n"); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); break; } default : { Exit("\n. Model not implemented yet.\n"); break; } } new_triplet = log_dens; if(isnan(log_dens) || isinf(FABS(log_dens))) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); MCMC_Print_Param(tree->mcmc,tree); Exit("\n"); } } else { mu0 = mu1 = mu2 = -1.; n0 = n1 = n2 = -1; mu0 = tree->rates->br_r[n->num]; dt0 = FABS(tree->rates->nd_t[n->num] - tree->rates->nd_t[n->anc->num]); n0 = tree->rates->n_jps[n->num]; r0 = tree->rates->nd_r[n->num]; v1 = v2 = NULL; For(i,3) { if((n->v[i] != n->anc) && (n->b[i] != tree->e_root)) { if(!v1) { v1 = n->v[i]; mu1 = tree->rates->br_r[v1->num]; dt1 = FABS(tree->rates->nd_t[v1->num] - tree->rates->nd_t[n->num]); n1 = tree->rates->n_jps[v1->num]; r1 = tree->rates->nd_r[v1->num]; } else { v2 = n->v[i]; mu2 = tree->rates->br_r[v2->num]; dt2 = FABS(tree->rates->nd_t[v2->num] - tree->rates->nd_t[n->num]); n2 = tree->rates->n_jps[v2->num]; r2 = tree->rates->nd_r[v2->num]; } } } mu1_mu0 = RATES_Lk_Rates_Core(mu0,mu1,r0,r1,n0,n1,dt0,dt1,tree); mu2_mu0 = RATES_Lk_Rates_Core(mu0,mu2,r0,r1,n0,n2,dt0,dt2,tree); new_triplet = mu1_mu0 + mu2_mu0; } tree->rates->c_lnL_rates = tree->rates->c_lnL_rates + new_triplet - curr_triplet; tree->rates->triplet[n->num] = new_triplet; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Returns LOG(f(br_r_rght;br_r_left)) */ phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl nd_r_d, int n_a, int n_d, phydbl dt_a, phydbl dt_d, t_tree *tree) { phydbl log_dens; phydbl mean,sd; phydbl min_r, max_r; phydbl cr,logcr; cr = tree->rates->clock_r; logcr = LOG(cr); log_dens = UNLIKELY; mean = sd = -1.; min_r = tree->rates->min_rate; max_r = tree->rates->max_rate; dt_d = MAX(0.5,dt_d); // We give only one decimal when printing out node heights. It is therefore a fair approximation switch(tree->rates->model) { case THORNE : { int err; if(tree->rates->model_log_rates == YES) { br_r_d += logcr; br_r_a += logcr; min_r += logcr; max_r += logcr; sd = SQRT(tree->rates->nu*dt_d); mean = br_r_a - .5*sd*sd; log_dens = Log_Dnorm_Trunc(br_r_d,mean,sd,min_r,max_r,&err); if(err) { PhyML_Printf("\n. Run: %d",tree->mcmc->run); PhyML_Printf("\n. br_r_d = %f br_r_a = %f dt_d = %f logcr = %f",br_r_d,br_r_a,dt_d,logcr); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } else { PhyML_Printf("\n. Not implemented yet."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } /* int err; */ /* phydbl cr; */ /* phydbl min_r, max_r; */ /* cr = tree->rates->clock_r; */ /* min_r = tree->rates->min_rate * cr; */ /* max_r = tree->rates->max_rate * cr; */ /* /\* !!!!!!!!!!!!1 *\/ */ /* br_r_d *= cr; */ /* br_r_a *= cr; */ /* err = NO; */ /* /\* if(dt_d < 5.0) dt_d = 5.0; *\/ */ /* sd = SQRT(dt_d*tree->rates->nu); */ /* /\* sd = SQRT(dt_d*EXP(tree->rates->nu)); *\/ */ /* /\* mean = LOG(br_r_a) - .5*sd*sd; *\/ */ /* if(tree->rates->model_log_rates == YES) */ /* { */ /* mean = br_r_a - .5*sd*sd; */ /* } */ /* else */ /* { */ /* mean = br_r_a; */ /* } */ /* log_dens = Log_Dnorm_Trunc(br_r_d,mean,sd,min_r,max_r,&err); */ /* if(err || isnan(log_dens) || isinf(log_dens)) */ /* { */ /* PhyML_Printf("\n. br_r_a=%f br_r_d=%f dt_d=%f nu=%G",br_r_a,br_r_d,dt_d,tree->rates->nu); */ /* PhyML_Printf("\n. Run: %d",tree->mcmc->run); */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ /* } */ break; } case GUINDON : { int err; min_r = tree->rates->min_rate; max_r = tree->rates->max_rate; br_r_d += logcr; br_r_a += logcr; min_r += logcr; max_r += logcr; sd = SQRT(tree->rates->nu*dt_d); mean = br_r_a - .5*sd*sd; log_dens = Log_Dnorm_Trunc(br_r_d,mean,sd,min_r,max_r,&err); if(err) { PhyML_Printf("\n. Run: %d",tree->mcmc->run); PhyML_Printf("\n. br_r_d=%f mean=%f sd=%f min_r=%f max_r=%f dt_d=%f",br_r_d,mean,sd,min_r,max_r,dt_d); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } break; } case GAMMA : { if(tree->rates->model_log_rates == YES) log_dens = Dgamma(EXP(br_r_d),1./tree->rates->nu,tree->rates->nu); else log_dens = Dgamma(br_r_d,1./tree->rates->nu,tree->rates->nu); log_dens = LOG(log_dens); break; } case STRICTCLOCK : { log_dens = 0.0; break; } default : { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } } if(isnan(log_dens) || isinf(FABS(log_dens))) { PhyML_Printf("\n. Run=%4d br_r_d=%f br_r_a=%f dt_d=%f dt_a=%f nu=%f log_dens=%G sd=%f mean=%f\n", tree->mcmc->run, br_r_d,br_r_a,dt_d,dt_a,tree->rates->nu,log_dens, sd,mean); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return log_dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Compound_Core(phydbl mu1, phydbl mu2, int n1, int n2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx) { if((n1 > -1) && (n2 > -1)) { return RATES_Compound_Core_Joint(mu1,mu2,n1,n2,dt1,dt2,alpha,beta,lexp,eps,approx); } else { return RATES_Compound_Core_Marginal(mu1,mu2,dt1,dt2,alpha,beta,lexp,eps,approx); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Compound_Core_Marginal(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx) { phydbl p0,p1,v0,v1,v2; phydbl dmu1; int equ; phydbl dens; v0 = v1 = v2 = 0.0; /* Probability of 0 and 1 jumps */ p0 = Dpois(0,lexp*(dt2+dt1),NO); p1 = Dpois(1,lexp*(dt2+dt1),NO); dmu1 = RATES_Dmu(mu1,-1,dt1,alpha,beta,lexp,0,0); /* Are the two rates equal ? */ equ = 0; if(FABS(mu1-mu2) < eps) equ = 1; /* No jump */ if(equ) { v0 = 1.0*Dgamma(mu1,alpha,beta)/dmu1; /* Rprintf("\n. mu1=%f mu2=%f",mu1,mu2); */ } else { v0 = 1.E-100; } /* One jump */ v1 = RATES_Dmu1_And_Mu2_One_Jump_Two_Intervals(mu1,mu2,dt1,dt2,alpha,beta); v1 /= dmu1; /* Two jumps and more (approximation) */ if(approx == 1) { v2 = RATES_Dmu(mu1,-1,dt1,alpha,beta,lexp,0,0)*RATES_Dmu(mu2,-1,dt2,alpha,beta,lexp,0,0) - Dpois(0,lexp*dt1,NO) * Dpois(0,lexp*dt2,NO) * Dgamma(mu1,alpha,beta) * Dgamma(mu2,alpha,beta); } else { v2 = RATES_Dmu_One(mu1,dt1,alpha,beta,lexp) * RATES_Dmu_One(mu2,dt2,alpha,beta,lexp); v2 += Dpois(0,lexp*dt1,NO)*Dgamma(mu1,alpha,beta)*RATES_Dmu(mu2,-1,dt2,alpha,beta,lexp,1,0); v2 += Dpois(0,lexp*dt2,NO)*Dgamma(mu2,alpha,beta)*RATES_Dmu(mu1,-1,dt1,alpha,beta,lexp,1,0); } /* PhyML_Printf("\n. %f %f %f %f %f ",mu1,mu2,dt1,dt2,v2); */ v2 /= dmu1; dens = p0*v0 + p1*v1 + v2; /* dens = p1*v1 + v2; */ /* dens = p1*v1 + v2; */ /* dens = v0; */ /* dens *= dmu1; */ if(dens < SMALL) { PhyML_Printf("\n. dens=%12G mu1=%12G mu2=%12G dt1=%12G dt2=%12G lexp=%12G alpha=%f v0=%f v1=%f v2=%f p0=%f p1=%f p2=%f", dens, mu1,mu2,dt1,dt2, lexp, alpha, v0,v1,v2, p0,p1,1.-p0-p1); } return dens; } /**********************************************************/ phydbl RATES_Compound_Core_Joint(phydbl mu1, phydbl mu2, int n1, int n2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx) { phydbl density; phydbl dmu1; if(n1 < 0 || n2 < 0) { PhyML_Printf("\n. n1=%d n2=%d",n1,n2); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dmu1 = RATES_Dmu(mu1,n1,dt1,alpha,beta,lexp,0,0); if((n1 < 0) || (n2 < 0)) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if((n1 == 0) && (n2 == 0)) { if(FABS(mu1-mu2) < eps) { density = Dgamma(mu1,alpha,beta); } else { density = 1.E-70; } } else if((n1 == 0) && (n2 == 1)) { density = Dgamma(mu1,alpha,beta) * RATES_Dmu1_Given_V_And_N(mu2,mu1,1,dt2,alpha,beta); } else if((n1 == 1) && (n2 == 0)) { density = Dgamma(mu2,alpha,beta) * RATES_Dmu1_Given_V_And_N(mu1,mu2,1,dt1,alpha,beta); } else /* independent */ { density = RATES_Dmu(mu1,n1,dt1,alpha,beta,lexp,0,0) * RATES_Dmu(mu2,n2,dt2,alpha,beta,lexp,0,0); } density /= dmu1; density *= Dpois(n2,dt2*lexp,NO); if(density < 1.E-70) density = 1.E-70; /* PhyML_Printf("\n. density = %15G mu1=%3.4f mu2=%3.4f dt1=%3.4f dt2=%3.4f n1=%2d n2=%2d",density,mu1,mu2,dt1,dt2,n1,n2); */ return density; } /**********************************************************/ void RATES_Print_Triplets(t_tree *tree) { int i; For(i,2*tree->n_otu-1) PhyML_Printf("\n. Node %3d t=%f",i,tree->rates->triplet[i]); } /**********************************************************/ void RATES_Print_Rates(t_tree *tree) { RATES_Print_Rates_Pre(tree->n_root,tree->n_root->v[2],NULL,tree); RATES_Print_Rates_Pre(tree->n_root,tree->n_root->v[1],NULL,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Print_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if((d == tree->n_root->v[2] && d->tax) || (d == tree->n_root->v[1] && d->tax)) PhyML_Printf("\n. a=%3d ++d=%3d rate=%12f t_left=%12f t_rght=%12f ml=%12f l=%12f %12f", a->num,d->num, tree->rates->br_r[d->num], tree->rates->nd_t[a->num],tree->rates->nd_t[d->num], tree->rates->ml_l[d->num], tree->rates->cur_l[d->num], (tree->rates->nd_t[d->num]-tree->rates->nd_t[a->num])*tree->rates->clock_r*tree->rates->br_r[d->num]); else if((d == tree->n_root->v[2]) || (d == tree->n_root->v[1])) PhyML_Printf("\n. a=%3d __d=%3d rate=%12f t_left=%12f t_rght=%12f ml=%12f l=%12f %12f", a->num,d->num, tree->rates->br_r[d->num], tree->rates->nd_t[a->num],tree->rates->nd_t[d->num], tree->rates->ml_l[d->num], tree->rates->cur_l[d->num], (tree->rates->nd_t[d->num]-tree->rates->nd_t[a->num])*tree->rates->clock_r*tree->rates->br_r[d->num]); else PhyML_Printf("\n. a=%3d d=%3d rate=%12f t_left=%12f t_rght=%12f ml=%12f l=%12f %12f", a->num,d->num, tree->rates->br_r[d->num], tree->rates->nd_t[a->num],tree->rates->nd_t[d->num], tree->rates->ml_l[d->num], tree->rates->cur_l[d->num], (tree->rates->nd_t[d->num]-tree->rates->nd_t[a->num])*tree->rates->clock_r*tree->rates->br_r[d->num]); if(d->tax) return; else { int i; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Print_Rates_Pre(d,d->v[i],d->b[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Average_Rate(t_tree *tree) { int i; phydbl sum; sum = 0.0; For(i,2*tree->n_otu-2) sum += tree->rates->br_r[i]; return sum/(2*tree->n_otu-2); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Average_Substitution_Rate(t_tree *tree) { phydbl sum_r,sum_dt; phydbl u,t,t_anc; int i; u = 0.0; sum_r = 0.0; sum_dt = 0.0; /* For(i,2*tree->n_otu-3) */ /* { */ /* t = tree->rates->nd_t[i]; */ /* t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num]; */ /* u = tree->a_edges[i]->l->v; */ /* if(tree->rates->model == GUINDON) u = tree->a_edges[i]->gamma_prior_mean; */ /* sum_r += u; */ /* sum_dt += FABS(t-t_anc); */ /* } */ For(i,2*tree->n_otu-3) { if(tree->a_edges[i] != tree->e_root) { t = tree->rates->nd_t[tree->a_edges[i]->left->num]; t_anc = tree->rates->nd_t[tree->a_edges[i]->rght->num]; u = tree->a_edges[i]->l->v; sum_r += u; sum_dt += FABS(t-t_anc); } sum_dt += FABS(tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]); sum_dt += FABS(tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]); u = tree->e_root->l->v; sum_r += u; } return(sum_r / sum_dt); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Check_Mean_Rates_True(t_tree *tree) { phydbl sum; int i; sum = 0.0; For(i,2*tree->n_otu-2) sum += tree->rates->true_r[i]; return(sum/(phydbl)(2*tree->n_otu-2)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int RATES_Check_Node_Times(t_tree *tree) { int err; err = NO; RATES_Check_Node_Times_Pre(tree->n_root,tree->n_root->v[2],&err,tree); RATES_Check_Node_Times_Pre(tree->n_root,tree->n_root->v[1],&err,tree); return err; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Check_Node_Times_Pre(t_node *a, t_node *d, int *err, t_tree *tree) { if((tree->rates->nd_t[d->num] < tree->rates->nd_t[a->num]) || (FABS(tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]) < 1.E-20)) { PhyML_Printf("\n== a->t=%f d->t=%f",tree->rates->nd_t[a->num],tree->rates->nd_t[d->num]); PhyML_Printf("\n== a->t_prior_min=%f a->t_prior_max=%f",tree->rates->t_prior_min[a->num],tree->rates->t_prior_max[a->num]); PhyML_Printf("\n== d->t_prior_min=%f d->t_prior_max=%f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]); *err = YES; } if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) RATES_Check_Node_Times_Pre(d,d->v[i],err,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Bracket_N_Jumps(int *up, int *down, phydbl param) { phydbl cdf,eps,a,b,c; int step; step = 10; eps = 1.E-10; cdf = 0.0; c = 1; while(cdf < 1.-eps) { c = (int)FLOOR(c * step); cdf = Ppois(c,param); } a = 0.0; b = (c-a)/2.; step = 0; do { step++; cdf = Ppois(b,param); if(cdf < eps) a = b; else { break; } b = (c-a)/2.; } while(step < 1000); if(step == 1000) { PhyML_Printf("\n. a=%f b=%f c=%f param=%f",a,b,c,param); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } *up = c; *down = a; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* mu : average rate of the time period dt dt : time period to be considered a : rate at a given time point is gamma distributed. a is the shape parameter b : rate at a given time point is gamma distributed. b is the scale parameter lexp : the number of rate switches is Poisson distributed with parameter lexp * dt */ /* compute f(mu;dt,a,b,lexp), the probability density of mu. We need to integrate over the possible number of jumps (n) during the time interval dt */ phydbl RATES_Dmu(phydbl mu, int n_jumps, phydbl dt, phydbl a, phydbl b, phydbl lexp, int min_n, int jps_dens) { if(n_jumps < 0) /* Marginal, i.e., the number of jumps is not fixed */ { phydbl var,cumpoissprob,dens,mean,poissprob,ab2,gammadens,lexpdt; int n,up,down; var = 0.0; cumpoissprob = 0.0; dens = 0.0; n = 0; mean = a*b; ab2 = a*b*b; lexpdt = lexp*dt; RATES_Bracket_N_Jumps(&up,&down,lexpdt); For(n,MAX(down,min_n)-1) cumpoissprob += Dpois(n,lexpdt,NO); for(n=MAX(down,min_n);n 1.-1.E-04) break; } if(dens < 1.E-70) dens = 1.E-70; return(dens); } else /* Joint, i.e., return P(mu | dt, n_jumps) */ { phydbl mean, var, density; mean = 1.0; var = (2./(n_jumps+2.))*a*b*b; if(jps_dens) density = Dgamma_Moments(mu,mean,var) * Dpois(n_jumps,dt*lexp,NO); else density = Dgamma_Moments(mu,mean,var); if(density < 1.E-70) density = 1.E-70; return density; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Dmu_One(phydbl mu, phydbl dt, phydbl a, phydbl b, phydbl lexp) { phydbl var,cumpoissprob,dens,mean,poissprob,ab2,gammadens,lexpdt; int n,up,down; var = 0.0; cumpoissprob = 0.0; dens = 0.0; n = 0; mean = a*b; ab2 = a*b*b; lexpdt = lexp*dt; if(dt < 0.0) { PhyML_Printf("\n. dt=%f",dt); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(lexpdt < SMALL) { PhyML_Printf("\n. lexpdt=%G lexp=%G dt=%G",lexpdt,lexp,dt); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(mu < 1.E-10) { PhyML_Printf("\n. mu=%G",mu); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } RATES_Bracket_N_Jumps(&up,&down,lexpdt); For(n,MAX(1,down)-1) cumpoissprob += Dpois(n,lexpdt,NO); for(n=MAX(1,down);n 1.-1.E-06) break; } return(dens); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Given the times of nodes a (ta) and d (td), the shape of the gamma distribution of instantaneous rates, the parameter of the exponential distribution of waiting times between rate jumps and the instantaneous rate at t_node a, this function works out an expected number of (amino-acids or nucleotide) substitutions per site. */ void RATES_Expect_Number_Subst(phydbl t_beg, phydbl t_end, phydbl r_beg, int *n_jumps, phydbl *mean_r, phydbl *r_end, t_rate *rates, t_tree *tree) { phydbl curr_r, curr_t, next_t; switch(rates->model) { case COMPOUND_COR:case COMPOUND_NOCOR: { /* Compound Poisson */ if(rates->model == COMPOUND_COR) { curr_r = r_beg; *mean_r = r_beg; } else { curr_r = Rgamma(rates->nu,1./rates->nu);; *mean_r = curr_r; } curr_t = t_beg + Rexp(rates->lexp); /* Exponentially distributed waiting times */ next_t = curr_t; *n_jumps = 0; while(curr_t < t_end) { curr_r = Rgamma(rates->nu,1./rates->nu); /* Gamma distributed random instantaneous rate */ (*n_jumps)++; next_t = curr_t + Rexp(rates->lexp); if(next_t < t_end) { *mean_r = (1./(next_t - t_beg)) * (*mean_r * (curr_t - t_beg) + curr_r * (next_t - curr_t)); } else { *mean_r = (1./(t_end - t_beg)) * (*mean_r * (curr_t - t_beg) + curr_r * (t_end - curr_t)); } curr_t = next_t; } /* PhyML_Printf("\n. [%3d %f %f]",*n_jumps,*mean_r,r_beg); */ if(*mean_r < rates->min_rate) *mean_r = rates->min_rate; if(*mean_r > rates->max_rate) *mean_r = rates->max_rate; *r_end = curr_r; break; } case EXPONENTIAL: { *mean_r = Rexp(rates->nu); if(*mean_r < rates->min_rate) *mean_r = rates->min_rate; if(*mean_r > rates->max_rate) *mean_r = rates->max_rate; *r_end = *mean_r; break; } case GAMMA: { *mean_r = Rgamma(rates->nu,1./rates->nu); if(*mean_r < rates->min_rate) *mean_r = rates->min_rate; if(*mean_r > rates->max_rate) *mean_r = rates->max_rate; *r_end = *mean_r; break; } case THORNE: { phydbl sd,mean; int err; sd = SQRT(rates->nu*FABS(t_beg-t_end)); mean = r_beg; *mean_r = Rnorm_Trunc(mean,sd,rates->min_rate,rates->max_rate,&err); if(err) PhyML_Printf("\n. %s %d %d",__FILE__,__LINE__,tree->mcmc->run); *r_end = *mean_r; break; } default: { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n. Model not implemented yet.\n"); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl r_a, t_tree *tree) { phydbl a_t,d_t; phydbl mean_r; int n_jumps; phydbl r_d; a_t = tree->rates->nd_t[a->num]; d_t = tree->rates->nd_t[d->num]; RATES_Expect_Number_Subst(a_t,d_t,r_a,&n_jumps,&mean_r,&r_d,tree->rates,tree); tree->rates->br_r[d->num] = mean_r; tree->rates->true_r[d->num] = mean_r; tree->rates->t_jps[d->num] = n_jumps; /* Move to the next branches */ if(d->tax) return; else { int i; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Get_Mean_Rates_Pre(d,d->v[i],d->b[i],r_d,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Random_Branch_Lengths(t_tree *tree) { phydbl r0; r0 = 1.0; tree->rates->br_r[tree->n_root->num] = r0; RATES_Get_Mean_Rates_Pre(tree->n_root,tree->n_root->v[2],NULL,r0,tree); RATES_Get_Mean_Rates_Pre(tree->n_root,tree->n_root->v[1],NULL,r0,tree); /* RATES_Normalise_Rates(tree); */ RATES_Update_Cur_Bl(tree); RATES_Initialize_True_Rates(tree); tree->n_root_pos = tree->rates->cur_l[tree->n_root->v[2]->num] / (tree->rates->cur_l[tree->n_root->v[2]->num] + tree->rates->cur_l[tree->n_root->v[1]->num]); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Set_Node_Times(t_tree *tree) { RATES_Set_Node_Times_Pre(tree->n_root,tree->n_root->v[2],tree); RATES_Set_Node_Times_Pre(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Init_Triplets(t_tree *tree) { int i; For(i,2*tree->n_otu-1) tree->rates->triplet[i] = 0.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Set_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { t_node *v1, *v2; /* the two sons of d */ phydbl t_sup, t_inf; int i; v1 = v2 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } t_inf = MIN(tree->rates->nd_t[v1->num],tree->rates->nd_t[v2->num]); t_sup = tree->rates->nd_t[a->num]; if(t_sup > t_inf) { PhyML_Printf("\n. t_sup = %f t_inf = %f",t_sup,t_inf); PhyML_Printf("\n. Run = %d",tree->mcmc->run); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(tree->rates->nd_t[d->num] > t_inf) { tree->rates->nd_t[d->num] = t_inf; PhyML_Printf("\n. Time for t_node %d is larger than should be. Set it to %f",d->num,tree->rates->nd_t[d->num]); } else if(tree->rates->nd_t[d->num] < t_sup) { tree->rates->nd_t[d->num] = t_sup; PhyML_Printf("\n. Time for t_node %d is lower than should be. Set it to %f",d->num,tree->rates->nd_t[d->num]); } For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Set_Node_Times_Pre(d,d->v[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Dmu1_And_Mu2_One_Jump_Two_Intervals(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta) { phydbl dens; if(mu2 < 1.E-10) { PhyML_Printf("\n. mu2=%G",mu2); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(mu1 < 1.E-10) { PhyML_Printf("\n. mu2=%G",mu1); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dens = ((dt1/(dt1+dt2)) * RATES_Dmu1_Given_V_And_N(mu1,mu2,1,dt1,alpha,beta) * Dgamma(mu2,alpha,beta)) + ((dt2/(dt1+dt2)) * RATES_Dmu1_Given_V_And_N(mu2,mu1,1,dt2,alpha,beta) * Dgamma(mu1,alpha,beta)); return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Dmu1_Given_V_And_N(phydbl mu1, phydbl v, int n, phydbl dt1, phydbl a, phydbl b) { phydbl lbda,dens,h,u; phydbl mean,var; int n_points,i; phydbl ndb; phydbl end, beg; n_points = 20; end = MIN(mu1/v-0.01,0.99); beg = 0.01; dens = 0.0; if(end > beg) { mean = a*b; var = a*b*b*2./(n+1.); ndb = (phydbl)n/dt1; h = (end - beg) / (phydbl)n_points; lbda = beg; For(i,n_points-1) { lbda += h; u = (mu1 - lbda*v)/(1.-lbda); if(u < 1.E-10) { PhyML_Printf("\n. u = %G",u); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dens += Dgamma_Moments(u,mean,var) / (1.-lbda) * ndb * POW(1.-lbda,n-1); } dens *= 2.; lbda = beg; u = (mu1 - lbda*v)/(1.-lbda); if(u < 1.E-10) { PhyML_Printf("\n. mu1 = %f lambda = %f v = %f u = %G beg = %f end = %f",mu1,lbda,v,u,beg,end); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dens += Dgamma_Moments(u,mean,var) / (1.-lbda) * ndb * POW(1.-lbda,n-1); lbda = end; u = (mu1 - lbda*v)/(1.-lbda); if(u < 1.E-10) { PhyML_Printf("\n. u = %G",u); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } dens += Dgamma_Moments(u,mean,var) / (1.-lbda) * ndb * POW(1.-lbda,n-1); dens *= (h/2.); dens *= dt1; } return(dens); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Joint density of mu1 and a minimum number of jumps occuring in the interval dt1+dt2 given mu1. 1 jump occurs at the junction of the two intervals, which makes mu1 and mu2 independant */ phydbl RATES_Dmu2_And_Mu1_Given_Min_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n_min, phydbl a, phydbl b, phydbl lexp) { phydbl density, lexpdt,cumpoiss,poiss; int i; int up,down; density = 0.0; lexpdt = lexp * (dt1+dt2); cumpoiss = 0.0; RATES_Bracket_N_Jumps(&up,&down,lexpdt); For(i,MAX(up,n_min)-1) { poiss = Dpois(i,lexpdt,NO); cumpoiss = cumpoiss + poiss; } for(i=MAX(up,n_min);i 1.-1.E-6) break; } if(density < 0.0) { PhyML_Printf("\n. density=%f cmpoiss = %f i=%d n_min=%d mu1=%f mu2=%f dt1=%f dt2=%f", density,cumpoiss,i,n_min,mu1,mu2,dt1,dt2); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } return(density); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Joint density of mu1 and mu2 given the number of jumps (n) in the interval dt1+dt2, which are considered as independant. Hence, for n jumps occuring in dt1+dt2, the number of jumps occuring in dt1 and dt2 are n and 0, or n-1 and 1, or n-2 and 2 ... or 0 and n. This function sums over all these scenarios, with weights corresponding to the probability of each partitition. */ phydbl RATES_Dmu2_And_Mu1_Given_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n, phydbl a, phydbl b, phydbl lexp) { phydbl density,cumpoiss,poiss,abb,ab,LOGnf,LOGdt1,LOGdt2,nLOGdt; int i; density = 0.0; abb = a*b*b; ab = a*b; cumpoiss = 0.0; poiss = 0.0; LOGnf = LnFact(n); LOGdt1 = LOG(dt1); LOGdt2 = LOG(dt2); nLOGdt = n*LOG(dt1+dt2); For(i,n+1) { poiss = LOGnf - LnFact(i) - LnFact(n-i) + i*LOGdt1 + (n-i)*LOGdt2 - nLOGdt; poiss = EXP(poiss); cumpoiss = cumpoiss + poiss; if(mu2 < 1.E-10) { PhyML_Printf("\n. mu2=%f",mu2); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(mu1 < 1.E-10) { PhyML_Printf("\n. mu1=%f",mu1); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } density = density + poiss * Dgamma_Moments(mu2,ab,2./((n-i)+2.)*abb) * Dgamma_Moments(mu1,ab,2./(i+2.)*abb); if(cumpoiss > 1.-1.E-6) break; } return(density); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Initialize_True_Rates(t_tree *tree) { int i; For(i,2*tree->n_otu-2) tree->rates->true_r[i] = tree->rates->br_r[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Rates_From_Bl(t_tree *tree) { phydbl dt,cr; t_node *left, *rght; int i; dt = -1.0; cr = tree->rates->clock_r; if(tree->n_root) { dt = FABS(tree->rates->nd_t[tree->n_root->num] - tree->rates->nd_t[tree->n_root->v[2]->num]); tree->rates->br_r[tree->n_root->v[2]->num] = 0.5 * tree->e_root->l->v / (dt*cr); dt = FABS(tree->rates->nd_t[tree->n_root->num] - tree->rates->nd_t[tree->n_root->v[1]->num]); tree->rates->br_r[tree->n_root->v[1]->num] = 0.5 * tree->e_root->l->v / (dt*cr); } For(i,2*tree->n_otu-3) { if(tree->a_edges[i] != tree->e_root) { left = tree->a_edges[i]->left; rght = tree->a_edges[i]->rght; dt = FABS(tree->rates->nd_t[left->num] - tree->rates->nd_t[rght->num]); if(left->anc == rght) tree->rates->br_r[left->num] = tree->a_edges[i]->l->v / (dt*cr); else tree->rates->br_r[rght->num] = tree->a_edges[i]->l->v / (dt*cr); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Lk_Jumps(t_tree *tree) { int i,n_jps; phydbl dens,dt,lexp; t_node *n; n = NULL; lexp = tree->rates->lexp; n_jps = 0; dt = 0.0; dens = 0.0; For(i,2*tree->n_otu-2) { n = tree->a_nodes[i]; dt = FABS(tree->rates->nd_t[n->num]-tree->rates->nd_t[n->anc->num]); n_jps = tree->rates->n_jps[n->num]; dens += Dpois(n_jps,lexp*dt,YES); } tree->rates->c_lnL_jps = dens; return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Posterior_Rates(t_tree *tree) { int node_num; node_num = Rand_Int(0,2*tree->n_otu-3); RATES_Posterior_One_Rate(tree->a_nodes[node_num]->anc,tree->a_nodes[node_num],NO,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Posterior_Times(t_tree *tree) { int node_num; node_num = Rand_Int(tree->n_otu,2*tree->n_otu-3); RATES_Posterior_One_Time(tree->a_nodes[node_num]->anc,tree->a_nodes[node_num],NO,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree) { phydbl like_mean, like_var; phydbl prior_mean, prior_var; phydbl post_mean, post_var, post_sd; phydbl dt,rd,cr,cel,cvl; int dim; phydbl l_opp; /* length of the branch connected to the root, opposite to the one connected to d */ t_edge *b; int i; t_node *v2,*v3; phydbl T0,T1,T2,T3; phydbl U0,U1,U2,U3; phydbl V1,V2,V3; phydbl r_min,r_max; int err; phydbl ratio,u; phydbl cvr, cer; phydbl nf; phydbl new_lnL_data, cur_lnL_data, new_lnL_rate, cur_lnL_rate; phydbl sd1,sd2,sd3; phydbl inflate_var; if(d == tree->n_root) return; dim = 2*tree->n_otu-3; err = NO; inflate_var = tree->rates->inflate_var; b = NULL; if(a == tree->n_root) b = tree->e_root; else For(i,3) if(d->v[i] == a) { b = d->b[i]; break; } v2 = v3 = NULL; if(!d->tax) { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v2) { v2 = d->v[i]; } else { v3 = d->v[i]; } } } T3 = T2 = 0.0; T0 = tree->rates->nd_t[a->num]; T1 = tree->rates->nd_t[d->num]; U0 = tree->rates->br_r[a->num]; U1 = tree->rates->br_r[d->num]; U3 = U2 = -1.0; if(!d->tax) { T2 = tree->rates->nd_t[v2->num]; T3 = tree->rates->nd_t[v3->num]; U2 = tree->rates->br_r[v2->num]; U3 = tree->rates->br_r[v3->num]; } V1 = tree->rates->nu * FABS(T1 - T0); V2 = tree->rates->nu * FABS(T2 - T1); V3 = tree->rates->nu * FABS(T3 - T1); dt = T1 - T0; rd = U1; cr = tree->rates->clock_r; r_min = tree->rates->min_rate; r_max = tree->rates->max_rate; nf = tree->rates->norm_fact; sd1 = SQRT(V1); sd2 = SQRT(V2); sd3 = SQRT(V3); /* Likelihood */ cel=0.0; For(i,dim) if(i != b->num) cel += tree->rates->reg_coeff[b->num*dim+i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]); cel += tree->rates->mean_l[b->num]; cvl = tree->rates->cond_var[b->num]; l_opp = 0.0; if(a == tree->n_root) { if(d == a->v[0]) l_opp = tree->rates->cur_l[a->v[1]->num]; else l_opp = tree->rates->cur_l[a->v[0]->num]; cel -= l_opp; } if(isnan(cvl) || isnan(cel) || cvl < .0) { For(i,dim) if(i != b->num) printf("\n. reg: %f %f %f nu=%f clock=%f", tree->rates->reg_coeff[b->num*dim+i], tree->rates->u_cur_l[i], tree->rates->mean_l[i], tree->rates->nu,tree->rates->clock_r); PhyML_Printf("\n. cel=%f cvl=%f\n",cel,cvl); PhyML_Printf("\n. Warning: invalid expected and/or std. dev. values. Skipping this step.\n"); Exit("\n"); } /* Model rates */ /* if(tree->mod->log_l == YES) cel = EXP(cel); */ /* like_mean = cel / (dt*cr*nf); */ /* like_var = cvl / POW(dt*cr*nf,2); */ /* Model log of rates. Branch lengths are given in log units */ if(tree->rates->model_log_rates == YES) { like_mean = cel - LOG(dt*cr*nf); like_var = cvl - 2.*LOG(dt*cr*nf); } else { like_mean = cel / (dt*cr*nf); like_var = cvl / POW(dt*cr*nf,2); } /* Prior */ if(!d->tax) { cvr = 1./(1./V1 + 1./V2 + 1./V3); cer = cvr*(U0/V1 + U2/V2 + U3/V3); } else { cvr = V1; cer = U0; } if(cvr < 0.0) { PhyML_Printf("\n. cvr=%f d->tax=%d V1=%f v2=%f V3=%f",cvr,d->tax,V1,V2,V3); PhyML_Printf("\n. T0=%f T1=%f T2=%f T3=%f",T0,T1,T2,T3); Exit("\n"); } prior_mean = cer; prior_var = cvr; /* Posterior */ post_mean = (prior_mean/prior_var + like_mean/like_var)/(1./prior_var + 1./like_var); post_var = 1./(1./prior_var + 1./like_var); /* Sample according to priors */ if(tree->mcmc->use_data == NO) { post_mean = prior_mean; post_var = prior_var; } post_sd = SQRT(post_var); rd = Rnorm_Trunc(post_mean,inflate_var*post_sd,r_min,r_max,&err); if(err || isnan(rd)) { PhyML_Printf("\n"); PhyML_Printf("\n. run: %d err=%d d->tax=%d",tree->mcmc->run,err,d->tax); PhyML_Printf("\n. rd=%f cvr=%G dt=%G cr=%G",rd,cvr,dt,cr); PhyML_Printf("\n. prior_mean = %G prior_var = %G",prior_mean,prior_var); PhyML_Printf("\n. like_mean = %G like_var = %G",like_mean,like_var); PhyML_Printf("\n. post_mean = %G post_var = %G",post_mean,post_var); PhyML_Printf("\n. clock_r = %f",tree->rates->clock_r); PhyML_Printf("\n. T0=%f T1=%f T2=%f T3=%f",T0,T1,T2,T3); PhyML_Printf("\n. U0=%f U1=%f U2=%f U3=%f",U0,U1,U2,U3); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } /* !!!!!!!!!!!!!! */ /* u = Uni(); */ /* rd = U1 * EXP(1.*(u-0.5)); */ if(rd > r_min && rd < r_max) { cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_data = tree->c_lnL; new_lnL_rate = tree->rates->c_lnL_rates; tree->rates->br_r[d->num] = rd; RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl(tree); if(tree->mcmc->use_data) new_lnL_data = Lk(b,tree); /* new_lnL_rate = RATES_Lk_Rates(tree); */ new_lnL_rate = cur_lnL_rate - (Log_Dnorm_Trunc(U1,U0,sd1,r_min,r_max,&err)) + (Log_Dnorm_Trunc(rd,U0,sd1,r_min,r_max,&err)); if(!d->tax) { new_lnL_rate -= (Log_Dnorm_Trunc(U2,U1,sd2,r_min,r_max,&err) + Log_Dnorm_Trunc(U3,U1,sd3,r_min,r_max,&err)); new_lnL_rate += (Log_Dnorm_Trunc(U2,rd,sd2,r_min,r_max,&err) + Log_Dnorm_Trunc(U3,rd,sd3,r_min,r_max,&err)); } tree->rates->c_lnL_rates = new_lnL_rate; /* printf("\n. %f %f sd1=%f U1=%f rd=%f ra=%f a=%d d=%d [%f] [%f %f]", */ /* new_lnL_rate,RATES_Lk_Rates(tree),sd1,U1,rd,ra,a->num,d->num,tree->rates->br_r[tree->n_root->num], */ /* Log_Dnorm_Trunc(U1,ra,sd1,r_min,r_max,&err), */ /* Log_Dnorm_Trunc(rd,ra,sd1,r_min,r_max,&err)); */ ratio = 0.0; /* Proposal ratio */ ratio += (Log_Dnorm_Trunc(U1,post_mean,inflate_var*post_sd,r_min,r_max,&err) - Log_Dnorm_Trunc(rd,post_mean,inflate_var*post_sd,r_min,r_max,&err)); /* ratio += LOG(rd/U1); */ /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); /* Likelihood ratio */ ratio += (new_lnL_data - cur_lnL_data); ratio = EXP(ratio); /* printf("\n. R a=%3d T0=%6.1f T1=%6.1f T2=%6.1f T3=%6.1f ratio=%8f pm=%7f U1=%7.2f rd=%7.2f %f %f lr=%f %f ld=%f %f [%f]",a->num,T0,T1,T2,T3,ratio,post_mean,U1,rd, */ /* Log_Dnorm_Trunc(U1,post_mean,post_sd,r_min,r_max,&err), */ /* Log_Dnorm_Trunc(rd,post_mean,post_sd,r_min,r_max,&err), */ /* new_lnL_rate,cur_lnL_rate, */ /* new_lnL_data,cur_lnL_data, */ /* ((Pnorm(r_max,U1,sd2)-Pnorm(r_min,U1,sd2)) * */ /* (Pnorm(r_max,U1,sd3)-Pnorm(r_min,U1,sd3)))/ */ /* ((Pnorm(r_max,rd,sd2)-Pnorm(r_min,rd,sd2)) * */ /* (Pnorm(r_max,rd,sd3)-Pnorm(r_min,rd,sd3)))); */ u = Uni(); if(u > MIN(1.,ratio)) { tree->rates->br_r[d->num] = U1; /* reject */ tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; RATES_Update_Cur_Bl(tree); Update_PMat_At_Given_Edge(b,tree); } else { tree->mcmc->acc_move[tree->mcmc->num_move_br_r+d->num]++; } RATES_Update_Norm_Fact(tree); tree->mcmc->acc_rate[tree->mcmc->num_move_br_r+d->num] = (tree->mcmc->acc_move[tree->mcmc->num_move_br_r+d->num]+1.E-6)/ (tree->mcmc->run_move[tree->mcmc->num_move_br_r+d->num]+1.E-6); } tree->mcmc->run_move[tree->mcmc->num_move_br_r+d->num]++; if(traversal == YES) { if(d->tax == YES) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */ RATES_Posterior_One_Rate(d,d->v[i],YES,tree); } } if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b,d); /* if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { tree->both_sides = YES; Lk(tree); } */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree) { /* T0 (a) | | l1,U1,b1 | T1 (d) / \ l2,u2,b2 / \ L3,u3,b3 / \ t2 t3 (v2) (v3) */ phydbl l1,l2,l3; phydbl new_l1; phydbl El1,El2,El3; phydbl u0,r1,r2,r3; phydbl t0,t1,t2,t3; phydbl t_min, t_max; /* phydbl t_max_12,t_max_13; */ phydbl bl_min, bl_max; phydbl t1_new; phydbl EX,EY; phydbl VX,VY; phydbl cr; int i,j; phydbl *mu, *cov; phydbl *cond_mu, *cond_cov; short int *is_1; phydbl sig11, sig1X, sig1Y, sigXX, sigXY, sigYY; phydbl cov11,cov12,cov13,cov22,cov23,cov33; int dim; t_edge *b1, *b2, *b3; t_node *v2,*v3; phydbl *l2XY; phydbl l_opp; t_edge *buff_b; t_node *buff_n; int err; int num_1, num_2, num_3; phydbl nf; phydbl u, ratio; phydbl new_lnL_data, cur_lnL_data, new_lnL_rate, cur_lnL_rate; int num_move; phydbl inflate_var; dim = 2*tree->n_otu-3; num_move = tree->mcmc->num_move_nd_t+d->num-tree->n_otu; inflate_var = tree->rates->inflate_var; if(d->tax) return; if(FABS(tree->rates->t_prior_min[d->num] - tree->rates->t_prior_max[d->num]) < 1.E-10) return; l2XY = tree->rates->_2n_vect2; mu = tree->rates->_2n_vect3; cov = tree->rates->_2n2n_vect1; cond_mu = tree->rates->_2n_vect1; cond_cov = tree->rates->_2n2n_vect2; is_1 = tree->rates->_2n_vect5; err = NO; b1 = NULL; if(a == tree->n_root) b1 = tree->e_root; else For(i,3) if(d->v[i] == a) { b1 = d->b[i]; break; } b2 = b3 = NULL; v2 = v3 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v2) { v2 = d->v[i]; b2 = d->b[i]; } else { v3 = d->v[i]; b3 = d->b[i]; } } t2 = tree->rates->nd_t[v2->num]; t3 = tree->rates->nd_t[v3->num]; buff_n = NULL; buff_b = NULL; if(t3 > t2) { buff_n = v2; v2 = v3; v3 = buff_n; buff_b = b2; b2 = b3; b3 = buff_b; } t0 = tree->rates->nd_t[a->num]; t1 = tree->rates->nd_t[d->num]; t2 = tree->rates->nd_t[v2->num]; t3 = tree->rates->nd_t[v3->num]; u0 = tree->rates->br_r[a->num]; r1 = tree->rates->br_r[d->num]; r2 = tree->rates->br_r[v2->num]; r3 = tree->rates->br_r[v3->num]; l1 = tree->rates->cur_l[d->num]; l2 = tree->rates->cur_l[v2->num]; l3 = tree->rates->cur_l[v3->num]; cr = tree->rates->clock_r; nf = tree->rates->norm_fact; For(i,dim) is_1[i] = 0; is_1[b1->num] = 1; is_1[b2->num] = 1; is_1[b3->num] = 1; /* For(i,dim) cond_mu[i] = 0.0; */ /* For(i,dim*dim) cond_cov[i] = 0.0; */ /* Normal_Conditional(tree->rates->mean_l,tree->rates->cov_l,tree->rates->u_cur_l,dim,is_1,3,cond_mu,cond_cov); */ /* El1 = cond_mu[b1->num]; */ /* El2 = cond_mu[b2->num]; */ /* El3 = cond_mu[b3->num]; */ /* cov11 = cond_cov[b1->num*dim+b1->num]; */ /* cov12 = cond_cov[b1->num*dim+b2->num]; */ /* cov13 = cond_cov[b1->num*dim+b3->num]; */ /* cov23 = cond_cov[b2->num*dim+b3->num]; */ /* cov22 = cond_cov[b2->num*dim+b2->num]; */ /* cov33 = cond_cov[b3->num*dim+b3->num]; */ /* El1 = tree->rates->u_ml_l[b1->num]; */ /* El2 = tree->rates->u_ml_l[b2->num]; */ /* El3 = tree->rates->u_ml_l[b3->num]; */ /* cov11 = tree->rates->cov[b1->num*dim+b1->num]; */ /* cov12 = tree->rates->cov[b1->num*dim+b2->num]; */ /* cov13 = tree->rates->cov[b1->num*dim+b3->num]; */ /* cov23 = tree->rates->cov[b2->num*dim+b3->num]; */ /* cov22 = tree->rates->cov[b2->num*dim+b2->num]; */ /* cov33 = tree->rates->cov[b3->num*dim+b3->num]; */ /* PhyML_Printf("\n- El1=%10f El2=%10f El3=%10f",El1,El2,El3); */ /* PhyML_Printf("\n- cov11=%10f cov12=%10f cov13=%10f cov23=%10f cov22=%10f cov33=%10f", cov11,cov12,cov13,cov23,cov22,cov33); */ num_1 = num_2 = num_3 = -1; if(b1->num < b2->num && b2->num < b3->num) { num_1 = 0; num_2 = 1; num_3 = 2; } if(b1->num < b3->num && b3->num < b2->num) { num_1 = 0; num_2 = 2; num_3 = 1; } if(b2->num < b1->num && b1->num < b3->num) { num_1 = 1; num_2 = 0; num_3 = 2; } if(b2->num < b3->num && b3->num < b1->num) { num_1 = 2; num_2 = 0; num_3 = 1; } if(b3->num < b2->num && b2->num < b1->num) { num_1 = 2; num_2 = 1; num_3 = 0; } if(b3->num < b1->num && b1->num < b2->num) { num_1 = 1; num_2 = 2; num_3 = 0; } cov11 = tree->rates->trip_cond_cov[d->num * 9 + num_1 * 3 + num_1]; cov12 = tree->rates->trip_cond_cov[d->num * 9 + num_1 * 3 + num_2]; cov13 = tree->rates->trip_cond_cov[d->num * 9 + num_1 * 3 + num_3]; cov23 = tree->rates->trip_cond_cov[d->num * 9 + num_2 * 3 + num_3]; cov22 = tree->rates->trip_cond_cov[d->num * 9 + num_2 * 3 + num_2]; cov33 = tree->rates->trip_cond_cov[d->num * 9 + num_3 * 3 + num_3]; El1=0.0; For(i,dim) if(i != b1->num && i != b2->num && i != b3->num) El1 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_1 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]); El1 += tree->rates->mean_l[b1->num]; El2=0.0; For(i,dim) if(i != b1->num && i != b2->num && i != b3->num) El2 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_2 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]); El2 += tree->rates->mean_l[b2->num]; El3=0.0; For(i,dim) if(i != b1->num && i != b2->num && i != b3->num) El3 += tree->rates->trip_reg_coeff[d->num * (6*tree->n_otu-9) + num_3 * dim +i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]); El3 += tree->rates->mean_l[b3->num]; /* PhyML_Printf("\n+ El1=%10f El2=%10f El3=%10f",El1,El2,El3); */ /* PhyML_Printf("\n+ cov11=%10f cov12=%10f cov13=%10f cov23=%10f cov22=%10f cov33=%10f", cov11,cov12,cov13,cov23,cov22,cov33); */ t1_new = +1; t_min = MAX(t0,tree->rates->t_prior_min[d->num]); t_max = MIN(MIN(t2,t3),tree->rates->t_prior_max[d->num]); t_min += tree->rates->min_dt; t_max -= tree->rates->min_dt; if(t_min > t_max) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } bl_min = bl_max = -1.0; l_opp = 0.0; if(a == tree->n_root) { l_opp = (d == a->v[0])?(tree->rates->cur_l[a->v[1]->num]):(tree->rates->cur_l[a->v[0]->num]); El1 -= l_opp; } EX = El1/r1 + El2/r2; EY = El1/r1 + El3/r3; VX = cov11/(r1*r1) + cov22/(r2*r2) + 2.*cov12/(r1*r2); VY = cov11/(r1*r1) + cov33/(r3*r3) + 2.*cov13/(r1*r3); mu[0] = El1; mu[1] = EX; mu[2] = EY; sig11 = cov11; sig1X = cov11/r1 + cov12/r2; sig1Y = cov11/r1 + cov13/r3; sigXX = VX; sigYY = VY; sigXY = cov11/(r1*r1) + cov13/(r1*r3) + cov12/(r1*r2) + cov23/(r2*r3); cov[0*3+0] = sig11; cov[0*3+1] = sig1X; cov[0*3+2] = sig1Y; cov[1*3+0] = sig1X; cov[1*3+1] = sigXX; cov[1*3+2] = sigXY; cov[2*3+0] = sig1Y; cov[2*3+1] = sigXY; cov[2*3+2] = sigYY; l2XY[0] = 0.0; /* does not matter */ l2XY[1] = (t2-t0)*cr*nf; /* constraint 1 */ l2XY[2] = (t3-t0)*cr*nf; /* constraint 2 */ is_1[0] = is_1[1] = is_1[2] = 0; is_1[0] = 1; Normal_Conditional(mu,cov,l2XY,3,is_1,1,cond_mu,cond_cov); if(cond_cov[0*3+0] < 0.0) { PhyML_Printf("\n. a: %d d: %d",a->num,d->num); PhyML_Printf("\n. Conditional mean=%G var=%G",cond_mu[0],cond_cov[0*3+0]); PhyML_Printf("\n. t0=%G t1=%f t2=%f t3=%f l1=%G l2=%G l3=%G",t0,t1,t2,t3,l1,l2,l3); PhyML_Printf("\n. El1=%G El2=%G El3=%G Nu=%G r1=%G r2=%G r3=%G cr=%G",El1,El2,El3,tree->rates->nu,r1,r2,r3,cr); PhyML_Printf("\n. COV11=%f COV12=%f COV13=%f COV22=%f COV23=%f COV33=%f",cov11,cov12,cov13,cov22,cov23,cov33); PhyML_Printf("\n. constraint1: %f constraints2: %f",l2XY[1],l2XY[2]); PhyML_Printf("\n"); For(i,3) { PhyML_Printf(". mu%d=%12lf\t",i,mu[i]); For(j,3) { PhyML_Printf("%12lf ",cov[i*3+j]); } PhyML_Printf("\n"); } cond_cov[0*3+0] = 1.E-10; } bl_min = (t_min - t0) * r1 * cr * nf; bl_max = (t_max - t0) * r1 * cr * nf; new_l1 = Rnorm_Trunc(cond_mu[0],inflate_var*SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err); /* new_l1 = Rnorm(cond_mu[0],SQRT(cond_cov[0*3+0])); */ if(new_l1 < bl_min) new_l1 = l1; if(new_l1 > bl_max) new_l1 = l1; t1_new = new_l1/(r1*cr*nf) + t0; if(err) { PhyML_Printf("\n"); PhyML_Printf("\n. Root ? %s",(tree->n_root==a)?("yes"):("no")); PhyML_Printf("\n. %s %d %d",__FILE__,__LINE__,tree->mcmc->run); PhyML_Printf("\n. t0=%f t1=%f t2=%f t3=%f",t0,t1,t2,t3); PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n. bl_min=%f bl_max=%f",bl_min,bl_max); PhyML_Printf("\n. cond_mu[0]=%f cond_cov[0]=%f",cond_mu[0],SQRT(cond_cov[0*3+0])); PhyML_Printf("\n. El1=%f El2=%f El3=%f",El1,El2,El3); PhyML_Printf("\n. l1=%f l2=%f l3=%f",l1,l2,l3); PhyML_Printf("\n. u0=%f r1=%f r2=%f r3=%f",u0,r1,r2,r3); PhyML_Printf("\n. COV11=%f COV22=%f",cov11,cov22); PhyML_Printf("\n. Clock rate = %f",tree->rates->clock_r); PhyML_Printf("\n. Setting t1_new to %f",t1); t1_new = t1; /* Exit("\n"); */ } /* } */ /* else */ /* { */ /* bl_min = (t2 - t_max) * r2; */ /* bl_max = (t2 - t_min) * r2; */ /* l2 = Rnorm_Trunc(cond_mu[0],SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err); */ /* t1_new = -l2/r2 + t2; */ /* if(err) */ /* { */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n. %s %d %d",__FILE__,__LINE__,tree->mcmc->run); */ /* PhyML_Printf("\n. t0=%f t1=%f t2=%f t3=%f",t0,t1,t2,t3); */ /* PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); */ /* PhyML_Printf("\n. bl_min=%f bl_max=%f",bl_min,bl_max); */ /* PhyML_Printf("\n. cond_mu[0]=%f cond_cov[0]=%f",cond_mu[0],SQRT(cond_cov[0*3+0])); */ /* PhyML_Printf("\n. El1=%f El2=%f El3=%f",El1,El2,El3); */ /* PhyML_Printf("\n. l1=%f l2=%f l3=%f",l1,l2,l3); */ /* PhyML_Printf("\n. u0=%f r1=%f r2=%f r3=%f",u0,r1,r2,r3); */ /* PhyML_Printf("\n. COV11=%f COV22=%f",cov11,cov22); */ /* PhyML_Printf("\n. Clock rate = %f",tree->rates->clock_r); */ /* PhyML_Printf("\n. Setting t1_new to %f",t1); */ /* t1_new = t1; */ /* /\* Exit("\n"); *\/ */ /* } */ /* } */ if(t1_new < t0) { t1_new = t0+1.E-4; PhyML_Printf("\n"); PhyML_Printf("\n. a is root -> %s",(a == tree->n_root)?("YES"):("NO")); PhyML_Printf("\n. t0 = %f t1_new = %f t1 = %f",t0,t1_new,t1); PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n. l1 = %f",l1); PhyML_Printf("\n. bl_min = %f bl_max = %f",bl_min,bl_max); PhyML_Printf("\n. (t1-t0)=%f (t2-t1)=%f",t1-t0,t2-t1); PhyML_Printf("\n. l1 = %f l2 = %f cov11=%f cov22=%f cov33=%f",l1,l2,cov11,cov22,cov33); PhyML_Printf("\n. clock=%G",tree->rates->clock_r); PhyML_Printf("\n. u0=%f r1=%f r2=%f r3=%f",u0,r1,r2,r3); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(t1_new > MIN(t2,t3)) { PhyML_Printf("\n"); PhyML_Printf("\n. a is root -> %s",(a == tree->n_root)?("YES"):("NO")); PhyML_Printf("\n. t0 = %f t1_new = %f t1 = %f t2 = %f t3 = %f MIN(t2,t3)=%f",t0,t1_new,t1,t2,t3,MIN(t2,t3)); PhyML_Printf("\n. t_min=%f t_max=%f",t_min,t_max); PhyML_Printf("\n. l2 = %f",l2); PhyML_Printf("\n. bl_min = %f bl_max = %f",bl_min,bl_max); PhyML_Printf("\n. (t1-t0)=%f (t2-t1)=%f",t1-t0,t2-t1); PhyML_Printf("\n. l1 = %f l2 = %f cov11=%f cov22=%f cov33=%f",l1,l2,cov11,cov22,cov33); PhyML_Printf("\n. clock=%G",tree->rates->clock_r); PhyML_Printf("\n. u0=%f r1=%f r2=%f r3=%f",u0,r1,r2,r3); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(isnan(t1_new)) { PhyML_Printf("\n. run=%d",tree->mcmc->run); PhyML_Printf("\n. mean=%G var=%G",cond_mu[0],cond_cov[0*3+0]); PhyML_Printf("\n. t1=%f l1=%G r1=%G t0=%G",t1,l1,r1,t0); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); /* Exit("\n"); */ } if(tree->mcmc->use_data == YES) tree->rates->nd_t[d->num] = t1_new; else { u = Uni(); tree->rates->nd_t[d->num] = u*(t_max-t_min) + t_min; } RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl(tree); cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_data = tree->c_lnL; new_lnL_rate = tree->rates->c_lnL_rates; if(tree->mcmc->use_data) { /* !!!!!!!!!!!!!!!!! */ /* tree->both_sides = NO; */ /* new_lnL_data = Lk(tree); */ if(tree->io->lk_approx == EXACT) { Update_PMat_At_Given_Edge(b1,tree); Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); Update_P_Lk(tree,b1,d); } new_lnL_data = Lk(b1,tree); } new_lnL_rate = RATES_Lk_Rates(tree); ratio = 0.0; /* Proposal ratio */ if(tree->mcmc->use_data) ratio += (Log_Dnorm_Trunc(l1, cond_mu[0],inflate_var*SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err) - Log_Dnorm_Trunc(new_l1,cond_mu[0],inflate_var*SQRT(cond_cov[0*3+0]),bl_min,bl_max,&err)); /* Prior ratio */ ratio += (new_lnL_rate - cur_lnL_rate); /* Likelihood ratio */ ratio += (new_lnL_data - cur_lnL_data); /* printf("\n* d:%d Ratio=%f l1=%f new_l1=%f mean=%f ml=%f sd=%f [%f %f]", */ /* d->num, */ /* EXP(ratio), */ /* l1,new_l1, */ /* cond_mu[0], */ /* tree->rates->mean_l[b1->num], */ /* SQRT(cond_cov[0*3+0]), */ /* Log_Dnorm(l1,cond_mu[0],SQRT(cond_cov[0*3+0]),&err),Log_Dnorm(new_l1,cond_mu[0],SQRT(cond_cov[0*3+0]),&err)); */ ratio = EXP(ratio); u = Uni(); if(u > MIN(1.,ratio)) { tree->rates->nd_t[d->num] = t1; /* reject */ tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; RATES_Update_Cur_Bl(tree); if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) { Update_PMat_At_Given_Edge(b1,tree); Update_PMat_At_Given_Edge(b2,tree); Update_PMat_At_Given_Edge(b3,tree); Update_P_Lk(tree,b1,d); } } else { tree->mcmc->acc_move[num_move]++; } RATES_Update_Norm_Fact(tree); tree->mcmc->run_move[num_move]++; if(traversal == YES) { if(d->tax == YES) return; else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) { if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,d->b[i],d); RATES_Posterior_One_Time(d,d->v[i],YES,tree); } } if(tree->io->lk_approx == EXACT && tree->mcmc->use_data) Update_P_Lk(tree,b1,d); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Posterior_Time_Root(t_tree *tree) { /* Root, T0 / \ l1 / \ l2 / \ v1,t1 v2,t2 */ phydbl t1,t2; phydbl u0,u1,u2; phydbl cel,cvl; int i,dim; t_edge *b; t_node *root; phydbl t0,t0_min, t0_max; phydbl new_t0; /* phydbl t_max_01, t_max_02; */ int err; phydbl cr; phydbl bl_min, bl_max; phydbl new_l; phydbl new_lnL_data, cur_lnL_data, cur_lnL_rate; phydbl u,ratio; dim = 2*tree->n_otu-3; b = tree->e_root; root = tree->n_root; t0 = tree->rates->nd_t[root->num]; t1 = tree->rates->nd_t[root->v[2]->num]; t2 = tree->rates->nd_t[root->v[1]->num]; u1 = tree->rates->br_r[root->v[2]->num]; u2 = tree->rates->br_r[root->v[1]->num]; u0 = 1.0; cr = tree->rates->clock_r; t0_min = -BIG; t0_max = MIN(t1,t2); /* t0_max = MIN(t1 - (1./tree->rates->nu)*POW((u0-u1)/tree->rates->z_max,2), */ /* t2 - (1./tree->rates->nu)*POW((u0-u2)/tree->rates->z_max,2)); */ /* if(u1 > u0) t_max_01 = t1 - (1./tree->rates->nu)*POW((u1-u0)/(PointNormal(tree->rates->p_max*Pnorm(.0,.0,1.))),2); */ /* else t_max_01 = t1 - (1./tree->rates->nu)*POW((u1-u0)/(PointNormal(tree->rates->p_max*(1.-Pnorm(.0,.0,1.)))),2); */ /* if(u2 > u0) t_max_02 = t2 - (1./tree->rates->nu)*POW((u2-u0)/(PointNormal(tree->rates->p_max*Pnorm(.0,.0,1.))),2); */ /* else t_max_02 = t2 - (1./tree->rates->nu)*POW((u2-u0)/(PointNormal(tree->rates->p_max*(1.-Pnorm(.0,.0,1.)))),2); */ /* t_max_01 = RATES_Find_Max_Dt_Bisec(u1,u0,tree->rates->t_prior_min[root->num],t1,tree->rates->nu,tree->rates->p_max,(u1 < u0)?YES:NO); */ /* t_max_02 = RATES_Find_Max_Dt_Bisec(u2,u0,tree->rates->t_prior_min[root->num],t2,tree->rates->nu,tree->rates->p_max,(u2 < u0)?YES:NO); */ /* t0_max = MIN(t_max_01,t_max_02); */ /* RATES_Min_Max_Interval(u0,u1,u2,r3,t0,t2,t3,&t_min,&t_max,tree->rates->nu,tree->rates->p_max,tree); */ t0_min = MAX(t0_min,tree->rates->t_prior_min[root->num]); t0_max = MIN(t0_max,tree->rates->t_prior_max[root->num]); t0_max -= tree->rates->min_dt; if(t0_min > t0_max) return; tree->rates->t_prior[root->num] = Uni()*(t0_max - t0_min) + t0_min; u0 *= cr; u1 *= cr; u2 *= cr; if(FABS(tree->rates->t_prior_min[root->num] - tree->rates->t_prior_max[root->num]) < 1.E-10) return; cel=0.0; For(i,dim) if(i != b->num) cel += tree->rates->reg_coeff[b->num*dim+i] * (tree->rates->u_cur_l[i] - tree->rates->mean_l[i]); cel += tree->rates->mean_l[b->num]; cvl = tree->rates->cond_var[b->num]; bl_min = u1 * (t1 - t0_max) + u2 * (t2 - t0_max); bl_max = u1 * (t1 - t0_min) + u2 * (t2 - t0_min); if(bl_min > bl_max) return; new_l = Rnorm_Trunc(cel,SQRT(cvl),bl_min,bl_max,&err); new_t0 = (u1*t1 + u2*t2 - new_l)/(u1+u2); if(t0 > t1 || t0 > t2) { PhyML_Printf("\n"); PhyML_Printf("\n. Run = %d",tree->mcmc->run); PhyML_Printf("\n. t0=%f t1=%f t2=%f",t0,t1,t2); PhyML_Printf("\n. t0_min=%f t0_max=%f",t0_min,t0_max); PhyML_Printf("\n. new_l=%f cel=%f",new_l,cel); PhyML_Printf("\n. u0=%f u1=%f u2=%f",u0/cr,u1/cr,u2/cr); PhyML_Printf("\n. Nu = %f Clock = %f",tree->rates->nu,tree->rates->clock_r); PhyML_Printf("\n. Setting t0 to %f",tree->rates->nd_t[root->num]); return; } if(t0 < t0_min || t0 > t0_max) { PhyML_Printf("\n"); PhyML_Printf("\n. Run = %d",tree->mcmc->run); PhyML_Printf("\n. t0=%f t1=%f t2=%f",t0,t1,t2); PhyML_Printf("\n. t0_min=%f t0_max=%f",t0_min,t0_max); PhyML_Printf("\n. u0=%f u1=%f u2=%f",u0/cr,u1/cr,u2/cr); PhyML_Printf("\n. Nu = %f Clock = %f",tree->rates->nu,tree->rates->clock_r); PhyML_Printf("\n. Setting t0 to %f",tree->rates->nd_t[root->num]); t0 = tree->rates->nd_t[root->num]; } /* Sample according to prior */ /* tree->rates->nd_t[root->num] = tree->rates->t_prior[root->num]; */ /* Sample according to posterior */ tree->rates->nd_t[root->num] = new_t0; RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl(tree); cur_lnL_data = tree->c_lnL; cur_lnL_rate = tree->rates->c_lnL_rates; new_lnL_data = tree->c_lnL; if(tree->mcmc->use_data) new_lnL_data = Lk(NULL,tree); ratio = 0.0; /* Prior ratio */ ratio += .0; /* Likelihood ratio */ ratio += new_lnL_data - cur_lnL_data; ratio = EXP(ratio); u = Uni(); if(u > MIN(1.,ratio)) { tree->rates->nd_t[root->num] = t0; /* reject */ tree->rates->c_lnL_rates = cur_lnL_rate; tree->c_lnL = cur_lnL_data; } else { tree->mcmc->acc_move[tree->mcmc->num_move_nd_t]++; } RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl(tree); tree->mcmc->run_move[tree->mcmc->num_move_nd_t]++; tree->mcmc->acc_rate[tree->mcmc->num_move_nd_t] = (tree->mcmc->acc_move[tree->mcmc->num_move_nd_t]+1.E-6)/ (tree->mcmc->run_move[tree->mcmc->num_move_nd_t]+1.E+6); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Cur_Bl(t_tree *tree) { RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl_Pre(tree->n_root,tree->n_root->v[2],NULL,tree); RATES_Update_Cur_Bl_Pre(tree->n_root,tree->n_root->v[1],NULL,tree); if(tree->mod && tree->mod->log_l == YES) { tree->e_root->l->v = EXP(tree->rates->cur_l[tree->n_root->v[2]->num]) + EXP(tree->rates->cur_l[tree->n_root->v[1]->num]) ; tree->e_root->l->v = LOG(tree->e_root->l->v); } else { tree->e_root->l->v = tree->rates->cur_l[tree->n_root->v[2]->num] + tree->rates->cur_l[tree->n_root->v[1]->num] ; } tree->rates->u_cur_l[tree->e_root->num] = tree->e_root->l->v; tree->n_root_pos = tree->rates->cur_l[tree->n_root->v[2]->num] / tree->e_root->l->v; if(tree->rates->model == GUINDON) { phydbl t0,t1,t2; t_node *n0, *n1; n0 = tree->n_root->v[2]; n1 = tree->n_root->v[1]; t1 = tree->rates->nd_t[tree->n_root->v[2]->num]; t2 = tree->rates->nd_t[tree->n_root->v[1]->num]; t0 = tree->rates->nd_t[tree->n_root->num]; tree->e_root->l->v = (t1-t0)/(t1+t2-2.*t0)*tree->rates->cur_gamma_prior_mean[n0->num] + (t2-t0)/(t1+t2-2.*t0)*tree->rates->cur_gamma_prior_mean[n1->num]; tree->e_root->l_var->v = POW((t1-t0)/(t1+t2-2.*t0),2)*tree->rates->cur_gamma_prior_var[n0->num] + POW((t2-t0)/(t1+t2-2.*t0),2)*tree->rates->cur_gamma_prior_var[n1->num]; /* printf("\n. ROOT: %f %f %f %f", */ /* tree->rates->cur_gamma_prior_mean[n0->num], */ /* tree->rates->cur_gamma_prior_var[n0->num], */ /* tree->rates->cur_gamma_prior_mean[n1->num], */ /* tree->rates->cur_gamma_prior_var[n1->num]); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { phydbl dt,rr,cr,ra,rd,ta,td,nu; tree->rates->br_do_updt[d->num] = YES; if(tree->rates->br_do_updt[d->num] == YES) { tree->rates->br_do_updt[d->num] = NO; dt = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]; cr = tree->rates->clock_r; rd = tree->rates->br_r[d->num]; ra = tree->rates->br_r[a->num]; td = tree->rates->nd_t[d->num]; ta = tree->rates->nd_t[a->num]; nu = tree->rates->nu; if(tree->rates->model_log_rates == YES) { /* Artihmetic average */ rr = (EXP(ra) + EXP(rd))/2.; } else { rr = (ra+rd)/2.; } tree->rates->cur_l[d->num] = dt*rr*cr; if(tree->rates->model == GUINDON) { phydbl m,v; Integrated_Geometric_Brownian_Bridge_Moments(dt,ra,rd,nu,&m,&v); m *= cr*dt; // the actual rate average is m * cr. We multiply by dt in order to derive the value for the branch length v *= (cr*cr)*(dt*dt); tree->rates->cur_gamma_prior_mean[d->num] = m; tree->rates->cur_gamma_prior_var[d->num] = v; tree->rates->cur_l[d->num] = tree->rates->cur_gamma_prior_mean[d->num]; // Required for having proper branch lengths in Write_Tree function } if(tree->mod && tree->mod->log_l == YES) tree->rates->cur_l[d->num] = LOG(tree->rates->cur_l[d->num]); if(b) { b->l->v = tree->rates->cur_l[d->num]; tree->rates->u_cur_l[b->num] = tree->rates->cur_l[d->num]; b->l_var->v = tree->rates->cur_gamma_prior_var[d->num]; } if(b && (isnan(b->l->v) || isnan(b->l_var->v))) { PhyML_Printf("\n== dt=%G rr=%G cr=%G ra=%G rd=%G nu=%G %f %f ",dt,rr,cr,ra,rd,nu,b->l_var->v,b->l->v); PhyML_Printf("\n== ta=%G td=%G ra*cr=%G rd*cr=%G sd=%G", ta,td,ra*cr,rd*cr, SQRT(dt*nu)*cr); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } } if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) RATES_Update_Cur_Bl_Pre(d,d->v[i],d->b[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Bl_To_Bl(t_tree *tree) { RATES_Bl_To_Bl_Pre(tree->n_root,tree->n_root->v[2],NULL,tree); RATES_Bl_To_Bl_Pre(tree->n_root,tree->n_root->v[1],NULL,tree); /* tree->rates->cur_l[tree->n_root->v[2]->num] = tree->a_edges[tree->e_root->num]->l->v * tree->n_root_pos; */ /* tree->rates->cur_l[tree->n_root->v[1]->num] = tree->a_edges[tree->e_root->num]->l->v * (1. - tree->n_root_pos); */ tree->rates->cur_l[tree->n_root->v[2]->num] = tree->a_edges[tree->e_root->num]->l->v * 0.5; tree->rates->cur_l[tree->n_root->v[1]->num] = tree->a_edges[tree->e_root->num]->l->v * (1. - 0.5); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Bl_To_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(b) { tree->rates->cur_l[d->num] = b->l->v; } if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) RATES_Bl_To_Bl_Pre(d,d->v[i],d->b[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Bl_To_Ml(t_tree *tree) { RATES_Bl_To_Ml_Pre(tree->n_root,tree->n_root->v[2],NULL,tree); RATES_Bl_To_Ml_Pre(tree->n_root,tree->n_root->v[1],NULL,tree); tree->rates->u_ml_l[tree->e_root->num] = tree->a_edges[tree->e_root->num]->l->v; tree->rates->ml_l[tree->n_root->v[2]->num] = tree->rates->u_ml_l[tree->e_root->num] * tree->n_root_pos; tree->rates->ml_l[tree->n_root->v[1]->num] = tree->rates->u_ml_l[tree->e_root->num] * (1. - tree->n_root_pos); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Bl_To_Ml_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(b) { tree->rates->u_ml_l[b->num] = b->l->v; tree->rates->ml_l[d->num] = b->l->v; } if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) RATES_Bl_To_Ml_Pre(d,d->v[i],d->b[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Cov_Matrix_Rooted(phydbl *unroot_cov, t_tree *tree) { int i,dim; dim = 2*tree->n_otu-3; RATES_Get_Cov_Matrix_Rooted_Pre(tree->n_root,tree->n_root->v[2],NULL,unroot_cov,tree); RATES_Get_Cov_Matrix_Rooted_Pre(tree->n_root,tree->n_root->v[1],NULL,unroot_cov,tree); For(i,dim+1) tree->rates->cov_l[i*(dim+1)+tree->n_root->v[2]->num] /= 2.; For(i,dim+1) tree->rates->cov_l[i*(dim+1)+tree->n_root->v[1]->num] /= 2.; For(i,dim+1) tree->rates->cov_l[tree->n_root->v[2]->num*(dim+1)+i] /= 2.; For(i,dim+1) tree->rates->cov_l[tree->n_root->v[1]->num*(dim+1)+i] /= 2.; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Cov_Matrix_Rooted_Pre(t_node *a, t_node *d, t_edge *b, phydbl *cov, t_tree *tree) { int i, dim; t_node *n; dim = 2*tree->n_otu-3; n = NULL; For(i,dim) { if(tree->a_edges[i] != tree->e_root) { n = (tree->a_edges[i]->left->anc == tree->a_edges[i]->rght)? (tree->a_edges[i]->left): (tree->a_edges[i]->rght); if(b) { tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[b->num*dim + i]; } else { tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[tree->e_root->num*dim + i]; } } else { n = tree->e_root->left; if(b) tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[b->num*dim + i]; else tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[tree->e_root->num*dim + i]; n = tree->e_root->rght; if(b) tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[b->num*dim + i]; else tree->rates->cov_l[d->num*(dim+1) + n->num] = cov[tree->e_root->num*dim + i]; } } if(d->tax) return; else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) RATES_Get_Cov_Matrix_Rooted_Pre(d,d->v[i],d->b[i],cov,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Covariance_Mu(t_tree *tree) { int i,j; phydbl dt,var; int dim; int lca_num; dim = 2*tree->n_otu-2; For(i,dim*dim) tree->rates->cov_r[i] = 0.0; dt = tree->rates->nd_t[tree->n_root->v[2]->num] - tree->rates->nd_t[tree->n_root->num]; var = dt * tree->rates->nu; tree->rates->cov_r[tree->n_root->v[2]->num*dim+tree->n_root->v[2]->num] = var; dt = tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]; var = dt * tree->rates->nu; tree->rates->cov_r[tree->n_root->v[1]->num*dim+tree->n_root->v[1]->num] = var; RATES_Variance_Mu_Pre(tree->n_root,tree->n_root->v[2],tree); RATES_Variance_Mu_Pre(tree->n_root,tree->n_root->v[1],tree); For(i,dim) { for(j=i+1;jrates->lca[i*(dim+1)+j]->num; if(lca_num < dim) { tree->rates->cov_r[i*dim+j] = tree->rates->cov_r[lca_num*dim+lca_num]; tree->rates->cov_r[j*dim+i] = tree->rates->cov_r[i*dim+j]; } else if(lca_num == dim) { tree->rates->cov_r[i*dim+j] = 0.0; tree->rates->cov_r[j*dim+i] = 0.0; } else { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Variance_Mu_Pre(t_node *a, t_node *d, t_tree *tree) { int dim; phydbl var0; phydbl dt1,var1; phydbl dt2,var2; int i; int dir1, dir2; dim = 2*tree->n_otu-2; if(d->tax) return; dir1 = dir2 = -1; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(dir1 < 0) dir1 = i; else dir2 = i; } } var0 = tree->rates->cov_r[d->num*dim+d->num]; dt1 = tree->rates->nd_t[d->v[dir1]->num] - tree->rates->nd_t[d->num]; var1 = tree->rates->nu*dt1; dt2 = tree->rates->nd_t[d->v[dir2]->num] - tree->rates->nd_t[d->num]; var2 = tree->rates->nu*dt2; tree->rates->cov_r[d->v[dir1]->num*dim+d->v[dir1]->num] = var0+var1; tree->rates->cov_r[d->v[dir2]->num*dim+d->v[dir2]->num] = var0+var2; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Variance_Mu_Pre(d,d->v[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Fill_Lca_Table(t_tree *tree) { int i,j; int dim; dim = 2*tree->n_otu-1; For(i,dim) { for(j=i;jrates->lca[i*dim+j] = Find_Lca_Pair_Of_Nodes(tree->a_nodes[i],tree->a_nodes[j],tree); tree->rates->lca[j*dim+i] = tree->rates->lca[i*dim+j]; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Get V(L_{i} | L_{-i}) for all i */ void RATES_Get_Conditional_Variances(t_tree *tree) { int i,j; short int *is_1; phydbl *a; int dim; t_edge *b; phydbl *cond_mu, *cond_cov; dim = 2*tree->n_otu-3; a = tree->rates->_2n_vect1; is_1 = tree->rates->_2n_vect5; b = NULL; cond_mu = tree->rates->_2n_vect2; cond_cov = tree->rates->_2n2n_vect1; For(i,dim) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9); For(i,dim) { b = tree->a_edges[i]; For(j,dim) is_1[j] = 0; is_1[b->num] = 1; For(j,dim*dim) cond_cov[j] = 0.0; For(j,dim) cond_mu[j] = 0.0; Normal_Conditional(tree->rates->mean_l,tree->rates->cov_l,a,dim,is_1,1,cond_mu,cond_cov); tree->rates->cond_var[b->num] = cond_cov[b->num*dim+b->num]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_All_Reg_Coeff(t_tree *tree) { int i,j; short int *is_1; phydbl *a; int dim; t_edge *b; dim = 2*tree->n_otu-3; a = tree->rates->_2n_vect1; is_1 = tree->rates->_2n_vect5; b = NULL; For(i,dim) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9); For(i,dim) { b = tree->a_edges[i]; For(j,dim) is_1[j] = 0; is_1[b->num] = 1; Get_Reg_Coeff(tree->rates->mean_l,tree->rates->cov_l,a,dim,is_1,1,tree->rates->reg_coeff+b->num*dim); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Get V(L_{i} | L_{-i}) for all i */ void RATES_Get_Trip_Conditional_Variances(t_tree *tree) { int i,j; short int *is_1; phydbl *a; phydbl *cond_mu, *cond_cov; t_node *n; int n_otu; a = tree->rates->_2n_vect1; is_1 = tree->rates->_2n_vect5; cond_mu = tree->rates->_2n_vect2; cond_cov = tree->rates->_2n2n_vect1; n = NULL; n_otu = tree->n_otu; For(i,2*n_otu-3) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9); For(i,2*n_otu-2) { n = tree->a_nodes[i]; if(!n->tax) { For(j,2*n_otu-3) is_1[j] = 0; is_1[n->b[0]->num] = 1; is_1[n->b[1]->num] = 1; is_1[n->b[2]->num] = 1; Normal_Conditional_Unsorted(tree->rates->mean_l,tree->rates->cov_l,a,2*n_otu-3,is_1,3,cond_mu,cond_cov); For(j,9) tree->rates->trip_cond_cov[n->num*9+j] = cond_cov[j]; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_All_Trip_Reg_Coeff(t_tree *tree) { int i,j; short int *is_1; phydbl *a; t_node *n; int n_otu; a = tree->rates->_2n_vect1; is_1 = tree->rates->_2n_vect5; n = NULL; n_otu = tree->n_otu; For(i,2*n_otu-3) a[i] = tree->rates->mean_l[i] * (Uni() * 0.2 + 0.9); For(i,2*n_otu-2) { n = tree->a_nodes[i]; if(!n->tax) { For(j,2*n_otu-3) is_1[j] = 0; is_1[n->b[0]->num] = 1; is_1[n->b[1]->num] = 1; is_1[n->b[2]->num] = 1; Get_Reg_Coeff(tree->rates->mean_l,tree->rates->cov_l,a,2*n_otu-3,is_1,3,tree->rates->trip_reg_coeff+n->num*(6*n_otu-9)); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Check_Lk_Rates(t_tree *tree, int *err) { int i; phydbl u,u_anc; phydbl t,t_anc; *err = 0; For(i,2*tree->n_otu-2) { u = tree->rates->br_r[i]; u_anc = tree->rates->br_r[tree->a_nodes[i]->anc->num]; t = tree->rates->nd_t[i]; t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num]; if(t_anc > t) { PhyML_Printf("\n. %d %d u=%f u_anc=%f t=%f t_anc=%f",i,tree->a_nodes[i]->anc->num,u,u_anc,t,t_anc); PhyML_Printf("\n. %d %d %d",tree->n_root->num,tree->n_root->v[2]->num,tree->n_root->v[1]->num); *err = 1; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Expected_Tree_Length(t_tree *tree) { int n; phydbl mean; n = 0; mean = 0.0; RATES_Expected_Tree_Length_Pre(tree->n_root,tree->n_root->v[2],1.0,&mean,&n,tree); RATES_Expected_Tree_Length_Pre(tree->n_root,tree->n_root->v[1],1.0,&mean,&n,tree); if(n != 2*tree->n_otu-2) { PhyML_Printf("\n. n=%d 2n-2=%d",n,2*tree->n_otu-2); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return mean; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Expected_Tree_Length_Pre(t_node *a, t_node *d, phydbl eranc, phydbl *mean, int *n, t_tree *tree) { phydbl erdes; int i; phydbl loc_mean; int loc_n; /* erdes = u_anc - */ /* sd*(Dnorm((tree->rates->min_rate-u_anc)/sd,.0,1.) - Dnorm((tree->rates->max_rate-u_anc)/sd,.0,1.))/ */ /* (Pnorm((tree->rates->max_rate-u_anc)/sd,.0,1.) - Pnorm((tree->rates->min_rate-u_anc)/sd,.0,1.)); */ /* erdes = Norm_Trunc_Mean(eranc,sd,tree->rates->min_rate,tree->rates->max_rate); */ erdes = 1.0; loc_mean = *mean; loc_n = *n; loc_mean *= loc_n; loc_mean += erdes; loc_mean /= (loc_n + 1); *mean = loc_mean; *n = loc_n + 1; if(d->tax) return; else For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) RATES_Expected_Tree_Length_Pre(d,d->v[i],erdes,mean,n,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Norm_Fact(t_tree *tree) { int i; phydbl r,t,t_anc; phydbl num,denom; num = denom = 0.0; For(i,2*tree->n_otu-2) { r = tree->rates->br_r[i]; t = tree->rates->nd_t[i]; t_anc = tree->rates->nd_t[tree->a_nodes[i]->anc->num]; num += (t-t_anc); denom += (t-t_anc) * r; } tree->rates->norm_fact = num/denom; /* !!!!!!!!!!!!!!!!!! */ tree->rates->norm_fact = 1.0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Normalise_Rates(t_tree *tree) { phydbl expr,curr; int i; curr = RATES_Average_Substitution_Rate(tree); curr /= tree->rates->clock_r; /* Set expected mean rate to one such that clock_r is easy to interpret regarding the mean values of br_r */ expr = 1.0; For(i,2*tree->n_otu-2) { tree->rates->br_r[i] *= expr/curr; if(tree->rates->br_r[i] > tree->rates->max_rate) tree->rates->br_r[i] = tree->rates->max_rate; if(tree->rates->br_r[i] < tree->rates->min_rate) tree->rates->br_r[i] = tree->rates->min_rate; } tree->rates->clock_r *= curr/expr; /* Branch lengths therefore do not change */ /* if(tree->rates->clock_r < tree->rates->min_clock) */ /* { */ /* PhyML_Printf("\n. Curr mean rates: %G",curr); */ /* PhyML_Printf("\n. Set clock rate to: %G",tree->rates->clock_r); */ /* tree->rates->clock_r = tree->rates->min_clock; */ /* } */ /* if(tree->rates->clock_r > tree->rates->max_clock) */ /* { */ /* PhyML_Printf("\n. Curr mean rates: %G",curr); */ /* PhyML_Printf("\n. Set clock rate to: %G",tree->rates->clock_r); */ /* tree->rates->clock_r = tree->rates->max_clock; */ /* } */ RATES_Update_Norm_Fact(tree); RATES_Update_Cur_Bl(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Find_Max_Dt_Bisec(phydbl r, phydbl r_mean, phydbl ta, phydbl tc, phydbl nu, phydbl threshp, int inf) { phydbl cdfr,cdf0; phydbl sd; phydbl trunc_cdf; phydbl ori_tc, ori_ta; phydbl tb; ori_tc = tc; ori_ta = ta; /* PhyML_Printf("\n Max %s r=%f r_mean%f",inf?"inf":"sup",r,r_mean); */ do { tb = ta + (tc - ta)/2.; sd = SQRT(nu*(ori_tc - tb)); cdfr = Pnorm(r ,r_mean,sd); cdf0 = Pnorm(.0,r_mean,sd); if(inf) trunc_cdf = (cdfr - cdf0)/(1. - cdf0); else trunc_cdf = (1. - cdfr)/(1. - cdf0); /* PhyML_Printf("\n. ta=%15f tb=%15f tc=%15f cdf = %15f",ta,tb,tc,trunc_cdf); */ if(trunc_cdf > threshp) { ta = tb; } else { tc = tb; } }while((tc - ta)/(ori_tc - ori_ta) > 0.001); if(tb < ori_ta) { PhyML_Printf("\n. tb < ta r=%f r_mean=%f",r,r_mean); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(tb > ori_tc) { PhyML_Printf("\n. tb > tc r=%f r_mean=%f ori_ta=%f ori_tc=%f tb=%f",r,r_mean,ori_ta,ori_tc,tb); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return tb; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Find_Min_Dt_Bisec(phydbl r, phydbl r_mean, phydbl ta, phydbl tc, phydbl nu, phydbl threshp, int inf) { phydbl cdfr,cdf0; phydbl sd; phydbl trunc_cdf; phydbl ori_tc, ori_ta; phydbl tb; ori_tc = tc; ori_ta = ta; /* PhyML_Printf("\n Min %s r=%f r_mean=%f",inf?"inf":"sup",r,r_mean); */ do { tb = ta + (tc - ta)/2.; sd = SQRT(nu*(tb - ori_ta)); cdfr = Pnorm(r ,r_mean,sd); cdf0 = Pnorm(.0,r_mean,sd); if(inf) trunc_cdf = (cdfr - cdf0)/(1. - cdf0); else trunc_cdf = (1. - cdfr)/(1. - cdf0); /* PhyML_Printf("\n. ta=%15f tb=%15f tc=%15f cdf = %15f",ta,tb,tc,trunc_cdf); */ if(trunc_cdf > threshp) { tc = tb; } else { ta = tb; } }while((tc - ta)/(ori_tc - ori_ta) > 0.001); if(tb < ori_ta) { PhyML_Printf("\n. tb < ta r=%f r_mean=%f",r,r_mean); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(tb > ori_tc) { PhyML_Printf("\n. tb > tc r=%f r_mean=%f ori_ta=%f ori_tc=%f tb=%f",r,r_mean,ori_ta,ori_tc,tb); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return tb; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Min_Max_Interval(phydbl u0, phydbl u1, phydbl u2, phydbl u3, phydbl t0, phydbl t2, phydbl t3, phydbl *t_min, phydbl *t_max, phydbl nu, phydbl p_thresh, t_tree *tree) { int n_eval; int i; phydbl sum_cdf; phydbl *cdf; phydbl t1; phydbl mint2t3; mint2t3 = MIN(t2,t3); n_eval = 5; cdf = (phydbl *)mCalloc(n_eval,sizeof(phydbl)); sum_cdf = .0; For(i,n_eval) { t1 = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1); cdf[i] = Dnorm_Trunc(u1,u0,SQRT(nu*(t1-t0)),tree->rates->min_rate,tree->rates->max_rate) * Dnorm_Trunc(u2,u1,SQRT(nu*(t2-t1)),tree->rates->min_rate,tree->rates->max_rate) * Dnorm_Trunc(u3,u1,SQRT(nu*(t3-t1)),tree->rates->min_rate,tree->rates->max_rate) * (mint2t3 - t0) / (n_eval + 1); if(i) cdf[i] += cdf[i-1]; } sum_cdf = cdf[i-1]; For(i,n_eval) cdf[i] /= sum_cdf; /* PhyML_Printf("\n"); */ /* For(i,n_eval) PhyML_Printf("\n* %f %f",cdf[i],sum_cdf); */ For(i,n_eval) if(cdf[i] > p_thresh) { *t_min = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1); break; } For(i,n_eval) if(cdf[i] > (1. - p_thresh)) { *t_max = t0 + (i + 1)*(mint2t3 - t0)/(n_eval + 1); break; } Free(cdf); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Get_Correction_Factor(phydbl mode, phydbl sd, int *err, t_tree *tree) { phydbl K,X0,X1,X2,Y0,Y1,Y2; phydbl eps=0.01; phydbl A,B; phydbl slope,inter; phydbl denom; *err = NO; /* DO NOTHING */ return 0.0; A = tree->rates->min_rate / sd; B = tree->rates->max_rate / sd; K = mode / sd; X0 = 0.; /* Y0 = Dnorm(X0-K,.0,1.)/(1. - Pnorm(X0-K,.0,1.)) - X0; */ Y0 = (Dnorm(A-K+X0,.0,1.)-Dnorm(B-K+X0,.0,1.))/(Pnorm(B-K+X0,.0,1.)-Pnorm(A-K+X0,.0,1.)) - X0; X1 = .1; /* Y1 = Dnorm(X1-K,.0,1.)/(1. - Pnorm(X1-K,.0,1.)) - X1; */ Y1 = (Dnorm(A-K+X1,.0,1.)-Dnorm(B-K+X1,.0,1.))/(Pnorm(B-K+X1,.0,1.)-Pnorm(A-K+X1,.0,1.)) - X1; /* printf("\n. ^^ mean=%f sd=%f",mode,sd); */ /* printf("\n. X0=%f Y0=%f X1=%f Y1=%f",X0,Y0,X1,Y1); */ do { slope = (Y1-Y0)/(X1-X0); inter = Y0 - X0*(Y1-Y0)/(X1-X0); X2 = -inter/slope; denom = (Pnorm(B-K+X2,.0,1.)-Pnorm(A-K+X2,.0,1.)); if(denom < 1.E-10) { /* printf("\n. X2 = %f Y2=%f num=%f denom=%f Y1=%f Y0=%f X1=%f X0=%f mode=%f sd=%f",X2,Y2,num,denom,Y1,Y0,X1,X0,mode,sd); */ *err = YES; break; } /* Y2 = Dnorm(X2-K,.0,1.)/(1. - Pnorm(X2-K,.0,1.)) - X2; */ Y2 = (Dnorm(A-K+X2,.0,1.)-Dnorm(B-K+X2,.0,1.))/(Pnorm(B-K+X2,.0,1.)-Pnorm(A-K+X2,.0,1.)) - X2; /* printf("\n. X2 = %f Y2=%f num=%f denom=%f Y1=%f Y0=%f X1=%f X0=%f",X2,Y2,num,denom,Y1,Y0,X1,X0); */ if(X2 > X1) { X0 = X1; X1 = X2; Y0 = Y1; Y1 = Y2; } else { X1 = X0; X0 = X2; Y1 = Y0; Y0 = Y2; } }while(fabs(Y2) > eps); /* printf("\n. shift = %f X2=%f Y2 = %f",X2*sd,X2,Y2); */ return X2 * sd; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Sample_Average_Rate(t_node *a, t_node *d, t_tree *tree) { return(-1.); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Mean_Br_Len(int iter, t_tree *tree) { int i,dim; phydbl *mean; if(tree->rates->update_mean_l == NO) return; dim = 2*tree->n_otu-3; mean = tree->rates->mean_l; For(i,dim) { mean[i] *= (phydbl)iter; mean[i] += tree->a_edges[i]->l->v; mean[i] /= (phydbl)(iter+1); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Update_Cov_Br_Len(int iter, t_tree *tree) { int i,j,dim; phydbl *mean,*cov; if(tree->rates->update_cov_l == NO) return; dim = 2*tree->n_otu-3; mean = tree->rates->mean_l; cov = tree->rates->cov_l; For(i,dim) { For(j,dim) { cov[i*dim+j] += mean[i]*mean[j]; cov[i*dim+j] *= (phydbl)tree->mcmc->run; cov[i*dim+j] += tree->a_edges[i]->l->v * tree->a_edges[j]->l->v; cov[i*dim+j] /= (phydbl)(tree->mcmc->run+1); cov[i*dim+j] -= mean[i]*mean[j]; if(i == j && cov[i*dim+j] < MIN_VAR_BL) cov[i*dim+j] = MIN_VAR_BL; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Set_Mean_L(t_tree *tree) { int i; For(i,2*tree->n_otu-3) { tree->rates->mean_l[i] = tree->a_edges[i]->l->v; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Record_Times(t_tree *tree) { int i; if(tree->rates->nd_t_recorded == YES) { PhyML_Printf("\n. Overwriting recorded times is forbidden.\n"); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } For(i,2*tree->n_otu-1) tree->rates->buff_t[i] = tree->rates->nd_t[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Reset_Times(t_tree *tree) { int i; tree->rates->nd_t_recorded = NO; For(i,2*tree->n_otu-1) tree->rates->nd_t[i] = tree->rates->buff_t[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Record_Rates(t_tree *tree) { int i; if(tree->rates->br_r_recorded == YES) { PhyML_Printf("\n. Overwriting recorded rates is forbidden.\n"); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } For(i,2*tree->n_otu-2) tree->rates->buff_r[i] = tree->rates->br_r[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Reset_Rates(t_tree *tree) { int i; tree->rates->br_r_recorded = NO; For(i,2*tree->n_otu-2) tree->rates->br_r[i] = tree->rates->buff_r[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Set_Clock_And_Nu_Max(t_tree *tree) { phydbl dt,nu; phydbl min_t; int i; phydbl step; phydbl l_max; phydbl max_clock; phydbl r_max; phydbl tune; phydbl pa,pb; if(tree->rates->model == THORNE || tree->rates->model == GUINDON) { tune = 1.05; if(tree->rates->model_log_rates == NO) { r_max = LOG(tree->rates->max_rate); } else { r_max = tree->rates->max_rate; } l_max = tree->mod->l_max; min_t = .0; For(i,2*tree->n_otu-1) if(tree->rates->t_prior_min[i] < min_t) min_t = tree->rates->t_prior_min[i]; dt = FABS(min_t); max_clock = l_max / dt; nu = 1.E-10; step = 1.E-1; do { do { nu += step; pa = Dnorm(0.0, 0.0,SQRT(nu*dt)); pb = Dnorm(r_max,0.0,SQRT(nu*dt)); }while(pa/pb > tune); nu -= step; step /= 10.; }while(step > 1.E-10); tree->rates->max_nu = nu; /* tree->rates->max_nu = 1.0; */ tree->rates->max_clock = max_clock; PhyML_Printf("\n. Clock rate parameter upper bound set to %f expected subst./site/time unit",tree->rates->max_clock); PhyML_Printf("\n. Autocorrelation parameter upper bound set to %f",tree->rates->max_nu); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Set_Birth_Rate_Boundaries(t_tree *tree) { phydbl lbda; phydbl p_above_min,p_below_max; phydbl min,max; int assign = YES; min = -0.01*tree->rates->t_prior_max[tree->n_root->num]; max = -100.*tree->rates->t_prior_min[tree->n_root->num]; for(lbda = 0.0001; lbda < 10; lbda+=0.0001) { p_above_min = 1. - POW(1.-EXP(-lbda*min),tree->n_otu); p_below_max = POW(1.-EXP(-lbda*max),tree->n_otu); if(p_above_min < 1.E-10) { tree->rates->birth_rate_max = lbda; break; } if(p_below_max > 1.E-10 && assign==YES) { assign = NO; tree->rates->birth_rate_min = lbda; } } /* tree->rates->birth_rate_min = 1.E-6; */ /* tree->rates->birth_rate_max = 1.; */ PhyML_Printf("\n. Birth rate lower bound set to %f.",tree->rates->birth_rate_min); PhyML_Printf("\n. Birth rate upper bound set to %f.",tree->rates->birth_rate_max); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Write_Mean_R_On_Edge_Label(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(b) { if(!b->labels) { Make_New_Edge_Label(b); b->n_labels++; } sprintf(b->labels[0],"%f",tree->rates->mean_r[d->num] / (phydbl)(tree->mcmc->run/tree->mcmc->sample_interval+1.)); } if(d->tax) return; else { int i; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { RATES_Write_Mean_R_On_Edge_Label(d,d->v[i],d->b[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree) { phydbl sum; int n; sum = 0.0; n = 0; if(root->tax == NO) { if(root == tree->n_root) { RATES_Get_Mean_Rate_In_Subtree_Pre(root,root->v[2],&sum,&n,tree); RATES_Get_Mean_Rate_In_Subtree_Pre(root,root->v[1],&sum,&n,tree); } else { int i; For(i,3) { if(root->v[i] != root->anc && root->b[i] != tree->e_root) { RATES_Get_Mean_Rate_In_Subtree_Pre(root,root->v[i],&sum,&n,tree); } } } return sum/(phydbl)n; } else { return 0.0; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Mean_Rate_In_Subtree_Pre(t_node *a, t_node *d, phydbl *sum, int *n, t_tree *tree) { (*sum) += EXP(tree->rates->nd_r[d->num]); (*n) += 1; if(d->tax == YES) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { RATES_Get_Mean_Rate_In_Subtree_Pre(d,d->v[i],sum,n,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *RATES_Get_Model_Name(int model) { char *s; s = (char *)mCalloc(T_MAX_NAME,sizeof(char)); switch(model) { case GUINDON : {strcpy(s,"gbs"); break;} case THORNE : {strcpy(s,"gbd"); break;} case GAMMA : {strcpy(s,"gamma"); break;} case STRICTCLOCK : {strcpy(s,"clock"); break;} default : { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); break; } } return s; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void RATES_Get_Survival_Ranks(t_tree *tree) { int i,j; phydbl rank; For(i,2*tree->n_otu-2) { rank = 0.; For(j,2*tree->n_otu-2) { if(tree->rates->br_r[i] > tree->rates->br_r[j]) rank += 1.0; } tree->rates->survival_rank[i] = rank; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/rates.h000066400000000000000000000245261263450375500147460ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef RATES_H #define RATES_H #include "utilities.h" #include "spr.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "time.h" #include "m4.h" #include "draw.h" #include "mcmc.h" #include "stats.h" void RATES_Monte_Carlo_Mean_Rates(t_tree *tree); void RATES_Monte_Carlo_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl curr_rate, t_tree *tree); void RATES_Print_Rates(t_tree *tree); void RATES_Print_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); t_rate *RATES_Make_Rate_Struct(int n_otu); void RATES_Init_Rate_Struct(t_rate *rates, t_rate *existing_rates, int n_otu); void RATES_Classify_Branches(t_tree *tree); void RATES_Adjust_Rates(t_tree *tree); void RATES_Adjust_Rates_Local_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void RATES_Adjust_Rates_Local(t_node *a, t_node *d, t_edge *b1, t_tree *tree); void RATES_Record_T(t_tree *tree); void RATES_Restore_T(t_tree *tree); void RATES_Monte_Carlo_Mean_Rates_Core(phydbl t_lim_sup, phydbl t_lim_inf, phydbl *curr_rate, phydbl *mean_rate, phydbl lexp, phydbl alpha); phydbl RATES_Lk_Rates(t_tree *tree); void RATES_Lk_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void RATES_Fill_Node_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl *node_r, t_tree *tree); void RATES_Fill_Node_Rates(phydbl *node_r, t_tree *tree); void RATES_Optimize_Node_Times_Serie_Fixed_Br_Len(t_node *a, t_node *d, t_tree *tree); void RATES_Optimize_Lexp(t_tree *tree); void RATES_Round_Optimize(t_tree *tree); void RATES_Optimize_Lexp(t_tree *tree); void RATES_Optimize_Alpha(t_tree *tree); phydbl RATES_Dmu(phydbl mu, int n_jumps, phydbl dt, phydbl a, phydbl b, phydbl lexp, int min_n, int jps_dens); phydbl RATES_Dr_X_Dx(phydbl r, phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu_Given_Y_Trpzd(phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp, int nsteps, phydbl beg, phydbl end, phydbl prevs); phydbl RATES_Dmu_Given_Y_Std(phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu_Given_Y_Romb(phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu_Given_Y(phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dy_Given_Mu(phydbl mu, phydbl y, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_Given_Y_X_Dy_Given_Mu1(phydbl mu1, phydbl mu2, phydbl y, phydbl dt1, phydbl dt2, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_Given_Mu1_Trpz(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl a, phydbl b, phydbl lexp, int nsteps, phydbl beg, phydbl end, phydbl prevs); phydbl RATES_Dmu2_And_Mu1(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_Given_Mu1(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_Given_Mu1_Romb(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl a, phydbl b, phydbl lexp); void RATES_Random_Branch_Lengths(t_tree *tree); void RATES_Bracket_N_Jumps(int *up, int *down, phydbl param); void RATES_Set_Node_Times(t_tree *tree); void RATES_Set_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree); void RATES_Optimize_Node_Times(t_tree *tree); phydbl RATES_Exp_Y(phydbl mu1, phydbl mu2, phydbl dt1, phydbl lexp); phydbl RATES_Dmu2_Given_Mu1_Bis(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp); void RATES_Replace_Br_Lengths_By_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void RATES_Replace_Br_Lengths_By_Rates(t_tree *tree); void RATES_Get_Mean_Rates(t_tree *tree); void RATES_Get_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl r_a, t_tree *tree); void RATES_Expect_Number_Subst(phydbl t_beg, phydbl t_end, phydbl r_beg, int *n_jumps, phydbl *mean_r, phydbl *r_end, t_rate *rates, t_tree *tree); void RATES_Optimize_Clock_Rate(t_tree *tree); phydbl RATES_Dmu1_Given_Lbda_And_Mu2(phydbl lbda, phydbl mu1, phydbl mu2, phydbl alpha, phydbl beta); phydbl RATES_Dmu1_And_Mu2_One_Jump_Trpz(phydbl mu1, phydbl mu2, phydbl a, phydbl b, int nsteps, phydbl beg, phydbl end, phydbl prevs); phydbl RATES_Dmu1_And_Mu2_One_Jump_One_Interval(phydbl mu1, phydbl mu2, phydbl a, phydbl b); phydbl RATES_Dmu1_And_Mu2_One_Jump_Two_Intervals(phydbl dt1, phydbl dt2, phydbl mu1, phydbl mu2, phydbl a, phydbl b); phydbl RATES_Dmu1_And_Mu2_One_Jump_Old(phydbl mu1, phydbl mu2, phydbl a, phydbl b); phydbl RATES_Dmu2_And_Min_N_Given_Mu1(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n_min, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_And_Mu1_Given_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Lk_Rates_Core(phydbl br_r_a, phydbl br_r_d, phydbl nd_r_a, phydbl nd_r_d, int n_a, int n_d, phydbl dt_a, phydbl dt_d, t_tree *tree); void RATES_Init_Triplets(t_tree *tree); phydbl RATES_Lk_Change_One_Time(t_node *n, phydbl new_t, t_tree *tree); void RATES_Update_Triplet(t_node *n, t_tree *tree); void RATES_Print_Triplets(t_tree *tree); phydbl RATES_Lk_Change_One_Rate(t_node *d, phydbl new_rate, t_tree *tree); phydbl RATES_Dmu2_And_Mu1_Given_Min_N(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n_min, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu2_And_Mu1_Given_N_Normal(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Coeff_Corr(phydbl alpha, phydbl beta, int n1, int n2); phydbl RATES_Dmu2_And_Mu1_Given_N_Full(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, int n, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu1_Given_V_And_N(phydbl mu1, phydbl v, int n, phydbl dt1, phydbl a, phydbl b); phydbl RATES_Yule(t_tree *tree); phydbl RATES_Check_Mean_Rates(t_tree *tree); void RATES_Check_Mean_Rates_Pre(t_node *a, t_node *d, t_edge *b, phydbl *sum, t_tree *tree); void RATES_Discretize_Rates(t_tree *tree); void RATES_Discretize_Rates_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); phydbl RATES_Dmu_Given_V_And_MinN(phydbl mu, phydbl dt, phydbl v, int minn, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Dmu_One(phydbl mu, phydbl dt, phydbl a, phydbl b, phydbl lexp); phydbl RATES_Compound_Core(phydbl mu1, phydbl mu2, int n1, int n2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx); void RATES_Record_Rates(t_tree *tree); void RATES_Reset_Rates(t_tree *tree); void RATES_Record_Times(t_tree *tree); void RATES_Reset_Times(t_tree *tree); void RATES_Update_T_Rates_Pre(t_node *a, t_node *d, t_tree *tree); void RATES_Update_T_Rates(t_tree *tree); void RATES_Get_Rates_From_Bl(t_tree *tree); phydbl RATES_Compound_Core_Joint(phydbl mu1, phydbl mu2, int n1, int n2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx); phydbl RATES_Dmu_Joint(phydbl mu, int n, phydbl dt, phydbl a, phydbl b, phydbl lexp, int min_n); phydbl RATES_Compound_Core_Marginal(phydbl mu1, phydbl mu2, phydbl dt1, phydbl dt2, phydbl alpha, phydbl beta, phydbl lexp, phydbl eps, int approx); phydbl RATES_Lk_Jumps(t_tree *tree); void RATES_Posterior_Rates(t_tree *tree); void RATES_Posterior_One_Rate(t_node *a, t_node *d, int traversal, t_tree *tree); void RATES_Free_Rates(t_rate *rates); void RATES_Initialize_True_Rates(t_tree *tree); void RATES_Posterior_Times(t_tree *tree); void RATES_Posterior_One_Time(t_node *a, t_node *d, int traversal, t_tree *tree); void RATES_Update_Cur_Bl(t_tree *tree); void RATES_Update_Cur_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void RATES_Get_Cov_Matrix_Rooted(phydbl *unroot_cov, t_tree *tree); void RATES_Get_Cov_Matrix_Rooted_Pre(t_node *a, t_node *d, t_edge *b, phydbl *cov, t_tree *tree); void RATES_Bl_To_Ml(t_tree *tree); void RATES_Bl_To_Ml_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); int RATES_Check_Node_Times(t_tree *tree); void RATES_Check_Node_Times_Pre(t_node *a, t_node *d, int *err, t_tree *tree); void RATES_Covariance_Mu(t_tree *tree); void RATES_Variance_Mu_Pre(t_node *a, t_node *d, t_tree *tree); void RATES_Fill_Lca_Table(t_tree *tree); void RATES_Posterior_Clock_Rate(t_tree *tree); void RATES_Get_Conditional_Variances(t_tree *tree); void RATES_Get_All_Reg_Coeff(t_tree *tree); void RATES_Posterior_Time_Root(t_tree *tree); void RATES_Get_Trip_Conditional_Variances(t_tree *tree); void RATES_Get_All_Trip_Reg_Coeff(t_tree *tree); void RATES_Check_Lk_Rates(t_tree *tree, int *err); phydbl RATES_Expected_Tree_Length(t_tree *tree); void RATES_Expected_Tree_Length_Pre(t_node *a, t_node *d, phydbl eranc, phydbl *mean, int *n, t_tree *tree); void RATES_Normalise_Rates(t_tree *tree); phydbl RATES_Check_Mean_Rates_True(t_tree *tree); phydbl RATES_Find_Min_Dt_Bisec(phydbl r0, phydbl r1, phydbl t0, phydbl t1, phydbl nu, phydbl threshp, int inf); phydbl RATES_Find_Max_Dt_Bisec(phydbl r0, phydbl r1, phydbl t0, phydbl t1, phydbl nu, phydbl threshp, int inf); void RATES_Min_Max_Interval(phydbl u0, phydbl u1, phydbl u2, phydbl u3, phydbl t0, phydbl t2, phydbl t3, phydbl *t_min, phydbl *t_max, phydbl nu, phydbl p_thresh, t_tree *tree); phydbl RATES_Get_Correction_Factor(phydbl mode, phydbl sd, int *err, t_tree *tree); phydbl RATES_Average_Substitution_Rate(t_tree *tree); void RATES_Update_Norm_Fact(t_tree *tree); void RATES_Update_Mean_Br_Len(int iter, t_tree *tree); void RATES_Update_Cov_Br_Len(int iter, t_tree *tree); void RATES_Set_Mean_L(t_tree *tree); void RATES_Fill_All_Param(t_rate *rate, t_tree *tree); void RATES_Record_Rates(t_tree *tree); void RATES_Reset_Rates(t_tree *tree); phydbl RATES_Average_Rate(t_tree *tree); void RATES_Set_Clock_And_Nu_Max(t_tree *tree); void RATES_Write_Mean_R_On_Edge_Label(t_node *a, t_node *d, t_edge *b, t_tree *tree); phydbl RATES_Lk_Linreg(t_tree *tree); phydbl RATES_Get_Mean_Rate_In_Subtree(t_node *root, t_tree *tree); void RATES_Get_Mean_Rate_In_Subtree_Pre(t_node *a, t_node *d, phydbl *sum, int *n, t_tree *tree); char *RATES_Get_Model_Name(int model); void RATES_Get_Survival_Ranks(t_tree *tree); void RATES_Bl_To_Bl(t_tree *tree); void RATES_Bl_To_Bl_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void RATES_Set_Birth_Rate_Boundaries(t_tree *tree); #endif phyml-3.2.0/src/rwrapper.c000066400000000000000000000131721263450375500154600ustar00rootroot00000000000000#include "rwrapper.h" /* #include */ /* #include */ /*********************************************************/ /*********************************************************/ /*********************************************************/ /*********************************************************/ /*********************************************************/ /* void RWRAPPER_Min_Number_Of_Tip_Permut(char **tree_file_name, char **coord_file_name, phydbl *res) */ /* { */ /* t_tree *tree; */ /* option *io; */ /* FILE *fp_tree_file, *fp_coord_file; */ /* int i; */ /* srand(time(NULL)); rand(); */ /* /\\* Rprintf("%s\n",tree_file_name[0]); *\\/ */ /* /\\* Rprintf("%s\n",coord_file_name[0]); *\\/ */ /* fp_tree_file = (FILE *)fopen(tree_file_name[0],"r"); */ /* fp_coord_file = (FILE *)fopen(coord_file_name[0],"r"); */ /* io = (option *)Make_Input(); */ /* io->fp_in_tree = fp_tree_file; */ /* Read_Tree_File(io); */ /* tree = io->treelist->tree[0]; */ /* tree->io = io; */ /* tree->io->z_scores = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl)); */ /* /\\* For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->noeud[i]->name,1,tree); *\\/ */ /* /\\* TIPO_Normalize_Zscores(tree); *\\/ */ /* /\\* TIPO_Get_Min_Number_Of_Tip_Permut(tree); *\\/ */ /* /\\* res[0] = (phydbl)tree->tip_order_score; *\\/ */ /* For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree); */ /* Free_Bip(tree); */ /* Alloc_Bip(tree); */ /* Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */ /* TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */ /* /\\* TIPO_Get_Tips_Y_Rank(tree); *\\/ */ /* tree->geo_mig_sd = 1.; */ /* Generic_Brent_Lk(&(tree->geo_mig_sd), */ /* 1.E-5,1.E+2,1.E-6, */ /* 100,NO, */ /* &Optwrap_Geo_Lk, */ /* NULL,tree,NULL); */ /* res[0] = (phydbl)tree->geo_mig_sd; */ /* /\\* For(i,tree->n_otu) Rprintf("\n.. %f",tree->io->z_scores[i]); *\\/ */ /* /\\* printf("\n>> sd: %f",tree->geo_mig_sd); *\\/ */ /* fclose(fp_tree_file); */ /* fclose(fp_coord_file); */ /* } */ /*********************************************************/ void RWRAPPER_Log_Dnorm(phydbl *x, phydbl *mean, phydbl *sd, phydbl *res) { int err; err = NO; *res = Log_Dnorm(*x,*mean,*sd,&err); } /*********************************************************/ void RWRAPPER_Integrated_Geometric_Brownian_Bridge_Mean(phydbl *T, phydbl *A, phydbl *B, phydbl *u, phydbl *mean) { Integrated_Geometric_Brownian_Bridge_Mean(*T,*A,*B,*u,mean); } /*********************************************************/ void RWRAPPER_Integrated_Geometric_Brownian_Bridge_Var(phydbl *T, phydbl *A, phydbl *B, phydbl *u, phydbl *var) { Integrated_Geometric_Brownian_Bridge_Var(*T,*A,*B,*u,var); } /* /\*********************************************************\/ */ /* void RWRAPPER_Rnorm_Trunc(phydbl *mean, phydbl *sd, phydbl *min, phydbl *max, phydbl *res) */ /* { */ /* *res = Rnorm_Trunc(*mean,*sd,*min,*max); */ /* } */ /* void RWRAPPER_Cholesky_Decomp(double *A, int *dim) */ /* { */ /* Cholesky_Decomp(A,*dim); */ /* } */ /*********************************************************/ /* void RWRAPPER_Bivariate_Normal_Density(phydbl *x, phydbl *y, phydbl *mux, phydbl *muy, phydbl *sdx, phydbl *sdy, phydbl *rho, phydbl *dens) */ /* { */ /* *dens = Bivariate_Normal_Density(*x,*y,*mux,*muy,*sdx,*sdy,*rho); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dmu2_And_Mu1_Given_Min_N(phydbl *mu1, phydbl *mu2, phydbl *dt1, phydbl *dt2, int *n_min, phydbl *a, phydbl *b, phydbl *lexp, phydbl *dens) */ /* { */ /* *dens = RATES_Dmu2_And_Mu1_Given_Min_N(*mu1, *mu2, *dt1, *dt2, *n_min, *a, *b, *lexp); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dgamma(phydbl *x, phydbl *shape, phydbl *scale, phydbl *dens) */ /* { */ /* *dens = Dgamma(*x,*shape,*scale); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dnorm(phydbl *x, phydbl *mean, phydbl *var, double *dens) */ /* { */ /* *dens = Dnorm_Moments(*x,*mean,*var); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dmu_One(phydbl *mu, phydbl *dt, phydbl *a, phydbl *b, phydbl *lexp, double *dens) */ /* { */ /* *dens = RATES_Dmu_One(*mu,*dt,*a,*b,*lexp); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dr_X_Dx(double *r, double *mu, double *y, double *dt, double *a, double *b, double *lexp, double *dens) */ /* { */ /* *dens = RATES_Dr_X_Dx(*r,*mu,*y,*dt,*a,*b,*lexp); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dmu_Given_Y(double *mu, double *y, double *dt, double *a, double *b, double *lexp, double *dens) */ /* { */ /* *dens = RATES_Dmu_Given_Y(*mu,*y,*dt,*a,*b,*lexp); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dmu2_And_Mu1(double *mu1, double *mu2, double *dt1, double *dt2, double *a, double *b, double *lexp, double *dens) */ /* { */ /* *dens = RATES_Dmu2_And_Mu1(*mu1,*mu2,*dt1,*dt2,*a,*b,*lexp); */ /* } */ /* /\*********************************************************\/ */ /* void RWRAPPER_Dmu2_Given_Mu1(double *mu1, double *mu2, double *dt1, double *dt2, double *a, double *b, double *lexp, double *dens) */ /* { */ /* /\* *dens = RATES_Dmu2_Given_Mu1(*mu1,*mu2,*dt1,*dt2,*a,*b,*lexp); *\/ */ /* *dens = RATES_Dmu2_Given_Mu1_Bis(*mu1,*mu2,*dt1,*dt2,*a,*b,*lexp); */ /* } */ /* /\*********************************************************\/ */ phyml-3.2.0/src/rwrapper.h000066400000000000000000000054041263450375500154640ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef RWRAPPER_H #define RWRAPPER_H #include "utilities.h" #include "rates.h" #include "eigen.h" #include "io.h" #include "stats.h" #include "tiporder.h" /* void RWRAPPER_Dmu2_Given_Mu1_And_Min_N(phydbl *mu1, phydbl *mu2, phydbl *dt1, phydbl *dt2, int *n_min, phydbl *a, phydbl *b, phydbl *lexp, phydbl *dens); */ /* void RWRAPPER_Dnorm(phydbl *x, phydbl *mean, phydbl *var, double *dens); */ /* void RWRAPPER_Dmu(phydbl *mu, phydbl *dt, phydbl *a, phydbl *b, phydbl *lexp, double *dens); */ /* void RWRAPPER_Dr_X_Dx(double *r, double *mu, double *y, double *dt, double *a, double *b, double *lexp, double *dens); */ /* void RWRAPPER_Dmu_Given_Y(double *mu, double *y, double *dt, double *a, double *b, double *lexp, double *dens); */ /* void RWRAPPER_Dmu(phydbl *mu, phydbl *dt, phydbl *a, phydbl *b, phydbl *lexp, double *dens); */ /* void RWRAPPER_Dmu2_Given_Mu1(double *mu1, double *mu2, double *dt1, double *dt2, double *a, double *b, double *lexp, double *dens); */ /* void RWRAPPER_Dgamma(phydbl *x, phydbl *shape, phydbl *scale, phydbl *dens); */ /* void RWRAPPER_Bivariate_Normal_Density(phydbl *x, phydbl *y, phydbl *mux, phydbl *muy, phydbl *sdx, phydbl *sdy, phydbl *rho, phydbl *dens); */ /* void RWRAPPER_Dmu2_And_Mu1_Given_Min_N(phydbl *mu1, phydbl *mu2, phydbl *dt1, phydbl *dt2, int *n_min, phydbl *a, phydbl *b, phydbl *lexp, phydbl *dens); */ /* void RWRAPPER_RATES_Dmu1_And_Mu2_One_Jump_Two_Intervals(phydbl *dt1, phydbl *dt2, phydbl *mu1, phydbl *mu2, phydbl *alpha, phydbl *beta, phydbl *dens); */ /* void RWRAPPER_Dmu_One(phydbl *mu, phydbl *dt, phydbl *a, phydbl *b, phydbl *lexp, double *dens); */ /* void RWRAPPER_Lk_Rates_Core(phydbl *mu1, phydbl *mu2, phydbl *dt1, phydbl *dt2, phydbl *a, phydbl *b, phydbl *lexp, phydbl *eps, int *approx, phydbl *dens); */ /* void RWRAPPER_Dmu2_And_Mu1(double *mu1, double *mu2, double *dt1, double *dt2, double *a, double *b, double *lexp, double *dens); */ /* void RWRAPPER_Rnorm_Trunc(phydbl *mean, phydbl *sd, phydbl *min, phydbl *max, phydbl *res); */ /* void RWRAPPER_Cholesky_Decomp(double *A, int *dim); */ /* void RWRAPPER_Min_Number_Of_Tip_Permut(char **tree_file_name, char **coord_file_name, phydbl *res); */ void RWRAPPER_Log_Dnorm(phydbl *x, phydbl *mean, phydbl *sd, phydbl *res); void RWRAPPER_Integrated_Geometric_Brownian_Bridge_Mean(phydbl *T, phydbl *A, phydbl *B, phydbl *u, phydbl *mean); void RWRAPPER_Integrated_Geometric_Brownian_Bridge_Var(phydbl *T, phydbl *A, phydbl *B, phydbl *u, phydbl *var); #endif phyml-3.2.0/src/simu.c000066400000000000000000000567571263450375500146130ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "simu.h" #ifdef BEAGLE #include "beagle_utils.h" #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Simu_Loop(t_tree *mixt_tree) { phydbl lk_old; SPR_Shuffle(mixt_tree); Set_Both_Sides(YES,mixt_tree); Lk(NULL,mixt_tree); mixt_tree->best_lnL = mixt_tree->c_lnL; if(mixt_tree->mod->s_opt->print) PhyML_Printf("\n. Current value of log-likelihood: %f",mixt_tree->c_lnL); int n_tot_moves = 0; do { lk_old = mixt_tree->c_lnL; Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print)); n_tot_moves = Simu(mixt_tree,10); if(!n_tot_moves) break; } while(mixt_tree->c_lnL > lk_old + mixt_tree->mod->s_opt->min_diff_lk_local); do { Round_Optimize(mixt_tree,mixt_tree->data,ROUND_MAX); if(!Check_NNI_Five_Branches(mixt_tree)) break; } while(1); if((mixt_tree->mod->s_opt->print) && (!mixt_tree->io->quiet)) PhyML_Printf("\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Simu(t_tree *tree, int n_step_max) { phydbl old_loglk,n_iter,lambda; int i,n_neg,n_tested,n_without_swap,n_tot_swap,step,it_lim_without_swap; t_edge **sorted_b,**tested_b; sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); old_loglk = UNLIKELY; tree->c_lnL = UNLIKELY; n_iter = 1.0; /* it_lim_without_swap = (tree->mod->ras->invar)?(5):(2); */ it_lim_without_swap = (tree->mod->ras->invar)?(1):(1); n_tested = 0; n_without_swap = 0; step = 0; lambda = .75; n_tot_swap = 0; Update_Dirs(tree); if(tree->lock_topo) { PhyML_Printf("\n== The tree topology is locked."); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } do { ++step; if(n_tested || step == 1) MIXT_Set_Alias_Subpatt(YES,tree); old_loglk = tree->c_lnL; Set_Both_Sides(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); if(tree->c_lnL < old_loglk) { if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Moving backward\n"); if(!Mov_Backward_Topo_Bl(tree,old_loglk,tested_b,n_tested)) Exit("\n== Err. mov_back failed\n"); if(!tree->n_swap) n_neg = 0; Record_Br_Len(tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); } if(step > n_step_max) break; if(tree->io->print_trace) { char *s = Write_Tree(tree,NO); PhyML_Fprintf(tree->io->fp_out_trace,"[%f]%s\n",tree->c_lnL,s); fflush(tree->io->fp_out_trace); if(tree->io->print_site_lnl) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk); Free(s); } if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology ]"); /* if(((tree->c_lnL > old_loglk) && (FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_local)) || (n_without_swap > it_lim_without_swap)) break; */ if((FABS(old_loglk-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global) || (n_without_swap > it_lim_without_swap)) break; Fill_Dir_Table(tree); Fix_All(tree); n_neg = 0; For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) NNI(tree,tree->a_edges[i],0); Select_Edges_To_Swap(tree,sorted_b,&n_neg); Sort_Edges_NNI_Score(tree,sorted_b,n_neg); Optimiz_Ext_Br(tree); Update_Bl(tree,lambda); n_tested = 0; For(i,(int)CEIL((phydbl)n_neg*(lambda))) tested_b[n_tested++] = sorted_b[i]; Make_N_Swap(tree,tested_b,0,n_tested); if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("[# nnis=%3d]",n_tested); n_tot_swap += n_tested; if(n_tested > 0) n_without_swap = 0; else n_without_swap++; n_iter+=1.0; } while(1); /* Round_Optimize(tree,tree->data); */ Free(sorted_b); Free(tested_b); return n_tot_swap; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Simu_Pars(t_tree *tree, int n_step_max) { phydbl old_pars,n_iter,lambda; int i,n_neg,n_tested,n_without_swap,n_tot_swap,step; t_edge **sorted_b,**tested_b; int each; sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); tested_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); old_pars = 0; tree->c_pars = 0; n_iter = 1.0; n_tested = 0; n_without_swap = 0; step = 0; each = 4; lambda = .75; n_tot_swap = 0; Update_Dirs(tree); if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Starting simultaneous NNI moves (parsimony criterion)...\n"); do { ++step; if(step > n_step_max) break; each--; Set_Both_Sides(YES,tree); Pars(NULL,tree); if((tree->mod->s_opt->print) && (!tree->io->quiet)) { Print_Pars(tree); if(step > 1) (n_tested > 1)?(printf("[%4d NNIs]",n_tested)):(printf("[%4d NNI ]",n_tested)); } if(FABS(old_pars - tree->c_pars) < SMALL) break; if((tree->c_pars > old_pars) && (step > 1)) { if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Moving backward (topoLlogy) \n"); if(!Mov_Backward_Topo_Pars(tree,old_pars,tested_b,n_tested)) Exit("\n. Err: mov_back failed\n"); if(!tree->n_swap) n_neg = 0; Set_Both_Sides(YES,tree); Pars(NULL,tree); } else { old_pars = tree->c_pars; Fill_Dir_Table(tree); n_neg = 0; For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) NNI_Pars(tree,tree->a_edges[i],NO); Select_Edges_To_Swap(tree,sorted_b,&n_neg); Sort_Edges_NNI_Score(tree,sorted_b,n_neg); n_tested = 0; For(i,(int)CEIL((phydbl)n_neg*(lambda))) tested_b[n_tested++] = sorted_b[i]; Make_N_Swap(tree,tested_b,0,n_tested); n_tot_swap += n_tested; if(n_tested > 0) n_without_swap = 0; else n_without_swap++; } n_iter+=1.0; } while(1); Free(sorted_b); Free(tested_b); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Select_Edges_To_Swap(t_tree *tree, t_edge **sorted_b, int *n_neg) { int i; t_edge *b; phydbl best_score; *n_neg = 0; For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; best_score = b->nni->score; if((!b->left->tax) && (!b->rght->tax) && (b->nni->score < -tree->mod->s_opt->min_diff_lk_move)) { Check_NNI_Scores_Around(b->left,b->rght,b,&best_score,tree); Check_NNI_Scores_Around(b->rght,b->left,b,&best_score,tree); if(best_score < b->nni->score) continue; sorted_b[*n_neg] = b; (*n_neg)++; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Bl(t_tree *tree, phydbl fact) { int i; t_edge *b,*orig; For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; /* b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact; */ orig = b; do { b->l->v = b->l_old->v + (b->nni->l0 - b->l_old->v)*fact; if(b->next) b = b->next; else b = b->next; } while(b); b = orig; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_N_Swap(t_tree *tree,t_edge **b, int beg, int end) { int i; int dim; t_edge *orig; dim = 2*tree->n_otu-2; /* PhyML_Printf("\n. Beg Actually performing swaps\n"); */ tree->n_swap = 0; for(i=beg;inum, */ /* b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]]->num, */ /* b[i]->nni->swap_node_v2->num, */ /* b[i]->nni->swap_node_v3->num, */ /* b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]]->num); */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); } if(tree->n_root) { tree->n_root->v[2] = tree->e_root->left; tree->n_root->v[1] = tree->e_root->rght; } orig = b[i]; do { b[i]->l->v = b[i]->nni->best_l; if(b[i]->next) b[i] = b[i]->next; else b[i] = b[i]->next; } while(b[i]); b[i] = orig; tree->n_swap++; } /* PhyML_Printf("\n. End Actually performing swaps\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Make_Best_Swap(t_tree *tree) { int i,j,return_value; t_edge *b,**sorted_b; int dim; t_edge *orig; dim = 2*tree->n_otu-2; sorted_b = (t_edge **)mCalloc(tree->n_otu-3,sizeof(t_edge *)); j=0; For(i,2*tree->n_otu-3) if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) sorted_b[j++] = tree->a_edges[i]; Sort_Edges_NNI_Score(tree,sorted_b,tree->n_otu-3); if(sorted_b[0]->nni->score < -0.0) { b = sorted_b[0]; return_value = 1; Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]], b->nni->swap_node_v2, b->nni->swap_node_v3, b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b->nni->swap_node_v2->v[tree->t_dir[b->nni->swap_node_v2->num*dim+b->nni->swap_node_v1->num]], b->nni->swap_node_v2, b->nni->swap_node_v3, b->nni->swap_node_v3->v[tree->t_dir[b->nni->swap_node_v3->num*dim+b->nni->swap_node_v4->num]], tree); } /* b->l->v = b->nni->best_l; */ orig = b; do { b->l->v = b->nni->best_l; if(b->next) b = b->next; else b = b->next; } while(b); b = orig; /* (b->nni->best_conf == 1)? */ /* (Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v1],tree)): */ /* (Swap(b->left->v[b->l_v2],b->left,b->rght,b->rght->v[b->r_v2],tree)); */ /* b->l->v = */ /* (b->nni->best_conf == 1)? */ /* (b->nni->l1): */ /* (b->nni->l2); */ } else return_value = 0; Free(sorted_b); return return_value; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Mov_Backward_Topo_Bl(t_tree *tree, phydbl lk_old, t_edge **tested_b, int n_tested) { phydbl **l_init; int i,j,step,beg,end; t_edge *b,*orig; l_init = (phydbl **)mCalloc(2*tree->n_otu-3,sizeof(phydbl *)); For(i,2*tree->n_otu-3) l_init[i] = MIXT_Get_Lengths_Of_This_Edge(tree->a_edges[i],tree); step = 2; do { For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; /* b->l->v = b->l_old->v + (1./step) * (l_init[i] - b->l_old->v); */ j = 0; orig = b; do { b->l->v = b->l_old->v + (1./step) * (l_init[i][j] - b->l_old->v); if(b->next) b = b->next; else b = b->next; j++; } while(b); b = orig; } beg = (int)FLOOR((phydbl)n_tested/(step-1)); end = 0; Unswap_N_Branch(tree,tested_b,beg,end); beg = 0; end = (int)FLOOR((phydbl)n_tested/step); Swap_N_Branch(tree,tested_b,beg,end); if(!end) tree->n_swap = 0; Set_Both_Sides(NO,tree); Lk(NULL,tree); step++; }while((tree->c_lnL < lk_old) && (step < 1000)); if(step == 1000) { if(tree->n_swap) Exit("\n== Err. in Mov_Backward_Topo_Bl (n_swap > 0)\n"); For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; orig = b; do { b->l->v = b->l_old->v; if(b->next) b = b->next; else b = b->next; } while(b); b = orig; } Set_Both_Sides(NO,tree); Lk(NULL,tree); } For(i,2*tree->n_otu-3) Free(l_init[i]); Free(l_init); tree->n_swap = 0; For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->nni->score < 0.0) tree->n_swap++; tree->a_edges[i]->nni->score = +1.0; } if(tree->c_lnL > lk_old) return 1; else if((tree->c_lnL > lk_old-tree->mod->s_opt->min_diff_lk_local) && (tree->c_lnL < lk_old+tree->mod->s_opt->min_diff_lk_local)) return -1; else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_tested) { int i,step,beg,end; step = 2; do { beg = (int)FLOOR((phydbl)n_tested/(step-1)); end = 0; Unswap_N_Branch(tree,tested_b,beg,end); beg = 0; end = (int)FLOOR((phydbl)n_tested/step); Swap_N_Branch(tree,tested_b,beg,end); if(!end) tree->n_swap = 0; Set_Both_Sides(NO,tree); Pars(NULL,tree); step++; }while((tree->c_pars > pars_old) && (step < 1000)); if(step == 1000) { if(tree->n_swap) Exit("\n. Err. in Mov_Backward_Topo_Bl (n_swap > 0)\n"); Set_Both_Sides(NO,tree); Pars(NULL,tree); } tree->n_swap = 0; For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->nni->score < 0.0) tree->n_swap++; tree->a_edges[i]->nni->score = +1.0; } if(tree->c_pars < pars_old) return 1; else if(tree->c_pars == pars_old) return -1; else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Unswap_N_Branch(t_tree *tree, t_edge **b, int beg, int end) { int i; int dim; t_edge *orig; dim = 2*tree->n_otu-2; if(end>beg) { for(i=beg;inum, */ /* b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num][b[i]->nni->swap_node_v1->num]]->num, */ /* b[i]->nni->swap_node_v4->num, */ /* b[i]->nni->swap_node_v2->num, */ /* b[i]->nni->swap_node_v3->num, */ /* b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num][b[i]->nni->swap_node_v4->num]]->num, */ /* b[i]->nni->swap_node_v1->num */ /* ); */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); } /* (b[i]->nni->best_conf == 1)? */ /* (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v1],tree)): */ /* (Swap(b[i]->left->v[b[i]->l_v2],b[i]->left,b[i]->rght,b[i]->rght->v[b[i]->r_v2],tree)); */ /* b[i]->l->v = b[i]->l_old->v; */ orig = b[i]; do { b[i]->l->v = b[i]->l_old->v; if(b[i]->next) b[i] = b[i]->next; else b[i] = b[i]->next; } while(b[i]); b[i] = orig; } } else { for(i=beg-1;i>=end;i--) { Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); } /* b[i]->l->v = b[i]->l_old->v; */ orig = b[i]; do { b[i]->l->v = b[i]->l_old->v; if(b[i]->next) b[i] = b[i]->next; else b[i] = b[i]->next; } while(b[i]); b[i] = orig; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Swap_N_Branch(t_tree *tree,t_edge **b, int beg, int end) { int i; int dim; t_edge *orig; dim = 2*tree->n_otu-2; if(end>beg) { for(i=beg;inni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); } /* b[i]->l->v = b[i]->nni->best_l; */ orig = b[i]; do { b[i]->l->v = b[i]->nni->best_l; if(b[i]->next) b[i] = b[i]->next; else b[i] = b[i]->next; } while(b[i]); b[i] = orig; } } else { for(i=beg-1;i>=end;i--) { Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) { /* Undo this swap as it violates one of the topological constraints defined in the input constraint tree */ Swap(b[i]->nni->swap_node_v2->v[tree->t_dir[b[i]->nni->swap_node_v2->num*dim+b[i]->nni->swap_node_v1->num]], b[i]->nni->swap_node_v2, b[i]->nni->swap_node_v3, b[i]->nni->swap_node_v3->v[tree->t_dir[b[i]->nni->swap_node_v3->num*dim+b[i]->nni->swap_node_v4->num]], tree); } /* b[i]->l->v = b[i]->nni->best_l; */ orig = b[i]; do { b[i]->l->v = b[i]->nni->best_l; if(b[i]->next) b[i] = b[i]->next; else b[i] = b[i]->next; } while(b[i]); b[i] = orig; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score, t_tree *tree) { int i; For(i,3) { if((d->v[i] != a) && (!d->v[i]->tax)) { if((d->b[i]->nni->score > *best_score-1.E-10) && (d->b[i]->nni->score < *best_score+1.E-10)) /* ties */ { d->b[i]->nni->score = *best_score+1.; } if(d->b[i]->nni->score < *best_score) { *best_score = d->b[i]->nni->score; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/simu.h000066400000000000000000000021141263450375500145720ustar00rootroot00000000000000/* PHYML : a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences Copyright (C) Stephane Guindon. Oct 2003 onward All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef CURR_H #define CURR_H #include "utilities.h" void Simu_Loop(t_tree *tree); int Simu(t_tree *tree,int n_step_max); void Select_Edges_To_Swap(t_tree *tree,t_edge **sorted_b,int *n_neg); void Update_Bl(t_tree *tree,phydbl fact); void Make_N_Swap(t_tree *tree,t_edge **b,int beg,int end); int Make_Best_Swap(t_tree *tree); int Mov_Backward_Topo_Bl(t_tree *tree,phydbl lk_old,t_edge **tested_b,int n_tested); void Unswap_N_Branch(t_tree *tree,t_edge **b,int beg,int end); void Swap_N_Branch(t_tree *tree,t_edge **b,int beg,int end); void Check_NNI_Scores_Around(t_node *a, t_node *d, t_edge *b, phydbl *best_score, t_tree *tree); int Mov_Backward_Topo_Pars(t_tree *tree, int pars_old, t_edge **tested_b, int n_tested); void Simu_Pars(t_tree *tree, int n_step_max); #endif phyml-3.2.0/src/spr.c000066400000000000000000003735531263450375500144360ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* ** spr.c: Routines for performing SPR moves on the tree. ** ** Wim Hordijk Last modified: 28 August 2006 ** Stephane Guindon 2007 */ #include "spr.h" #ifdef BEAGLE #include "beagle_utils.h" #endif /* ** BIG: Some big number. */ /* #define BIG 1e05 */ /* ** Global vars. ** ** - cur_lk: The current likelihood of the tree. ** - subtree_dist: The average subtree distances matrix. ** - seq_dist: The sequence distance matrix. ** - optim_cand: Array for holding candidate moves for local and global branch ** length optimization. ** - rgrft_cand: Array for holding candidate regraft positions. ** - v_tmp: The central t_node of the temporary regraft structure for ** estimating changes in likelihood. ** - path: The path through the tree during the recursive tree length ** calculation. ** - sum_scale_tmp Array for temporarily storing scaling factors. ** - p_lk_tmp: Temporary partial likelihood storage. ** - e_brent: A temporary t_edge to use for estimating distances using Brent. ** - tree->mod->s_opt->wim_n_rgrft: Number of promising regraft positions to consider when performing all improving SPR moves. ** - tree->mod->s_opt->wim_n_optim: Number of candidate moves on which to perform local branch length optimization. ** - tree->mod->s_opt->wim_max_dist: Maximum regraft distance to consider. ** - tree->mod->s_opt->wim_n_globl: Number of candidates moves on which to perform global branch length optimization. ** - tree->mod->s_opt->wim_n_best: Number of promising regraft positions to consider when performing only the best SPR move. ** - nr_d_l: Total number of change in tree length calculations done. ** - nr_d_lk: Total number of change in likelihood calculations done. ** - nr_loc: Total number of local branch length optimizations done. ** - nr_glb: Total number of global branch length optimizations done. */ phydbl cur_lk, **subtree_dist, *sum_scale_tmp, *p_lk_tmp; matrix *seq_dist; _move_ **optim_cand, **rgrft_cand; t_node *v_tmp=NULL, **path; t_edge *e_brent=NULL; int nr_d_L, nr_d_lk, nr_loc, nr_glb; /* ** Init_SPR: Initialize the SPR algorithm: allocate memory and set variables. ** ** Parameters: ** - tree: The current tree to use for initialization. */ void Init_SPR (t_tree *tree) { int i, nr_nodes, nr_edges; t_node *u_0, *u_1, *u_2; /* ** Get the SPR parameter values. */ nr_edges = 2*tree->n_otu-3; if(tree->mod->s_opt->wim_n_rgrft < 0) tree->mod->s_opt->wim_n_rgrft = 1 + nr_edges / 5; if(tree->mod->s_opt->wim_n_globl < 0) tree->mod->s_opt->wim_n_globl = 1 + nr_edges / 10; if(tree->mod->s_opt->wim_max_dist < 0) tree->mod->s_opt->wim_max_dist = 1 + nr_edges / 10; if(tree->mod->s_opt->wim_n_optim < 0) tree->mod->s_opt->wim_n_optim = 100; if(tree->mod->s_opt->wim_n_best < 0) tree->mod->s_opt->wim_n_best = tree->mod->s_opt->wim_n_rgrft; /* can't * be * anything else */ /* ** If it doesn't exist yet, create the temporary regraft structure: ** a central t_node with three edges and tip nodes adjacent to it. */ if (v_tmp == NULL) { v_tmp=Make_Node_Light(0); v_tmp->tax = 0; u_0=Make_Node_Light(1); u_0->tax = 1; u_1=Make_Node_Light(2); u_1->tax = 1; u_2=Make_Node_Light(3); u_2->tax = 1; v_tmp->v[0] = u_0; v_tmp->v[1] = u_1; v_tmp->v[2] = u_2; u_0->v[0] = v_tmp; u_1->v[0] = v_tmp; u_2->v[0] = v_tmp; t_edge *edge_0 = Make_Edge_Light (v_tmp, u_0, 0); Make_Edge_Lk (edge_0, tree); t_edge *edge_1 = Make_Edge_Light (v_tmp, u_1,1); Make_Edge_Lk (edge_1, tree); t_edge *edge_2 = Make_Edge_Light (v_tmp, u_2,2); Make_Edge_Lk (edge_2, tree); /* For(i,tree->data->crunch_len) */ /* { */ /* For(j,tree->mod->ras->n_catg) */ /* { */ /* Free(edge_0->p_lk_rght[i][j]); */ /* } */ /* Free(edge_0->p_lk_rght[i]); */ /* } */ Free(edge_0->p_lk_rght); if(!edge_0->rght->tax) Free(edge_0->sum_scale_rght); /* For(i,tree->data->crunch_len) */ /* { */ /* For(j,tree->mod->ras->n_catg) */ /* { */ /* Free(edge_1->p_lk_rght[i][j]); */ /* } */ /* Free(edge_1->p_lk_rght[i]); */ /* } */ Free(edge_1->p_lk_rght); if(!edge_1->rght->tax) Free(edge_1->sum_scale_rght); /* For(i,tree->data->crunch_len) */ /* { */ /* For(j,tree->mod->ras->n_catg) */ /* { */ /* Free(edge_2->p_lk_rght[i][j]); */ /* } */ /* Free(edge_2->p_lk_rght[i]); */ /* } */ Free(edge_2->p_lk_rght); if(!edge_2->rght->tax) Free(edge_2->sum_scale_rght); } /* ** If it doesn't exist yet, create the temporary edge. */ if (e_brent == NULL) { u_1=Make_Node_Light(4); u_1->tax = 1; u_2=Make_Node_Light(5); u_2->tax = 1; u_1->v[0] = u_2; u_2->v[0] = u_1; t_edge *edge_4 = Make_Edge_Light (u_1, u_2, 3); Make_Edge_Lk (edge_4, tree); e_brent = u_1->b[0]; /* For(i,tree->data->crunch_len) */ /* { */ /* For(j,tree->mod->ras->n_catg) */ /* { */ /* Free(edge_4->p_lk_rght[i][j]); */ /* } */ /* Free(edge_4->p_lk_rght[i]); */ /* } */ Free(edge_4->p_lk_rght); if(!edge_4->rght->tax) Free(edge_4->sum_scale_rght); /* For(i,tree->data->crunch_len) */ /* { */ /* For(j,tree->mod->ras->n_catg) */ /* { */ /* Free(edge_4->p_lk_left[i][j]); */ /* } */ /* Free(edge_4->p_lk_left[i]); */ /* } */ Free(edge_4->p_lk_left); if(!edge_4->left->tax) Free(edge_4->sum_scale_left); } /* ** Allocate memory for temporarily storing partial likelihoods and ** scaling factors. */ p_lk_tmp = (phydbl *)mCalloc (tree->n_pattern*tree->mod->ras->n_catg*tree->mod->ns, sizeof (phydbl)); /* p_lk_tmp = (phydbl ***)mCalloc (tree->n_pattern, sizeof (phydbl **)); */ /* for (i = 0; i < tree->n_pattern; i++) */ /* { */ /* p_lk_tmp[i] = (phydbl **)mCalloc (tree->mod->ras->n_catg, sizeof (phydbl *)); */ /* for (j = 0; j < tree->mod->ras->n_catg; j++) */ /* { */ /* p_lk_tmp[i][j] = (phydbl *)mCalloc (tree->mod->ns, sizeof (phydbl)); */ /* } */ /* } */ sum_scale_tmp = (phydbl *)mCalloc (tree->n_pattern, sizeof (phydbl)); /* ** Allocate memory for storing the average subtree distances. */ nr_nodes = 2*tree->n_otu-2; subtree_dist = (phydbl **)malloc (nr_nodes * sizeof (phydbl *)); for (i = 0; i < nr_nodes; i++) { subtree_dist[i] = (phydbl *)malloc (nr_nodes * sizeof (phydbl)); } /* ** Allocate memory for storing the candidate regraft positions and ** t_edge length optimization moves. */ rgrft_cand = (_move_ **)malloc (MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best) * sizeof (_move_ *)); for (i = 0; i < MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best); i++) { rgrft_cand[i] = (_move_ *)malloc (sizeof (_move_)); rgrft_cand[i]->path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *)); } optim_cand = (_move_ **)malloc (tree->mod->s_opt->wim_n_optim * sizeof (_move_ *)); for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++) { optim_cand[i] = (_move_ *)malloc (sizeof (_move_)); optim_cand[i]->path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *)); } path = (t_node **)malloc ((tree->mod->s_opt->wim_max_dist+2) * sizeof (t_node *)); if(!tree->mat) { seq_dist = ML_Dist (tree->data, tree->mod); tree->mat = seq_dist; } else seq_dist = tree->mat; /* ** Set variables. */ nr_d_L = 0; nr_d_lk = 0; nr_loc = 0; nr_glb = 0; } /* ** Clean_SPR: Free up the used memory. ** ** Parameters: ** - tree: The current tree. */ void Clean_SPR (t_tree *tree) { int i; /* ** Clean up the temporary regraft structure. */ Free_Node (v_tmp->v[0]); Free_Node (v_tmp->v[1]); Free_Node (v_tmp->v[2]); v_tmp->b[0]->p_lk_rght = NULL; Free_Edge_Lk (v_tmp->b[0]); Free_Edge (v_tmp->b[0]); v_tmp->b[1]->p_lk_rght = NULL; Free_Edge_Lk(v_tmp->b[1]); Free_Edge(v_tmp->b[1]); v_tmp->b[2]->p_lk_rght = NULL; Free_Edge_Lk (v_tmp->b[2]); Free_Edge (v_tmp->b[2]); Free_Node (v_tmp); v_tmp = NULL; /* ** Clean up the temporary edge. */ Free_Node (e_brent->left); Free_Node (e_brent->rght); e_brent->p_lk_left = NULL; e_brent->p_lk_rght = NULL; Free_Edge_Lk (e_brent); Free_Edge (e_brent); e_brent = NULL; /* ** Free the temporary partial likelihood and scaling memory. */ /* for (i = 0; i < tree->n_pattern; i++) */ /* { */ /* for (j = 0; j < tree->mod->ras->n_catg; j++) */ /* { */ /* free (p_lk_tmp[i][j]); */ /* } */ /* free (p_lk_tmp[i]); */ /* } */ free (p_lk_tmp); free (sum_scale_tmp); /* ** Free the subtree distance matrix. */ for (i = 0; i < 2*tree->n_otu - 2; i++) { free (subtree_dist[i]); } free (subtree_dist); /* ** Free the arrays for storing the candidate regrafting positions and ** t_edge length optimization moves. */ for (i = 0; i < MAX(tree->mod->s_opt->wim_n_rgrft,tree->mod->s_opt->wim_n_best); i++) { free (rgrft_cand[i]->path); free (rgrft_cand[i]); } free (rgrft_cand); for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++) { free (optim_cand[i]->path); free (optim_cand[i]); } free (optim_cand); free (path); /* ** Print some statistics (for "research" purposes only). */ /* PhyML_Printf ("nr_d_L: %d\n", nr_d_L); */ /* PhyML_Printf ("nr_d_lk: %d\n", nr_d_lk); */ /* PhyML_Printf ("nr_loc: %d\n", nr_loc); */ /* PhyML_Printf ("nr_glb: %d\n", nr_glb); */ } /* ** Optim_SPR: Optimize the tree using SPR moves. ** ** Parameters: ** - tree: The tree to optimize. ** - max_size: The maximum size (= number of taxa) of the subtrees to be ** pruned. If m=0 or m>ntax, all possible prunings will be ** considered. ** - method: The optimization method to use ("ALL" or "BEST"). */ void Optim_SPR (t_tree *tree, int max_size, int method) { int nr_moves, improvement; if(tree->mod->s_opt->print) PhyML_Printf("\n\n. Starting SPR moves...\n"); /* ** Calculate the current likelihood value. */ Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); time(&(tree->t_current)); if(tree->mod->s_opt->print) Print_Lk(tree,"topology"); /* ** Optimize all t_edge lengths and calculate the new likelihood value. */ /* PhyML_Printf("\n. Optimizing t_edge lengths."); */ Optimize_Br_Len_Serie (tree); Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); time(&(tree->t_current)); if(tree->mod->s_opt->print) Print_Lk(tree,"topology"); /* ** While improvements were found, perform another round of SPR moves. */ nr_moves = 0; improvement = 1; while (improvement) { /* ** Perform one round of SPR moves. */ if (method == ALL) { improvement = Perform_SPR_Moves (tree, max_size); } else if (method == BEST) { improvement = Perform_Best_SPR (tree, max_size); } else if (method == ONE) { improvement = Perform_One_SPR (tree, max_size); } else { PhyML_Printf ("\n. Unknown SPR optimization method, bailing out...\n"); exit (1); } /* If an improvement was found, update statistics. */ if(improvement) { nr_moves++; if((nr_moves == 1) || (nr_moves % 4 == 1)) { /* ** Optimize model parameters. */ Optimiz_All_Free_Param (tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print)); Set_Both_Sides(YES,tree); Lk(NULL,tree); } } /* Beg SG 28 May 2007 */ if(method == BEST || method == ONE) break; /* Beg SG 28 May 2007 */ } if(tree->mod->s_opt->print) PhyML_Printf ("\n\n. Number of SPR moves: %d\n", nr_moves); /* ** Perform a last round of optimization steps (for t_edge lengths). */ Round_Optimize(tree,tree->data,ROUND_MAX); Check_NNI_Five_Branches(tree); } /* ** Perform_SPR_Moves: Perform a round of SPR moves on the tree. Prune each subtree in ** turn and calculate the change in tree length for each candidate ** regraft position. Estimate change in likelihood for the most ** promising moves, and perform all moves that result in an ** improvement. If no improvements were found at all, try local edge ** length optimization. If still no improvement, try global edge ** length optimization. ** ** Parameters: ** - tree: The tree to perform the SPR moves on. ** - max_size: The maximum size (= number of taxa) of the subtrees to be ** pruned. If m=0 or m>ntax, all possible prunings will be ** considered. ** ** Returns: ** If the current tree could be improved: 1. ** Otherwise: 0. */ int Perform_SPR_Moves (t_tree *tree, int max_size) { int nr_edges, i, j, candidate, improvement; t_node *root, *v_prune; t_edge *e_prune; /* ** Calculate the average subtree distances. */ root = tree->a_nodes[0]; PostOrder_v (tree, root->v[2], root->b[2]); /* ** Initialize the array of optimization candidates. */ for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++) { optim_cand[i]->delta_lk = -1.0*BIG; optim_cand[i]->d_L = -1.0*BIG; } /* ** Try all possible SPR moves and perform the ones that give an improvement. */ nr_edges = 2*tree->n_otu - 3; cur_lk = tree->c_lnL; improvement = 0; /* PhyML_Printf("\n >>>>>>>>>>>>>>>>>>"); */ /* PhyML_Printf("\n. cur_lk = %f %f",cur_lk,Lk(NULL,tree)); */ /* PhyML_Printf ("\n. Trying SPR moves"); */ /* PhyML_Printf ("\n. - calculating tree distances and estimating likelihoods"); */ for(i = 0; i < nr_edges; i++) { /* ** Get the next prune edge. */ e_prune = tree->a_edges[i]; /* ** Try right subtree if appropriate. */ if (!e_prune->left->tax) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->left; /* if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Perform moves that give an improvement. */ Calc_Tree_Length (e_prune, v_prune, tree); if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0) { improvement = 1; Make_Move (rgrft_cand[candidate],0,tree); /* PhyML_Printf("\n. Make simple move"); */ /* PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */ } } } /* ** Try left subtree if appropriate. */ if (!e_prune->rght->tax) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->rght; /* if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Perform moves that give an improvement. */ Calc_Tree_Length (e_prune, v_prune, tree); if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0) { improvement = 1; Make_Move (rgrft_cand[candidate],0,tree); /* PhyML_Printf("\n. Make simple move"); */ /* PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */ } } } } /* ** If there was no improvement at all, try local t_edge length optimization at the ** regraft position. */ /* PhyML_Printf("\n. before local = %f %f",tree->c_lnL,Lk(tree)); */ if (!improvement) { /* PhyML_Printf ("\n. - performing local t_edge length optimizations"); */ if ((candidate = Find_Optim_Local (tree)) >= 0) { /* PhyML_Printf("\n. make local move"); */ improvement = 1; Make_Move (optim_cand[candidate],1,tree); /* PhyML_Printf("\n. lk after local move = %f",Lk(tree)); */ } } /* ** If there was still no improvement, try global t_edge length optimization. */ /* PhyML_Printf("\n. before global = %f %f",tree->c_lnL,Lk(tree)); */ if (!improvement) { /* PhyML_Printf ("\n. - performing global t_edge length optimization"); */ if ((candidate = Find_Optim_Globl (tree)) >= 0) { /* PhyML_Printf("\n. make global move"); */ improvement = 1; Make_Move (optim_cand[candidate],2,tree); /* PhyML_Printf("\n. lk after global move = %f",Lk(tree)); */ } } /* PhyML_Printf("\n. after all = %f %f",tree->c_lnL,Lk(tree)); */ /* ** Optimize all t_edge lengths again to make sure we got an updated ** likelihood value. */ Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); root = tree->a_nodes[0]; Optimize_Br_Len_Serie (tree); Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); time(&(tree->t_current)); if(tree->mod->s_opt->print) Print_Lk(tree,"topoLOGy"); /* ** Return the result. */ return (improvement); } /* ** Perform_Best_SPR: Perform the best SPR move on the tree. Prune each subtree in ** turn and calculate the change in tree length for each candidate ** regraft position. Estimate change in likelihood for the most ** promising regraft positions, and store the best one. Then choose ** the best candidate over all moves. If no improving move can be ** found, try local t_edge length optimization, and if necessary ** global t_edge length optimization. ** ** Parameters: ** - tree: The tree to perform the SPR moves on. ** - max_size: The maximum size (= number of taxa) of the subtrees to be ** pruned. If m=0 or m>ntax, all possible prunings will be ** considered. ** ** Returns: ** If an improving move could be performed: 1. ** Otherwise: 0. */ int Perform_Best_SPR (t_tree *tree, int max_size) { int nr_edges, i, j, candidate, improvement; t_node *root, *v_prune; t_edge *e_prune; /* ** Calculate the average subtree distances. */ root = tree->a_nodes[0]; PostOrder_v (tree, root->v[2], root->b[2]); /* ** Initialize the array of optimization candidates. */ for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++) { optim_cand[i]->delta_lk = -1.0*BIG; optim_cand[i]->d_L = -1.0*BIG; } /* ** Try all possible SPR moves and perform the best one. */ nr_edges = 2*tree->n_otu - 3; cur_lk = tree->c_lnL; improvement = 0; /* PhyML_Printf ("\n. Trying SPR moves"); */ /* PhyML_Printf ("\n. -calculating tree distances and estimating likelihoods"); */ for (i = 0; i < nr_edges; i++) { /* ** Get the next prune edge. */ e_prune = tree->a_edges[i]; /* ** Try right subtree if appropriate. */ if (!e_prune->left->tax) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_best; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->left; /* if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Store the best one in the optimization list. */ Calc_Tree_Length (e_prune, v_prune, tree); candidate = Best_Lk_Change (e_prune, v_prune, tree); } } /* ** Try left subtree if appropriate. */ if (!e_prune->rght->tax) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->rght; /* if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Perform moves that give an improvement. */ Calc_Tree_Length (e_prune, v_prune, tree); candidate = Best_Lk_Change (e_prune, v_prune, tree); } } } /* If the best candidate has a positive estimated change in ** likelihood, perform that move. */ if (optim_cand[0]->delta_lk > 1.0/BIG) { improvement = 1; Make_Move (optim_cand[0],0,tree); } /* ** If there was no improvement at all, try local t_edge length optimization at the ** regraft position. */ if (!improvement) { /* PhyML_Printf ("\n. - performing local t_edge length optimizations"); */ if ((candidate = Find_Optim_Local (tree)) >= 0) { improvement = 1; Make_Move (optim_cand[candidate],1,tree); } } /* ** If there was still no improvement, try global t_edge length optimization. */ if (!improvement) { /* PhyML_Printf ("\n. - performing global t_edge length optimization"); */ if ((candidate = Find_Optim_Globl (tree)) >= 0) { improvement = 1; Make_Move (optim_cand[candidate],2,tree); } } /* ** Optimize all t_edge lengths again to make sure we got an updated ** likelihood value. */ Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); root = tree->a_nodes[0]; Optimize_Br_Len_Serie (tree); Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); time(&(tree->t_current)); if(tree->mod->s_opt->print) Print_Lk(tree,"topology"); /* ** Return the result. */ return (improvement); } /* ** Perform_One_Moves: Perform a round of SPR moves on the tree. Prune each subtree in ** turn and calculate the change in tree length for each candidate ** regraft position. Estimate change in likelihood for the most ** promising moves, and perform the first move that results in an ** improvement. If no improvements were found at all, try local edge ** length optimization. If still no improvement, try global edge ** length optimization. ** ** Parameters: ** - tree: The tree to perform the SPR moves on. ** - max_size: The maximum size (= number of taxa) of the subtrees to be ** pruned. If m=0 or m>ntax, all possible prunings will be ** considered. ** ** Returns: ** If the current tree could be improved: 1. ** Otherwise: 0. */ int Perform_One_SPR(t_tree *tree, int max_size) { int nr_edges, i, j, candidate, improvement; t_node *root, *v_prune; t_edge *e_prune; /* ** Calculate the average subtree distances. */ root = tree->a_nodes[0]; PostOrder_v (tree, root->v[2], root->b[2]); /* ** Initialize the array of optimization candidates. */ for (i = 0; i < tree->mod->s_opt->wim_n_optim; i++) { optim_cand[i]->delta_lk = -1.0*BIG; optim_cand[i]->d_L = -1.0*BIG; } /* ** Try all possible SPR moves and perform the ones that give an improvement. */ nr_edges = 2*tree->n_otu - 3; cur_lk = tree->c_lnL; improvement = 0; /* PhyML_Printf("\n >>>>>>>>>>>>>>>>>>"); */ /* PhyML_Printf("\n. cur_lk = %f %f",cur_lk,Lk(tree)); */ /* PhyML_Printf ("\n. Trying SPR moves"); */ /* PhyML_Printf ("\n. - calculating tree distances and estimating likelihoods"); */ for(i = 0; i < nr_edges; i++) { /* ** Get the next prune edge. */ e_prune = tree->a_edges[i]; /* ** Try right subtree if appropriate. */ if (!e_prune->left->tax) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->left; /* if ((max_size == 0) || (e_prune->num_tax_rght <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Perform moves that give an improvement. */ Calc_Tree_Length (e_prune, v_prune, tree); if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0) { improvement = 1; Make_Move (rgrft_cand[candidate],0,tree); } } } /* ** Try left subtree if appropriate. */ if (!e_prune->rght->tax && !improvement) { /* ** Clear the regraft candidate list. */ for (j = 0; j < tree->mod->s_opt->wim_n_rgrft; j++) { rgrft_cand[j]->d_L = -1.0*BIG; } v_prune = e_prune->rght; /* if ((max_size == 0) || (e_prune->num_tax_left <= max_size)) */ { /* ** Calculate changes in tree length, and estimate changes in likelihood for ** the most promising candidates. Perform moves that give an improvement. */ Calc_Tree_Length (e_prune, v_prune, tree); if ((candidate = Est_Lk_Change (e_prune, v_prune, tree)) >= 0) { improvement = 1; Make_Move (rgrft_cand[candidate],0,tree); /* PhyML_Printf("\n. Make simple move"); */ /* PhyML_Printf("\n. lk after simple move = %f",Lk(tree)); */ } } } if(improvement) break; } /* ** If there was no improvement at all, try local t_edge length optimization at the ** regraft position. */ /* PhyML_Printf("\n. before local = %f %f",tree->c_lnL,Lk(tree)); */ if (!improvement) { /* PhyML_Printf ("\n. - performing local t_edge length optimizations"); */ if ((candidate = Find_Optim_Local (tree)) >= 0) { /* PhyML_Printf("\n. make local move"); */ improvement = 1; Make_Move (optim_cand[candidate],1,tree); /* PhyML_Printf("\n. lk after local move = %f",Lk(tree)); */ } } /* ** If there was still no improvement, try global t_edge length optimization. */ /* PhyML_Printf("\n. before global = %f %f",tree->c_lnL,Lk(tree)); */ if (!improvement) { /* PhyML_Printf ("\n. - performing global t_edge length optimization"); */ if ((candidate = Find_Optim_Globl (tree)) >= 0) { /* PhyML_Printf("\n. make global move"); */ improvement = 1; Make_Move (optim_cand[candidate],2,tree); /* PhyML_Printf("\n. lk after global move = %f",Lk(tree)); */ } } /* PhyML_Printf("\n. after all = %f %f",tree->c_lnL,Lk(tree)); */ /* ** Optimize all t_edge lengths again to make sure we got an updated ** likelihood value. */ Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); root = tree->a_nodes[0]; Optimize_Br_Len_Serie (tree); Set_Both_Sides(YES,tree); cur_lk = Lk(NULL,tree); time(&(tree->t_current)); if(tree->mod->s_opt->print) Print_Lk(tree,"topology"); /* ** Return the result. */ return (improvement); } /* ** Calc_Tree_Length: Calculate the change in tree length, given a pruned subtree, ** for each possible regraft position. ** ** Parameters: ** - e_prune: The t_edge at which the subtree is pruned. ** - v_prune: The root of the pruned subtree. */ void Calc_Tree_Length (t_edge *e_prune, t_node *v_prune, t_tree *tree) { int i, d0, d1, d2; phydbl d_uu; t_node *u_prune, *u1, *u2; /* ** Get the directions from t_node v_prune. */ d0 = -1; u_prune = NULL; for (i = 0; i < 3; i++) { if (v_prune->b[i] == e_prune) { d0 = i; u_prune = v_prune->v[i]; break; } } d1 = (d0 + 1) % 3; d2 = 3 - d0 - d1; /* ** Get the relevant average subtree distance within the pruned subtree. */ if (!u_prune->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_prune->b[i] != e_prune) { if (u1 == NULL) { u1 = u_prune->v[i]; } else { u2 = u_prune->v[i]; } } } d_uu = subtree_dist[u1->num][u2->num]; } else { d_uu = 0.0; } /* ** Recursively calculate the change in tree length for each ** possible regraft position. ** ** First recurse into direction d1. */ if (!v_prune->v[d1]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d1]->b[i] != v_prune->b[d1]) { if (u1 == NULL) { u1 = v_prune->v[d1]->v[i]; } else { u2 = v_prune->v[d1]->v[i]; } } } Tree_Length(v_prune, u_prune, v_prune->v[d1], v_prune->v[d2], u1, v_prune->v[d2], u2, subtree_dist[u_prune->num][v_prune->v[d2]->num], d_uu, 0.0, 1, tree); Tree_Length(v_prune, u_prune, v_prune->v[d1], v_prune->v[d2], u2, v_prune->v[d2], u1, subtree_dist[u_prune->num][v_prune->v[d2]->num], d_uu, 0.0, 1, tree); } /* ** Next recurse into direction d2. */ if (!v_prune->v[d2]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d2]->b[i] != v_prune->b[d2]) { if (u1 == NULL) { u1 = v_prune->v[d2]->v[i]; } else { u2 = v_prune->v[d2]->v[i]; } } } Tree_Length(v_prune, u_prune, v_prune->v[d2], v_prune->v[d1], u1, v_prune->v[d1], u2, subtree_dist[u_prune->num][v_prune->v[d1]->num], d_uu, 0.0, 1, tree); Tree_Length(v_prune, u_prune, v_prune->v[d2], v_prune->v[d1], u2, v_prune->v[d1], u1, subtree_dist[u_prune->num][v_prune->v[d1]->num], d_uu, 0.0, 1, tree); } } /* ** Tree_Length: Recursively calculate the change in tree length for a given pruned ** subtree and regraft position. ** ** Parameters: ** - v_prune: The root of the pruned subtree. ** - u_prune: The t_node adjacent to v_p along the pruned edge. ** - v_n: The t_node adjacent to the regraft t_edge in the "backward" direction. ** - v_n_1: The previous v_n. ** - v_nx1: The t_node adjacent to the regrafting t_edge in the "forward" direction. ** - v_0: The other t_node originally adjacent to v_p; ** - u_n: The other t_node adjecent to v_n (besides v_n_1 and v_nx1); ** - d_uv_1: The distance between u_p and v_n_1; ** - d_uu: The subtree distance between descendants of u_prune. ** - d_L_1: The previous change in tree length. ** - n: The current distance from the prune position. */ void Tree_Length (t_node *v_prune, t_node *u_prune, t_node *v_n, t_node *v_n_1, t_node *v_nx1, t_node *v_0, t_node *u_n, phydbl d_up_v_1, phydbl d_L_1, phydbl d_uu, int n, t_tree *tree) { int i, j; phydbl d_un_v, d_up_v, d_L; t_node *u1, *u2; t_edge *e_prune, *e_regraft; _move_ *tmp_cand; /* ** Update the path and number of calculations. */ path[n] = v_n; nr_d_L++; e_prune = NULL; e_regraft = NULL; /* ** Calculate the change in tree length for the current pruned subtree and regraft ** position. */ if (n == 1) { d_un_v = subtree_dist[u_n->num][v_0->num]; } else { d_un_v = subtree_dist[u_n->num][v_n_1->num] - (pow (0.5, n) * subtree_dist[u_n->num][u_prune->num]) + (pow (0.5, n) * subtree_dist[u_n->num][v_0->num]); } d_up_v = 0.5 * (d_up_v_1 + subtree_dist[u_prune->num][u_n->num]); /* ** Alternative method for calculating d_up_v. Just kept it around for reference... ** d_up_v = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu); if (!u_n->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_n->v[i] != v_n) { if (u1 == NULL) { u1 = u_n->v[i]; } else { u2 = u_n->v[i]; } } } d_up_v -= 0.5 * subtree_dist[u1->num][u2->num]; } for (i = 0; i < 3; i++) { if (u_n->v[i] == v_n) { d_up_v -= u_n->b[i]->l->v; break; } } */ d_L = d_L_1 + 0.25*((d_up_v_1 + subtree_dist[u_n->num][v_nx1->num]) - (d_un_v + subtree_dist[u_prune->num][v_nx1->num])); /* ** If the change is within the tree->mod->s_opt->wim_n_rgrft best ones so far, save it. */ if (d_L > rgrft_cand[tree->mod->s_opt->wim_n_rgrft-1]->d_L) { for (i = 0; i < 3; i++) { if (v_prune->v[i] == u_prune) { e_prune = v_prune->b[i]; } if (v_n->v[i] == v_nx1) { e_regraft = v_n->b[i]; } } i = tree->mod->s_opt->wim_n_rgrft-1; rgrft_cand[i]->v_prune = v_prune; rgrft_cand[i]->u_prune = u_prune; rgrft_cand[i]->v_n = v_n; rgrft_cand[i]->v_nx1 = v_nx1; rgrft_cand[i]->u_n = u_n; rgrft_cand[i]->e_prune = e_prune; rgrft_cand[i]->e_regraft = e_regraft; rgrft_cand[i]->d_L = d_L; rgrft_cand[i]->d_up_v = d_up_v; rgrft_cand[i]->d_un_v = d_un_v; rgrft_cand[i]->dist = n; for (j = 1; j <= n; j++) { rgrft_cand[i]->path[j] = path[j]; } rgrft_cand[i]->path[n+1] = v_nx1; /* ** Move the candidate to the appropriate position in the list, so the list ** remains sorted in decreasing d_L value. */ while ((i > 0) && (rgrft_cand[i]->d_L > rgrft_cand[i-1]->d_L)) { tmp_cand = rgrft_cand[i]; rgrft_cand[i] = rgrft_cand[i-1]; rgrft_cand[i-1] = tmp_cand; i--; } } /* ** Recurse. */ if (n < tree->mod->s_opt->wim_max_dist) { if (!v_nx1->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_nx1->v[i] != v_n) { if (u1 == NULL) { u1 = v_nx1->v[i]; } else { u2 = v_nx1->v[i]; } } } Tree_Length (v_prune, u_prune, v_nx1, v_n, u1, v_0, u2, d_up_v, d_uu, d_L, n+1, tree); Tree_Length (v_prune, u_prune, v_nx1, v_n, u2, v_0, u1, d_up_v, d_uu, d_L, n+1, tree); } } } /* ** Est_Lk_Change: Estimate the changes in likelihood for the most promising candidate ** regraft positions given a pruned subtree. ** ** Parameters: ** - e_prune: The t_edge at which the subtree was pruned. ** - v_prune: The root of the pruned subtree. ** - tree: The tree on which to do the calculations. ** ** Returns: ** If an improvement as found: The candidate which gives the improvement (which ** will be the first one found). ** Otherwise: -1. */ int Est_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree) { int i, j, cand, best_cand, d0, d1, d2, n, pat, cat, ste; phydbl d_uu, best_d_lk, l_connect, l_01, l_02, l_12, l_est[3], new_lk, l_simple[3], l_dist[3]; phydbl *p_lk1_tmp, *p_lk2_tmp, *p_lk; int *p_sum; t_node *u_prune, *v_n, *v_nx1, *u1, *u2; t_edge *e_regraft, *e_tmp; _move_ *tmp_cand; int dim1, dim2; dim1 = tree->mod->ns * tree->mod->ras->n_catg; dim2 = tree->mod->ras->n_catg; /* ** Get the directions from t_node v_prune. */ d0 = -1; u_prune = NULL; for (i = 0; i < 3; i++) { if (v_prune->b[i] == e_prune) { d0 = i; u_prune = v_prune->v[i]; break; } } d1 = (d0 + 1) % 3; d2 = 3 - d0 - d1; /* ** Copy the relevant partial likelihoods to the temporary regraft structure. ** We can point to the original matrices, cos they won't be changed anyway. */ if (v_prune == e_prune->left) { v_tmp->b[0]->p_lk_rght = e_prune->p_lk_rght; v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_rght; } else { v_tmp->b[0]->p_lk_rght = e_prune->p_lk_left; v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_left; } v_tmp->num = v_prune->num; v_tmp->v[0]->num = u_prune->num; v_tmp->b[0]->num = e_prune->num; /* ** Estimate the length of the t_edge that will connect the two "detached" nodes ** after pruning. (The average of the sum of the lengths of the original two ** edges and the average subtree distance based estimate.) */ l_connect = subtree_dist[v_prune->v[d1]->num][v_prune->v[d2]->num]; if (!v_prune->v[d1]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d1]->b[i] != v_prune->b[d1]) { if (u1 == NULL) { u1 = v_prune->v[d1]->v[i]; } else { u2 = v_prune->v[d1]->v[i]; } } } l_connect -= 0.5 * subtree_dist[u1->num][u2->num]; } if (!v_prune->v[d2]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d2]->b[i] != v_prune->b[d2]) { if (u1 == NULL) { u1 = v_prune->v[d2]->v[i]; } else { u2 = v_prune->v[d2]->v[i]; } } } l_connect -= 0.5 * subtree_dist[u1->num][u2->num]; } l_connect += (v_prune->b[d1]->l->v + v_prune->b[d2]->l->v); l_connect /= 2.0; /* ** Temporarily swap the relevant partial likelihoods at the prune site. ** ** Direction d1. */ if (v_prune == v_prune->b[d1]->left) { p_lk1_tmp = v_prune->b[d1]->p_lk_left; if (v_prune == v_prune->b[d2]->left) { v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_rght; } else { v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_left; } } else { p_lk1_tmp = v_prune->b[d1]->p_lk_rght; if (v_prune == v_prune->b[d2]->left) { v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_rght; } else { v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_left; } } /* ** Direction d2. */ if (v_prune == v_prune->b[d2]->left) { p_lk2_tmp = v_prune->b[d2]->p_lk_left; if (v_prune == v_prune->b[d1]->left) { v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_rght; } else { v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_left; } } else { p_lk2_tmp = v_prune->b[d2]->p_lk_rght; if (v_prune == v_prune->b[d1]->left) { v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_rght; } else { v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_left; } } /* ** Temporarily set the t_edge lengths and update transition prob's at the ** prune site. */ v_prune->b[d1]->l_old->v = v_prune->b[d1]->l->v; v_prune->b[d2]->l_old->v = v_prune->b[d2]->l->v; v_prune->b[d1]->l->v = l_connect; v_prune->b[d2]->l->v = l_connect; Update_PMat_At_Given_Edge (v_prune->b[d1], tree); Update_PMat_At_Given_Edge (v_prune->b[d2], tree); /* ** Get the relevant average subtree distance within the pruned subtree. */ if (!u_prune->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_prune->b[i] != e_prune) { if (u1 == NULL) { u1 = u_prune->v[i]; } else { u2 = u_prune->v[i]; } } } d_uu = subtree_dist[u1->num][u2->num]; } else { d_uu = 0.0; } /* ** Try each candidate SPR and estimate the change in likelihood. */ best_d_lk = 1.0/BIG; best_cand = -1; for (cand = 0; cand < tree->mod->s_opt->wim_n_rgrft; cand++) { /* ** If there are no more candidates, bail out... */ if (FABS(rgrft_cand[cand]->d_L - 1.0*BIG) < SMALL) { break; } else { nr_d_lk++; } /* ** Get the relevant nodes and edges. */ v_n = rgrft_cand[cand]->v_n; v_nx1 = rgrft_cand[cand]->v_nx1; e_regraft = rgrft_cand[cand]->e_regraft; /* ** Update the relevant partial likelihoods along the path between the prune ** and regraft positions (temporarily save the first one). */ n = rgrft_cand[cand]->dist; e_tmp = NULL; p_lk = NULL; p_sum = NULL; for (i = 1; i <= n; i++) { /* ** Get the next t_edge along the path. */ for (j = 0; j < 3; j++) { if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1]) { e_tmp = rgrft_cand[cand]->path[i]->b[j]; break; } } if (i == 1) { /* ** Save the first partial likelihood along the path. */ if (rgrft_cand[cand]->path[i] == e_tmp->left) { p_lk = e_tmp->p_lk_left; p_sum = e_tmp->sum_scale_left; } else { p_lk = e_tmp->p_lk_rght; p_sum = e_tmp->sum_scale_rght; } for (pat = 0; pat < tree->n_pattern; pat++) { sum_scale_tmp[pat] = p_sum[pat]; for (cat = 0; cat < tree->mod->ras->n_catg; cat++) { for (ste = 0; ste < tree->mod->ns; ste++) { p_lk_tmp[pat*dim1+cat*dim2+ste] = p_lk[pat*dim1+cat*dim2+ste]; } } } } Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]); } if (v_n == e_regraft->left) { v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_left; v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_rght; v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_left; v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_rght; } else { v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_rght; v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_left; v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_rght; v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_left; } /* ** Estimate t_edge lengths of the three relevant regraft edges based on ** average subtree distances. ** ** l_01 */ /* ** Alternative method of estimating l_01. Kept it around for reference... ** l_01 = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu); if (!u_n->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_n->v[i] != v_n) { if (u1 == NULL) { u1 = u_n->v[i]; } else { u2 = u_n->v[i]; } } } l_01 -= 0.5 * subtree_dist[u1->num][u2->num]; } for (i = 0; i < 3; i++) { if (u_n->v[i] == v_n) { l_01 -= u_n->b[i]->l->v; break; } } */ l_01 = rgrft_cand[cand]->d_up_v - (0.5 * rgrft_cand[cand]->d_un_v) - (0.5 * d_uu); /* ** l_02 */ l_02 = subtree_dist[u_prune->num][v_nx1->num] - (0.5 * d_uu); if (!v_nx1->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_nx1->v[i] != v_n) { if (u1 == NULL) { u1 = v_nx1->v[i]; } else { u2 = v_nx1->v[i]; } } } l_02 -= (0.5 * subtree_dist[u1->num][u2->num]); } /* ** l_12 */ l_12 = e_regraft->l->v; /* ** Simple estimates. */ l_simple[0] = l_02 - (0.5*e_regraft->l->v); l_simple[1] = 0.5 * e_regraft->l->v; l_simple[2] = 0.5 * e_regraft->l->v; /* ** Average subtree distance based estimates. */ l_dist[0] = 0.5 * ( l_01 + l_02 - l_12); l_dist[1] = 0.5 * ( l_01 - l_02 + l_12); l_dist[2] = 0.5 * (-l_01 + l_02 + l_12); /* ** Take the average of the two estimates. */ l_est[0] = (l_simple[0] + l_dist[0]) / 2.0; l_est[1] = (l_simple[1] + l_dist[1]) / 2.0; l_est[2] = (l_simple[2] + l_dist[2]) / 2.0; /* ** Set the t_edge lengths and update the relevant transition prob's and ** partial likelihoods in the temporary regraft structure. */ for (i = 0; i < 3; i++) { v_tmp->b[i]->l->v = l_est[i]; /* TO DO */ Update_PMat_At_Given_Edge (v_tmp->b[i], tree); } /* Beg SG 18 May 2007 */ if(tree->mod->s_opt->wim_inside_opt) { Triple_Dist(v_tmp,tree,0); For(i,3) l_est[i] = v_tmp->b[i]->l->v; } /* End SG 18 May 2007 */ /* ** Calculate the change in likelihood locally. Save it and the estimated edge ** lengths in the current candidate in the list. */ Update_P_Lk (tree, v_tmp->b[0], v_tmp); new_lk = Lk(v_tmp->b[0],tree); /* PhyML_Printf("\n. new_lk = %f",new_lk); */ rgrft_cand[cand]->delta_lk = new_lk - cur_lk; rgrft_cand[cand]->rgrft_rank = cand; rgrft_cand[cand]->optim_rank = -1; rgrft_cand[cand]->globl_rank = -1; rgrft_cand[cand]->l_connect = l_connect; for (i = 0; i < 3; i++) { rgrft_cand[cand]->l_est[i] = v_tmp->b[i]->l->v; } if (rgrft_cand[cand]->delta_lk > best_d_lk) { best_d_lk = rgrft_cand[cand]->delta_lk; best_cand = cand; } /* ** If the change is within the tree->mod->s_opt->wim_n_optim best ones, save it in the list of ** optimization candidates. */ if (rgrft_cand[cand]->delta_lk > optim_cand[tree->mod->s_opt->wim_n_optim-1]->delta_lk) { i = tree->mod->s_opt->wim_n_optim-1; optim_cand[i]->v_prune = rgrft_cand[cand]->v_prune; optim_cand[i]->u_prune = rgrft_cand[cand]->u_prune; optim_cand[i]->v_n = rgrft_cand[cand]->v_n; optim_cand[i]->v_nx1 = rgrft_cand[cand]->v_nx1; optim_cand[i]->u_n = rgrft_cand[cand]->u_n; optim_cand[i]->e_prune = rgrft_cand[cand]->e_prune; optim_cand[i]->e_regraft = rgrft_cand[cand]->e_regraft; optim_cand[i]->d_L = rgrft_cand[cand]->d_L; optim_cand[i]->dist = rgrft_cand[cand]->dist; optim_cand[i]->rgrft_rank = rgrft_cand[cand]->rgrft_rank; optim_cand[i]->optim_rank = rgrft_cand[cand]->optim_rank; optim_cand[i]->globl_rank = rgrft_cand[cand]->globl_rank; optim_cand[i]->l_connect = rgrft_cand[cand]->l_connect; for (j = 0; j < 3; j++) { optim_cand[i]->l_est[j] = rgrft_cand[cand]->l_est[j]; } optim_cand[i]->delta_lk = rgrft_cand[cand]->delta_lk; /* ** Move the candidate to the appropriate position in the list, so the list ** remains sorted in decreasing delta_Lk value. */ while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk)) { tmp_cand = optim_cand[i]; optim_cand[i] = optim_cand[i-1]; optim_cand[i-1] = tmp_cand; i--; } } /* ** Reset the partial likelihoods along the path. */ for (pat = 0; pat < tree->n_pattern; pat++) { p_sum[pat] = sum_scale_tmp[pat]; for (cat = 0; cat < tree->mod->ras->n_catg; cat++) { for (ste = 0; ste < tree->mod->ns; ste++) { p_lk[pat*dim1+cat*dim2+ste] = p_lk_tmp[pat*dim1+cat*dim2+ste]; } } } n = rgrft_cand[cand]->dist; for (i = 2; i <= n; i++) { for (j = 0; j < 3; j++) { if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1]) { e_tmp = rgrft_cand[cand]->path[i]->b[j]; break; } } Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]); } /* ** If an improvement was found, forget the other candidates... */ if (best_cand >= 0) { break; } } /* ** Swap back the relevant partial likelihoods at the prune site. */ if (v_prune == v_prune->b[d1]->left) { v_prune->b[d1]->p_lk_left = p_lk1_tmp; } else { v_prune->b[d1]->p_lk_rght = p_lk1_tmp; } if (v_prune == v_prune->b[d2]->left) { v_prune->b[d2]->p_lk_left = p_lk2_tmp; } else { v_prune->b[d2]->p_lk_rght = p_lk2_tmp; } /* ** Reset the relevant t_edge lengths and transition prob's at the prune site. */ v_prune->b[d1]->l->v = v_prune->b[d1]->l_old->v; v_prune->b[d2]->l->v = v_prune->b[d2]->l_old->v; Update_PMat_At_Given_Edge (v_prune->b[d1], tree); Update_PMat_At_Given_Edge (v_prune->b[d2], tree); /* ** Return the best candidate. */ return (best_cand); } /* ** Best_Lk_Change: Estimate the changes in likelihood for the most promising candidate ** regraft positions given a pruned subtree and save the best one. ** ** Parameters: ** - e_prune: The t_edge at which the subtree was pruned. ** - v_prune: The root of the pruned subtree. ** - tree: The tree on which to do the calculations. ** ** Returns: ** The candidate which gives the best (possibly negative) improvement. */ int Best_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree) { int i, j, cand, best_cand, d0, d1, d2, n, pat, cat, ste; phydbl d_uu, best_d_lk, l_connect, l_01, l_02, l_12, l_est[3], new_lk, l_simple[3], l_dist[3]; phydbl *p_lk1_tmp, *p_lk2_tmp, *p_lk; int *p_sum; t_node *u_prune, *v_n, *v_nx1, *u1, *u2; t_edge *e_regraft, *e_tmp; _move_ *tmp_cand; int dim1, dim2; dim1 = tree->mod->ns * tree->mod->ras->n_catg; dim2 = tree->mod->ns ; /* ** Get the directions from t_node v_prune. */ d0 = -1; u_prune = NULL; for (i = 0; i < 3; i++) { if (v_prune->b[i] == e_prune) { d0 = i; u_prune = v_prune->v[i]; break; } } d1 = (d0 + 1) % 3; d2 = 3 - d0 - d1; /* ** Copy the relevant partial likelihoods to the temporary regraft structure. ** We can point to the original matrices, cos they won't be changed anyway. */ if (v_prune == e_prune->left) { v_tmp->b[0]->p_lk_rght = e_prune->p_lk_rght; v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_rght; } else { v_tmp->b[0]->p_lk_rght = e_prune->p_lk_left; v_tmp->b[0]->sum_scale_rght = e_prune->sum_scale_left; } v_tmp->num = v_prune->num; v_tmp->v[0]->num = u_prune->num; v_tmp->b[0]->num = e_prune->num; /* ** Estimate the length of the t_edge that will connect the two "detached" nodes ** after pruning. (The average of the sum of the lengths of the original two ** edges and the average subtree distance based estimate.) */ l_connect = subtree_dist[v_prune->v[d1]->num][v_prune->v[d2]->num]; if (!v_prune->v[d1]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d1]->b[i] != v_prune->b[d1]) { if (u1 == NULL) { u1 = v_prune->v[d1]->v[i]; } else { u2 = v_prune->v[d1]->v[i]; } } } l_connect -= 0.5 * subtree_dist[u1->num][u2->num]; } if (!v_prune->v[d2]->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_prune->v[d2]->b[i] != v_prune->b[d2]) { if (u1 == NULL) { u1 = v_prune->v[d2]->v[i]; } else { u2 = v_prune->v[d2]->v[i]; } } } l_connect -= 0.5 * subtree_dist[u1->num][u2->num]; } l_connect += (v_prune->b[d1]->l->v + v_prune->b[d2]->l->v); l_connect /= 2.0; /* ** Temporarily swap the relevant partial likelihoods at the prune site. ** ** Direction d1. */ if (v_prune == v_prune->b[d1]->left) { p_lk1_tmp = v_prune->b[d1]->p_lk_left; if (v_prune == v_prune->b[d2]->left) { v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_rght; } else { v_prune->b[d1]->p_lk_left = v_prune->b[d2]->p_lk_left; } } else { p_lk1_tmp = v_prune->b[d1]->p_lk_rght; if (v_prune == v_prune->b[d2]->left) { v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_rght; } else { v_prune->b[d1]->p_lk_rght = v_prune->b[d2]->p_lk_left; } } /* ** Direction d2. */ if (v_prune == v_prune->b[d2]->left) { p_lk2_tmp = v_prune->b[d2]->p_lk_left; if (v_prune == v_prune->b[d1]->left) { v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_rght; } else { v_prune->b[d2]->p_lk_left = v_prune->b[d1]->p_lk_left; } } else { p_lk2_tmp = v_prune->b[d2]->p_lk_rght; if (v_prune == v_prune->b[d1]->left) { v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_rght; } else { v_prune->b[d2]->p_lk_rght = v_prune->b[d1]->p_lk_left; } } /* ** Temporarily set the t_edge lengths and update transition prob's at the ** prune site. */ v_prune->b[d1]->l_old->v = v_prune->b[d1]->l->v; v_prune->b[d2]->l_old->v = v_prune->b[d2]->l->v; v_prune->b[d1]->l->v = l_connect; v_prune->b[d2]->l->v = l_connect; Update_PMat_At_Given_Edge (v_prune->b[d1], tree); Update_PMat_At_Given_Edge (v_prune->b[d2], tree); /* ** Get the relevant average subtree distance within the pruned subtree. */ if (!u_prune->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_prune->b[i] != e_prune) { if (u1 == NULL) { u1 = u_prune->v[i]; } else { u2 = u_prune->v[i]; } } } d_uu = subtree_dist[u1->num][u2->num]; } else { d_uu = 0.0; } /* ** Try the best candidate SPRs and estimate the change in likelihood. */ best_d_lk = -1.0*BIG; best_cand = 0; for (cand = 0; cand < tree->mod->s_opt->wim_n_best; cand++) { /* ** If there are no more candidates, bail out... */ if (FABS(rgrft_cand[cand]->d_L - 1.0*BIG) < SMALL) { break; } else { nr_d_lk++; } /* ** Get the relevant nodes and edges. */ v_n = rgrft_cand[cand]->v_n; v_nx1 = rgrft_cand[cand]->v_nx1; e_regraft = rgrft_cand[cand]->e_regraft; /* ** Update the relevant partial likelihoods along the path between the prune ** and regraft positions (temporarily save the first one). */ n = rgrft_cand[cand]->dist; e_tmp = NULL; p_lk = NULL; p_sum = NULL; for (i = 1; i <= n; i++) { /* ** Get the next t_edge along the path. */ for (j = 0; j < 3; j++) { if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1]) { e_tmp = rgrft_cand[cand]->path[i]->b[j]; break; } } if (i == 1) { /* ** Save the first partial likelihood along the path. */ if (rgrft_cand[cand]->path[i] == e_tmp->left) { p_lk = e_tmp->p_lk_left; p_sum = e_tmp->sum_scale_left; } else { p_lk = e_tmp->p_lk_rght; p_sum = e_tmp->sum_scale_rght; } for (pat = 0; pat < tree->n_pattern; pat++) { sum_scale_tmp[pat] = p_sum[pat]; for (cat = 0; cat < tree->mod->ras->n_catg; cat++) { for (ste = 0; ste < tree->mod->ns; ste++) { p_lk_tmp[pat*dim1+cat*dim2+ste] = p_lk[pat*dim1+cat*dim2+ste]; } } } } Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]); } if (v_n == e_regraft->left) { v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_left; v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_rght; v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_left; v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_rght; } else { v_tmp->b[1]->p_lk_rght = e_regraft->p_lk_rght; v_tmp->b[2]->p_lk_rght = e_regraft->p_lk_left; v_tmp->b[1]->sum_scale_rght = e_regraft->sum_scale_rght; v_tmp->b[2]->sum_scale_rght = e_regraft->sum_scale_left; } /* ** Estimate t_edge lengths of the three relevant regraft edges based on ** average subtree distances. ** ** l_01 */ /* ** Alternative method of estimating l_01. Kept it around for reference... ** l_01 = subtree_dist[u_prune->num][u_n->num] - (0.5 * d_uu); if (!u_n->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (u_n->v[i] != v_n) { if (u1 == NULL) { u1 = u_n->v[i]; } else { u2 = u_n->v[i]; } } } l_01 -= 0.5 * subtree_dist[u1->num][u2->num]; } for (i = 0; i < 3; i++) { if (u_n->v[i] == v_n) { l_01 -= u_n->b[i]->l->v; break; } } */ l_01 = rgrft_cand[cand]->d_up_v - (0.5 * rgrft_cand[cand]->d_un_v) - (0.5 * d_uu); /* ** l_02 */ l_02 = subtree_dist[u_prune->num][v_nx1->num] - (0.5 * d_uu); if (!v_nx1->tax) { u1 = u2 = NULL; for (i = 0; i < 3; i++) { if (v_nx1->v[i] != v_n) { if (u1 == NULL) { u1 = v_nx1->v[i]; } else { u2 = v_nx1->v[i]; } } } l_02 -= (0.5 * subtree_dist[u1->num][u2->num]); } /* ** l_12 */ l_12 = e_regraft->l->v; /* ** Simple estimates. */ l_simple[0] = l_02 - (0.5*e_regraft->l->v); l_simple[1] = 0.5 * e_regraft->l->v; l_simple[2] = 0.5 * e_regraft->l->v; /* ** Average subtree distance based estimates. */ l_dist[0] = 0.5 * ( l_01 + l_02 - l_12); l_dist[1] = 0.5 * ( l_01 - l_02 + l_12); l_dist[2] = 0.5 * (-l_01 + l_02 + l_12); /* ** Take the average of the two estimates. */ l_est[0] = (l_simple[0] + l_dist[0]) / 2.0; l_est[1] = (l_simple[1] + l_dist[1]) / 2.0; l_est[2] = (l_simple[2] + l_dist[2]) / 2.0; /* ** Set the t_edge lengths and update the relevant transition prob's and ** partial likelihoods in the temporary regraft structure. */ for (i = 0; i < 3; i++) { v_tmp->b[i]->l->v = l_est[i]; Update_PMat_At_Given_Edge (v_tmp->b[i], tree); } Update_P_Lk (tree, v_tmp->b[0], v_tmp); /* ** Calculate the change in likelihood locally. Save it and the estimated edge ** lengths in the current candidate in the list. */ new_lk = Lk(v_tmp->b[0],tree); rgrft_cand[cand]->delta_lk = new_lk - cur_lk; rgrft_cand[cand]->rgrft_rank = cand; rgrft_cand[cand]->optim_rank = -1; rgrft_cand[cand]->globl_rank = -1; rgrft_cand[cand]->l_connect = l_connect; for (i = 0; i < 3; i++) { rgrft_cand[cand]->l_est[i] = v_tmp->b[i]->l->v; } if (rgrft_cand[cand]->delta_lk > best_d_lk) { best_d_lk = rgrft_cand[cand]->delta_lk; best_cand = cand; } /* ** Reset the partial likelihoods along the path. */ for (pat = 0; pat < tree->n_pattern; pat++) { p_sum[pat] = sum_scale_tmp[pat]; for (cat = 0; cat < tree->mod->ras->n_catg; cat++) { for (ste = 0; ste < tree->mod->ns; ste++) { p_lk[pat*dim1+cat*dim2+ste] = p_lk_tmp[pat*dim1+cat*dim2+ste]; } } } n = rgrft_cand[cand]->dist; for (i = 2; i <= n; i++) { for (j = 0; j < 3; j++) { if (rgrft_cand[cand]->path[i]->v[j] == rgrft_cand[cand]->path[i+1]) { e_tmp = rgrft_cand[cand]->path[i]->b[j]; break; } } Update_P_Lk (tree, e_tmp, rgrft_cand[cand]->path[i]); } } /* ** If the best candidate is within the tree->mod->s_opt->wim_n_optim best ones, save it in the list of ** optimization candidates. */ if (rgrft_cand[best_cand]->delta_lk > optim_cand[tree->mod->s_opt->wim_n_optim-1]->delta_lk) { i = tree->mod->s_opt->wim_n_optim-1; optim_cand[i]->v_prune = rgrft_cand[best_cand]->v_prune; optim_cand[i]->u_prune = rgrft_cand[best_cand]->u_prune; optim_cand[i]->v_n = rgrft_cand[best_cand]->v_n; optim_cand[i]->v_nx1 = rgrft_cand[best_cand]->v_nx1; optim_cand[i]->u_n = rgrft_cand[best_cand]->u_n; optim_cand[i]->e_prune = rgrft_cand[best_cand]->e_prune; optim_cand[i]->e_regraft = rgrft_cand[best_cand]->e_regraft; optim_cand[i]->d_L = rgrft_cand[best_cand]->d_L; optim_cand[i]->dist = rgrft_cand[best_cand]->dist; optim_cand[i]->rgrft_rank = rgrft_cand[best_cand]->rgrft_rank; optim_cand[i]->optim_rank = rgrft_cand[best_cand]->optim_rank; optim_cand[i]->globl_rank = rgrft_cand[best_cand]->globl_rank; optim_cand[i]->l_connect = rgrft_cand[best_cand]->l_connect; for (j = 0; j < 3; j++) { optim_cand[i]->l_est[j] = rgrft_cand[best_cand]->l_est[j]; } optim_cand[i]->delta_lk = rgrft_cand[best_cand]->delta_lk; /* ** Move the candidate to the appropriate position in the list, so the list ** remains sorted in decreasing delta_Lk value. */ while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk)) { tmp_cand = optim_cand[i]; optim_cand[i] = optim_cand[i-1]; optim_cand[i-1] = tmp_cand; i--; } } /* ** Swap back the relevant partial likelihoods at the prune site. */ if (v_prune == v_prune->b[d1]->left) { v_prune->b[d1]->p_lk_left = p_lk1_tmp; } else { v_prune->b[d1]->p_lk_rght = p_lk1_tmp; } if (v_prune == v_prune->b[d2]->left) { v_prune->b[d2]->p_lk_left = p_lk2_tmp; } else { v_prune->b[d2]->p_lk_rght = p_lk2_tmp; } /* ** Reset the relevant t_edge lengths and transition prob's at the prune site. */ v_prune->b[d1]->l->v = v_prune->b[d1]->l_old->v; v_prune->b[d2]->l->v = v_prune->b[d2]->l_old->v; Update_PMat_At_Given_Edge (v_prune->b[d1], tree); Update_PMat_At_Given_Edge (v_prune->b[d2], tree); /* ** Return the best candidate. */ return (best_cand); } /* ** Make_Move: Perform an actual SPR move and calculate the new likelihood. ** ** Parameters: ** - candidate: The candidate move to perform. ** - tree: The tree on which to perform the move. ** */ void Make_Move (_move_ *move, int type, t_tree *tree) { int i; t_node *v_prune, *u_prune, *v_n, *root; t_edge *e_prune, *e_regraft, *e_connect, *e_avail; phydbl new_lk; /* ** Get the relevant nodes and edges. */ v_prune = move->v_prune; u_prune = move->u_prune; v_n = move->v_n; e_prune = move->e_prune; e_regraft = move->e_regraft; /* PhyML_Printf (" making move: %d -> %d (%f)\n", e_prune->num, e_regraft->num, move->delta_lk); */ /* ** Perform the move and set t_edge lengths. */ Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree); Regraft (e_regraft, v_prune, e_avail, tree); e_connect->l->v = move->l_connect; for (i = 0; i < 3; i++) { if (v_prune->v[i] == u_prune) { v_prune->b[i]->l->v = move->l_est[0]; } else if (v_prune->v[i] == v_n) { v_prune->b[i]->l->v = move->l_est[1]; } else { v_prune->b[i]->l->v = move->l_est[2]; } } if(type > 0) /* local or global move */ { Restore_Br_Len(tree); } /* ** Calculate the new likelihood. */ Set_Both_Sides(YES,tree); new_lk = Lk(NULL,tree); if(tree->c_lnL < cur_lk-tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== tree->c_lnL = %f cur_lk = %f",tree->c_lnL,cur_lk); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } cur_lk = new_lk; /* ** Recalculate the average distances between all (non-overlapping) subtrees. */ root = tree->a_nodes[0]; PostOrder_v (tree, root->v[2], root->b[2]); } /* ** Find_Optim_Local: Perform local t_edge length optimization on the candidates in the ** optimization list, and return the first one that gives an ** improvement in likelihood. ** ** Parameters: ** - tree: The tree on which to check the moves. ** ** Returns: ** If an improvement was found: The candidate that gives the improvement. ** Otherwise: -1. */ int Find_Optim_Local (t_tree *tree) { int best_cand, cand, i; t_node *v_prune, *u_prune, *v_n; t_edge *e_prune, *e_regraft, *e_connect, *e_avail; phydbl max_change, new_lk; _move_ *move, *tmp_cand; /* ** Try all candidate moves starting from the first one. */ best_cand = -1; max_change = 1.0/BIG; for(cand = 0; cand < tree->mod->s_opt->wim_n_optim; cand++) { move = optim_cand[cand]; if(move->delta_lk > -1.0*BIG) { /* ** Get the relevant nodes and edges. */ v_prune = move->v_prune; u_prune = move->u_prune; v_n = move->v_n; e_prune = move->e_prune; e_regraft = move->e_regraft; /* ** Perform the move and set t_edge lengths. */ Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree); Regraft (e_regraft, v_prune, e_avail, tree); e_connect->l_old->v = e_connect->l->v; e_connect->l->v = move->l_connect; for (i = 0; i < 3; i++) { v_prune->b[i]->l_old->v = v_prune->b[i]->l->v; if (v_prune->v[i] == u_prune) { v_prune->b[i]->l->v = move->l_est[0]; } else if (v_prune->v[i] == v_n) { v_prune->b[i]->l->v = move->l_est[1]; } else { v_prune->b[i]->l->v = move->l_est[2]; } } Set_Both_Sides(YES,tree); Lk(NULL,tree); // Not sure anymore whether this is required... /* ** Use Brent optimization on the relevant edges at the regraft position ** and calculate the new likelihood value. */ Br_Len_Brent (0.05,20.,v_prune->b[0], tree); Br_Len_Brent (0.05,20.,v_prune->b[1], tree); Br_Len_Brent (0.05,20.,v_prune->b[2], tree); /* Update_PMat_At_Given_Edge (v_prune->b[0], tree); */ /* Update_PMat_At_Given_Edge (v_prune->b[1], tree); */ /* Update_PMat_At_Given_Edge (v_prune->b[2], tree); */ Update_P_Lk (tree, v_prune->b[0], v_prune); new_lk = Lk(v_prune->b[0],tree); /* PhyML_Printf("\n. local new_lk = %f",new_lk); */ /* ** Save the change in likelihood and move the current candidate to the ** appropriate place in the list. */ move->delta_lk = new_lk - cur_lk; move->optim_rank = cand; i = cand; while ((i > 0) && (optim_cand[i]->delta_lk > optim_cand[i-1]->delta_lk)) { tmp_cand = optim_cand[i]; optim_cand[i] = optim_cand[i-1]; optim_cand[i-1] = tmp_cand; i--; } if (move->delta_lk > max_change) { best_cand = i; max_change = move->delta_lk; Record_Br_Len(tree); } /* ** Undo the move again. */ Prune (e_prune, v_prune, &(e_regraft), &(e_avail), tree); Regraft (e_connect, v_prune, e_avail, tree); e_regraft->l->v = e_regraft->l_old->v; for (i = 0; i < 3; i++) { v_prune->b[i]->l->v = v_prune->b[i]->l_old->v; } Set_Both_Sides(YES,tree); Lk(NULL,tree); nr_loc++; /* PhyML_Printf("\n. local back to = %f",tree->c_lnL); */ } else { break; } /* ** If an improvement was found, forget the other candidates... */ if (best_cand >= 0) { break; } } /* ** Return the best candidate. */ return (best_cand); } /* ** Find_Optim_Globl: Perform global t_edge length optimization on the candidates in the ** optimization list, and return the first one that gives an ** improvement in likelihood. ** ** Parameters: ** - tree: The tree on which to check the moves. ** ** Returns: ** If an improvement is found: The candidate that gives the improvement. ** Otherwise: -1. */ int Find_Optim_Globl (t_tree *tree) { int best_cand, cand, i; t_node *v_prune, *u_prune, *v_n; t_edge *e_prune, *e_regraft, *e_connect, *e_avail; phydbl max_change, new_lk; _move_ *move; /* ** Try all moves. */ best_cand = -1; max_change = 1.0/BIG; for (cand = 0; cand < tree->mod->s_opt->wim_n_globl; cand++) { move = optim_cand[cand]; if (move->delta_lk > -1.0*BIG) { Record_Br_Len(tree); /* ** Get the relevant nodes and edges. */ v_prune = move->v_prune; u_prune = move->u_prune; v_n = move->v_n; e_prune = move->e_prune; e_regraft = move->e_regraft; /* ** Perform the move and optimize all t_edge lengths. */ Prune (e_prune, v_prune, &(e_connect), &(e_avail), tree); Regraft (e_regraft, v_prune, e_avail, tree); e_connect->l_old->v = e_connect->l->v; e_connect->l->v = move->l_connect; for (i = 0; i < 3; i++) { v_prune->b[i]->l_old->v = v_prune->b[i]->l->v; if (v_prune->v[i] == u_prune) { v_prune->b[i]->l->v = move->l_est[0]; } else if (v_prune->v[i] == v_n) { v_prune->b[i]->l->v = move->l_est[1]; } else { v_prune->b[i]->l->v = move->l_est[2]; } } Set_Both_Sides(YES,tree); Lk(NULL,tree); Optimize_Br_Len_Serie (tree); Set_Both_Sides(YES,tree); new_lk = Lk (NULL,tree); /* PhyML_Printf("\n. global new_lk = %f\n",tree->c_lnL); */ /* ** Save the change in likelihood and undo the move. */ move->delta_lk = new_lk - cur_lk; move->globl_rank = cand; if (move->delta_lk > max_change) { best_cand = cand; max_change = move->delta_lk; Record_Br_Len(tree); } Prune (e_prune, v_prune, &(e_regraft), &(e_avail), tree); Regraft (e_connect, v_prune, e_avail, tree); e_regraft->l->v = e_regraft->l_old->v; for (i = 0; i < 3; i++) { v_prune->b[i]->l->v = v_prune->b[i]->l_old->v; } Set_Both_Sides(YES,tree); Restore_Br_Len(tree); Lk(NULL,tree); nr_glb++; /* PhyML_Printf("\n. global back to = %f",tree->c_lnL); */ } else break; /* ** If an improvement was found, forget the other candidates... */ if (best_cand >= 0) break; } /* ** Return the best candidate. */ return (best_cand); } /* ** Prune: Prune the subtree at a certain t_edge and node. Note that edge ** lengths are not set and partial likelihoods are not updated. ** ** Parameters: ** - e: The t_edge at which to prune the subtree. ** - v: The t_node adjacent to t_edge e which forms the root of the subtree. ** - e_connect: An t_edge pointer which will point to the t_edge that was left ** after pruning. ** - e_avail: The t_edge that is "left over" and should be used in the ** regrafting step. ** - tree: The tree on which the pruning is done. ** ** ** ** \ / ** o ** | ** | e --> subtree to be pruned ** | ** o v ** / \ ** e1/ \e2 ** / \ ** o o ** u1 u2 --> such that u1->num < u2->num */ void Prune (t_edge *e, t_node *v, t_edge **e_connect, t_edge **e_avail, t_tree *tree) { int dir0, dir1, dir2, v0, v1, v2, tmp_dir, i, j, k; t_node *u1, *u2, *tmp_node; t_edge *e1, *e2; int *sum_scale_f; phydbl *p_lk; int dim1, dim2; dim1 = tree->mod->ns * tree->mod->ras->n_catg; dim2 = tree->mod->ns; /* ** Get the relevant directions, nodes and edges. ** Make sure that t_node u1 is the t_node with the smaller number. */ dir0 = -1; for (i = 0; i < 3; i++) { if (v->b[i] == e) { dir0 = i; break; } } dir1 = (dir0 + 1) % 3; dir2 = 3 - dir0 - dir1; u1 = v->v[dir1]; u2 = v->v[dir2]; if (u1->num > u2->num) { tmp_node = u1; u1 = u2; u2 = tmp_node; tmp_dir = dir1; dir1 = dir2; dir2 = tmp_dir; } e1 = v->b[dir1]; e2 = v->b[dir2]; /* ** Detach t_node v from the tree. */ v->v[dir1] = NULL; v->v[dir2] = NULL; v->b[dir1] = NULL; v->b[dir2] = NULL; /* ** Connect nodes u1 and u2 via t_edge e1 and copy relevant partial likelihoods. */ if (u2 == e2->left) { v0 = e2->l_r; v1 = e2->l_v1; v2 = e2->l_v2; sum_scale_f = e2->sum_scale_left; p_lk = e2->p_lk_left; } else { v0 = e2->r_l; v1 = e2->r_v1; v2 = e2->r_v2; sum_scale_f = e2->sum_scale_rght; p_lk = e2->p_lk_rght; } if (u1 == e1->left) { e1->rght = u2; e1->r_l = v0; e1->r_v1 = v1; e1->r_v2 = v2; for (i = 0; i < tree->n_pattern; i++) { e1->sum_scale_rght[i] = sum_scale_f[i]; for (j = 0; j < tree->mod->ras->n_catg; j++) { for (k = 0; k < tree->mod->ns; k++) { e1->p_lk_rght[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k]; } } } } else { e1->left = u2; e1->l_r = v0; e1->l_v1 = v1; e1->l_v2 = v2; for (i = 0; i < tree->n_pattern; i++) { e1->sum_scale_left[i] = sum_scale_f[i]; for (j = 0; j < tree->mod->ras->n_catg; j++) { for (k = 0; k < tree->mod->ns; k++) { e1->p_lk_left[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k]; } } } } for (i = 0; i < 3; i++) { if (u1->v[i] == v) { u1->v[i] = u2; } if (u2->v[i] == v) { u2->v[i] = u1; u2->b[i] = e1; u2->l[i] = e1->l->v; } } /* ** Make sure that a possible tip t_node is still on the right side. */ if (e1->left->tax) { /* ** Swap left and right. */ tmp_node = e1->left; e1->left = e1->rght; e1->rght = tmp_node; tmp_dir = e1->l_r; e1->l_r = e1->r_l; e1->r_l = tmp_dir; tmp_dir = e1->l_v1; e1->l_v1 = e1->r_v1; e1->r_v1 = tmp_dir; tmp_dir = e1->l_v2; e1->l_v2 = e1->r_v2; e1->r_v2 = tmp_dir; p_lk = e1->p_lk_left; e1->p_lk_left = e1->p_lk_rght; e1->p_lk_rght = p_lk; sum_scale_f = e1->sum_scale_left; e1->sum_scale_left = e1->sum_scale_rght; e1->sum_scale_rght = sum_scale_f; } /* ** Set the connecting and available edges. */ *(e_connect) = e1; *(e_avail) = e2; } /* ** Regraft: Regraft a subtree at a certain edge. Note that t_edge lengths ** are not set and partial likelihoods are not updated. ** ** Parameters: ** - e: The t_edge to regraft the subtree on. ** - v: The root of the subtree to regraft. ** - avail: A previously deleted t_edge now available for insertion again. ** - tree: The tree on which the regrafting is done. ** ** ** \ / ** o ** | ** | --> subtree to regraft ** | ** o v ** ** o--------o ** u1 e u2 --> such that u1->num < u2->num */ void Regraft (t_edge *e, t_node *v, t_edge *avail, t_tree *tree) { int dir0, dir1, dir2, i, j, k; int *sum_scale_f; phydbl *p_lk; t_node *u1, *u2; int dim1, dim2; dim1 = tree->mod->ns * tree->mod->ras->n_catg; dim2 = tree->mod->ns ; /* ** Get the relevant directions and nodes. */ dir0 = -1; for (i = 0; i < 3; i++) { if (v->b[i] != NULL) { dir0 = i; break; } } dir1 = (dir0 + 1) % 3; dir2 = 3 - dir0 - dir1; if (e->left->num < e->rght->num) { u1 = e->left; u2 = e->rght; sum_scale_f = e->sum_scale_rght; p_lk = e->p_lk_rght; } else { u1 = e->rght; u2 = e->left; sum_scale_f = e->sum_scale_left; p_lk = e->p_lk_left; } /* ** Connect nodes v and u2 via the available t_edge 'avail' and copy the ** relevant partial likelihood. ** (We want to do this first, cos we need some of the values of edge ** e before changing them below). */ avail->left = v; avail->rght = u2; avail->l_r = dir2; avail->l_v1 = dir0; avail->l_v2 = dir1; v->v[dir2] = u2; v->b[dir2] = avail; for (i = 0; i < 3; i++) { if (e == u2->b[i]) { u2->v[i] = v; u2->b[i] = avail; avail->r_l = i; avail->r_v1 = (i + 1) % 3; avail->r_v2 = 3 - i - avail->r_v1; break; } } for (i = 0; i < tree->n_pattern; i++) { avail->sum_scale_rght[i] = sum_scale_f[i]; for (j = 0; j < tree->mod->ras->n_catg; j++) { for (k = 0; k < tree->mod->ns; k++) { avail->p_lk_rght[i*dim1+j*dim2+k] = p_lk[i*dim1+j*dim2+k]; } } } /* ** Connect nodes v and u1 via t_edge e. */ if (u1 == e->left) { e->rght = v; e->r_l = dir1; e->r_v1 = dir0; e->r_v2 = dir2; } else { e->left = v; e->l_r = dir1; e->l_v1 = dir0; e->l_v2 = dir2; } v->v[dir1] = u1; v->b[dir1] = e; for (i = 0; i < 3; i++) { if (u1->v[i] == u2) { u1->v[i] = v; break; } } } /* ** PostOrder_v: Recursively visit all nodes v in postorder to calculate ** the average distance between subtrees. ** ** Parameters: ** - tree: The tree for which to calculate the average distances. ** - v: The current node. ** - e: The t_edge we came from. */ void PostOrder_v (t_tree *tree, t_node *v, t_edge *e) { int i; t_node *w; /* ** If v is not a taxon, recurse. */ if (!v->tax) { for (i = 0; i < 3; i++) { if (v->b[i] != e) { PostOrder_v (tree, v->v[i], v->b[i]); } } } /* ** Recurse over all nodes w not in the current subtree and calculate ** the average distance between the current subtree and all others. */ if (v == e->left) { w = e->rght; } else { w = e->left; } PostOrder_w (tree, v, e, w, e); } /* ** PostOrder_w: Recursively visit all nodes w not in the subtree of v in ** postorder and calculate the average distance between the ** subtree of v and all others. ** ** Parameters: ** - tree: The tree for which to calculate the average distances. ** - v: The root t_node of the first subtree. ** - v_e: The t_edge adjacent to the first subtree. ** - w: The current node. ** - e: The t_edge we came from. */ void PostOrder_w (t_tree *tree, t_node *v, t_edge *v_e, t_node *w, t_edge *e) { int i; t_node *w1, *w2, *v1, *v2; /* ** If w is not a taxon, recurse. */ if (!w->tax) { for (i = 0; i < 3; i++) { if (w->b[i] != e) { PostOrder_w (tree, v, v_e, w->v[i], w->b[i]); } } } /* ** Calculate the average distance between the subtrees defined by ** nodes v and w. */ if (v->tax && w->tax) { subtree_dist[v->num][w->num] = seq_dist->dist[v->num][w->num]; } else if (!v->tax) { v1 = v2 = NULL; for (i = 0; i < 3; i++) { if (v->b[i] != v_e) { if (v1 == NULL) { v1 = v->v[i]; } else { v2 = v->v[i]; } } } subtree_dist[v->num][w->num] = 0.5*(subtree_dist[v1->num][w->num] + subtree_dist[v2->num][w->num]); } else { w1 = w2 = NULL; for (i = 0; i < 3; i++) { if (w->b[i] != e) { if (w1 == NULL) { w1 = w->v[i]; } else { w2 = w->v[i]; } } } subtree_dist[v->num][w->num] = 0.5*(subtree_dist[v->num][w1->num] + subtree_dist[v->num][w2->num]); } subtree_dist[w->num][v->num] = subtree_dist[v->num][w->num]; } /*********************************************************/ /*********************************************************/ /* Sort list of SPR move by putting the deepest moves first */ void Sort_Spr_List_Depth(t_tree *tree) { int i,j; t_spr *buff; For(i,tree->size_spr_list-1) { for(j=i+1;jsize_spr_list;j++) { if(tree->spr_list[j]->depth_path > tree->spr_list[i]->depth_path) { buff = tree->spr_list[i]; tree->spr_list[i] = tree->spr_list[j]; tree->spr_list[j] = buff; } } } } /*********************************************************/ /*********************************************************/ /* Sort list of SPR move by putting the more likely moves first */ void Sort_Spr_List_LnL(t_tree *tree) { int i,j; t_spr *buff; For(i,tree->size_spr_list-1) { for(j=i+1;jsize_spr_list;j++) { if(tree->spr_list[j]->lnL > tree->spr_list[i]->lnL) { buff = tree->spr_list[i]; tree->spr_list[i] = tree->spr_list[j]; tree->spr_list[j] = buff; } } } } /*********************************************************/ /*********************************************************/ /*********************************************************/ /* Below are my functions for SPR search (Stephane Guindon, 2007) */ void Randomize_Spr_List(t_tree *tree) { int i,j; t_spr *buff; For(i,tree->size_spr_list) { j = (int)FLOOR(rand()/(RAND_MAX+1.)*tree->size_spr_list); buff = tree->spr_list[i]; tree->spr_list[i] = tree->spr_list[j]; tree->spr_list[j] = buff; } } /*********************************************************/ int Spr(phydbl init_lnL, t_tree *tree) { int br; int pars_diff, max_pars_diff, new_pars, old_pars; t_edge *b; Set_Both_Sides(YES,tree); pars_diff = -1; max_pars_diff = -1; new_pars = -1; old_pars = -1; Reset_Spr_List(tree); For(br,2*tree->n_otu-3) { b = tree->a_edges[br]; old_pars = tree->c_pars; Spr_Subtree(b,b->left,tree); new_pars = tree->c_pars; pars_diff = new_pars - old_pars; if(pars_diff > max_pars_diff) max_pars_diff = pars_diff; old_pars = tree->c_pars; Spr_Subtree(b,b->rght,tree); new_pars = tree->c_pars; pars_diff = new_pars - old_pars; if(pars_diff > max_pars_diff) max_pars_diff = pars_diff; } /* tree->mod->s_opt->pars_thresh = MAX(5,max_pars_diff); */ return 1; } /*********************************************************/ void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree) { int i; int n_moves_pars, n_moves, curr_pars, min_pars, best_move; t_spr *best_pars_move; t_edge *target, *residual; best_move = -1; tree->n_moves = 0; curr_pars = tree->c_pars; MIXT_Set_Pars_Thresh(tree); if((link != b->left) && (link != b->rght)) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } else { /* printf("\n. -1"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */ if(!link->tax) Test_All_Spr_Targets(b,link,tree); /* printf("\n. 0"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */ if(tree->n_moves) { n_moves_pars = 0; n_moves = 0; For(i,tree->n_moves) if(curr_pars - tree->spr_list[i]->pars >= -tree->mod->s_opt->pars_thresh) n_moves_pars++; For(i,tree->n_moves) { n_moves++; /* if(n_moves > 15) break; */ if(n_moves > 5) break; if(tree->spr_list[i]->lnL < tree->best_lnL - 2. * tree->mod->s_opt->max_delta_lnL_spr) break; } if(!tree->mod->s_opt->spr_lnL) n_moves = n_moves_pars; if(!tree->io->fp_in_constraint_tree) n_moves = MAX(1,n_moves); n_moves = MIN(n_moves,2*tree->n_otu-3); if(tree->mod->s_opt->spr_pars) { if(tree->io->fp_in_constraint_tree) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } min_pars = 1E+8; best_pars_move = NULL; For(i,n_moves) if(tree->spr_list[i]->pars < min_pars) { best_pars_move = tree->spr_list[i]; min_pars = tree->spr_list[i]->pars; } if(best_pars_move->pars < tree->best_pars) { Prune_Subtree(best_pars_move->n_link,best_pars_move->n_opp_to_link,&target,&residual,tree); Graft_Subtree(best_pars_move->b_target,best_pars_move->n_link,residual,tree); Set_Both_Sides(YES,tree); Pars(NULL,tree); tree->best_pars = tree->c_pars; if(tree->best_pars != best_pars_move->pars) { PhyML_Printf("\n== best_pars = %d move_pars = %d",tree->best_pars,best_pars_move->pars); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } tree->n_improvements++; } else Pars(NULL,tree); } else { int apply_move = NO; phydbl accept_prob,u; /* tree->both_sides = YES; */ /* Lk(NULL,tree); */ /* tree->both_sides = NO; */ /* printf("\n. 1"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(YES,tree)) Exit("\n"); */ /* Sort_Spr_List_Depth(tree); */ Sort_Spr_List_LnL(tree); best_move = Evaluate_List_Of_Regraft_Pos_Triple(tree->spr_list,n_moves,tree); /* printf("\n. 2"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(YES,tree)) Exit("\n"); */ if(best_move > -1) { accept_prob = exp((tree->spr_list[best_move]->lnL - tree->best_lnL)/tree->annealing_temp); u = Uni(); if(!(u > accept_prob)) apply_move = YES; } /* if((best_move > -1) && (tree->spr_list[best_move]->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move)) */ if((best_move > -1) && (apply_move == YES)) { Try_One_Spr_Move_Triple(tree->spr_list[best_move],tree); } else { Pars(NULL,tree); /* tree->both_sides = YES; */ /* Lk(tree); */ /* tree->both_sides = NO; */ } /* printf("\n. 3"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(tree)) Exit("\n"); */ } } Reset_Spr_List(tree); } } /*********************************************************/ int Test_All_Spr_Targets(t_edge *b_pulled, t_node *n_link, t_tree *tree) { t_node *n_opp_to_link,*n_v1,*n_v2; t_edge *b_target,*b_residual; int i,dir1,dir2; phydbl *init_len_v1, *init_len_v2, *init_len_pulled; int best_found; phydbl init_lnL; if(tree->mixt_tree != NULL) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } init_lnL = tree->c_lnL; b_target = b_residual = NULL; n_opp_to_link = (n_link == b_pulled->rght)?(b_pulled->left):(b_pulled->rght); init_len_pulled = MIXT_Get_Lengths_Of_This_Edge(b_pulled,tree); dir1 = dir2 = -1; For(i,3) if(n_link->v[i] != n_opp_to_link) { if(dir1<0) dir1 = i; else dir2 = i; } if(n_link->v[dir1]->num < n_link->v[dir2]->num) { n_v1 = n_link->v[dir1]; n_v2 = n_link->v[dir2]; init_len_v1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir1],tree); init_len_v2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir2],tree); } else { n_v1 = n_link->v[dir2]; n_v2 = n_link->v[dir1]; init_len_v1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir2],tree); init_len_v2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir1],tree); } if(!(n_v1->tax && n_v2->tax)) /*! Pruning is meaningless otherwise */ { Prune_Subtree(n_link,n_opp_to_link,&b_target,&b_residual,tree); if(tree->mod->s_opt->spr_lnL) { Fast_Br_Len(b_target,tree,NO); /* Update_PMat_At_Given_Edge(b_target,tree); */ } best_found = 0; tree->depth_curr_path = 0; tree->curr_path[0] = b_target->left; Test_One_Spr_Target_Recur(b_target->rght, b_target->left, b_pulled,n_link,b_residual,&best_found,tree); tree->depth_curr_path = 0; tree->curr_path[0] = b_target->rght; Test_One_Spr_Target_Recur(b_target->left, b_target->rght, b_pulled,n_link,b_residual,&best_found,tree); Graft_Subtree(b_target,n_link,b_residual,tree); if((n_link->v[dir1] != n_v1) || (n_link->v[dir2] != n_v2)) PhyML_Printf("\n. Warning: -- SWITCH NEEDED -- ! \n"); /* n_link->b[dir1]->l->v = init_len_v1; */ /* n_link->b[dir2]->l->v = init_len_v2; */ /* b_pulled->l->v = init_len_pulled; */ MIXT_Set_Lengths_Of_This_Edge(init_len_v1,n_link->b[dir1],tree); MIXT_Set_Lengths_Of_This_Edge(init_len_v2,n_link->b[dir2],tree); MIXT_Set_Lengths_Of_This_Edge(init_len_pulled,b_pulled,tree); Update_PMat_At_Given_Edge(n_link->b[dir1],tree); Update_PMat_At_Given_Edge(n_link->b[dir2],tree); Update_PMat_At_Given_Edge(b_pulled,tree); /* if(tree->mod->s_opt->spr_lnL) */ /* { */ /* I don't understand why this is required when spr_lnL = NO, but it is... */ MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,b_pulled, n_link); Update_P_Lk(tree,b_target, n_link); Update_P_Lk(tree,b_residual,n_link); MIXT_Set_Alias_Subpatt(NO,tree); /* } */ /* else */ /* { */ Update_P_Pars(tree,b_pulled, n_link); Update_P_Pars(tree,b_target, n_link); Update_P_Pars(tree,b_residual,n_link); /* } */ For(i,3) if(n_link->v[i] != n_opp_to_link) { if(tree->mod->s_opt->spr_lnL) { MIXT_Set_Alias_Subpatt(YES,tree); Pre_Order_Lk(n_link,n_link->v[i],tree); MIXT_Set_Alias_Subpatt(NO,tree); } else Pre_Order_Pars(n_link,n_link->v[i],tree); } /* printf("\n. 000000"); fflush(NULL); */ /* if(!Check_Lk_At_Given_Edge(NO,tree)) Exit("\n"); */ } tree->c_lnL = init_lnL; Free(init_len_v1); Free(init_len_v2); Free(init_len_pulled); return 0; } /*********************************************************/ void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, int *best_found, t_tree *tree) { int i; if(*best_found) return; if(d->tax) return; else { phydbl move_lnL; For(i,3) { if(d->v[i] != a) { if(tree->mod->s_opt->spr_lnL) { MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk(tree,d->b[i],d); MIXT_Set_Alias_Subpatt(NO,tree); } else Update_P_Pars(tree,d->b[i],d); tree->depth_curr_path++; tree->curr_path[tree->depth_curr_path] = d->v[i]; if((tree->depth_curr_path <= tree->mod->s_opt->max_depth_path) && (tree->depth_curr_path >= tree->mod->s_opt->min_depth_path)) { move_lnL = Test_One_Spr_Target(d->b[i],pulled,link,residual,tree); if(move_lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) { *best_found = 1; } } if(tree->depth_curr_path < tree->mod->s_opt->max_depth_path) Test_One_Spr_Target_Recur(d,d->v[i],pulled,link,residual,best_found,tree); tree->depth_curr_path--; } } } } /*********************************************************/ phydbl Test_One_Spr_Target(t_edge *b_target, t_edge *b_arrow, t_node *n_link, t_edge *b_residual, t_tree *tree) { phydbl *init_target_len, *init_arrow_len, *init_residual_len; int i,dir_v0,dir_v1,dir_v2; phydbl *l0,*l1,*l2; t_node *v1, *v2; phydbl init_lnL, move_lnL; int init_pars; t_tree *orig_tree; t_edge *orig_target, *orig_arrow; t_node *orig_link; t_spr *orig_move,*move; if(tree->mixt_tree != NULL) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } tree->n_moves++; move_lnL = UNLIKELY; init_lnL = tree->c_lnL; init_pars = tree->c_pars; Graft_Subtree(b_target,n_link,b_residual,tree); /* init_target_len = b_target->l->v; */ /* init_arrow_len = b_arrow->l->v; */ /* init_residual_len = b_residual->l->v; */ init_target_len = MIXT_Get_Lengths_Of_This_Edge(b_target,tree); init_arrow_len = MIXT_Get_Lengths_Of_This_Edge(b_arrow,tree); init_residual_len = MIXT_Get_Lengths_Of_This_Edge(b_residual,tree); if(tree->mod->s_opt->spr_lnL) { MIXT_Set_Alias_Subpatt(YES,tree); /* move_lnL = Triple_Dist(n_link,tree,1); */ Update_PMat_At_Given_Edge(b_target,tree); Update_PMat_At_Given_Edge(b_arrow,tree); Update_P_Lk(tree,b_residual,n_link); move_lnL = Lk(b_residual,tree); MIXT_Set_Alias_Subpatt(NO,tree); } else { Update_P_Pars(tree,b_residual,n_link); Pars(b_residual,tree); } v1 = (b_residual->left == n_link)?(b_residual->rght):(b_residual->left); v2 = (b_target->left == n_link)?(b_target->rght):(b_target->left); dir_v1 = dir_v2 = dir_v0 = -1; For(i,3) { if(n_link->v[i] == v1) dir_v1 = i; else if(n_link->v[i] == v2) dir_v2 = i; else dir_v0 = i; } l0 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v0],tree); if(n_link->v[dir_v1]->num > n_link->v[dir_v2]->num) { l1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v2],tree); l2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v1],tree); } else { l1 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v1],tree); l2 = MIXT_Get_Lengths_Of_This_Edge(n_link->b[dir_v2],tree); } move = tree->spr_list[tree->size_spr_list]; For(i,tree->depth_curr_path+1) move->path[i] = tree->curr_path[i]; move->depth_path = tree->depth_curr_path; move->pars = tree->c_pars; move->lnL = tree->c_lnL; orig_target = b_target; orig_link = n_link; orig_arrow = b_arrow; orig_tree = tree; orig_move = move; i = 0; do { move->l0 = l0[i]; move->l1 = l1[i]; move->l2 = l2[i]; if(tree->mod->gamma_mgf_bl == YES) { move->v0 = l0[i+1]; move->v1 = l1[i+1]; move->v2 = l2[i+1]; } move->b_target = b_target; move->n_link = n_link; move->b_opp_to_link = b_arrow; move->dist = b_target->topo_dist_btw_edges; move->n_opp_to_link = (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left); if(tree->next) { tree = tree->next; b_target = b_target->next; b_arrow = b_arrow->next; n_link = n_link->next; move = move->next; } else { tree = tree->next; b_target = b_target->next; b_arrow = b_arrow->next; n_link = n_link->next; move = move->next; } i+=2; } while(tree); b_target = orig_target; n_link = orig_link; b_arrow = orig_arrow; tree = orig_tree; move = orig_move; Include_One_Spr_To_List_Of_Spr(move,tree); /* b_target->l->v = init_target_len; */ /* b_arrow->l->v = init_arrow_len; */ /* b_residual->l->v = init_residual_len; */ MIXT_Set_Lengths_Of_This_Edge(init_target_len,b_target,tree); MIXT_Set_Lengths_Of_This_Edge(init_arrow_len,b_arrow,tree); MIXT_Set_Lengths_Of_This_Edge(init_residual_len,b_residual,tree); Prune_Subtree(n_link, (n_link==b_arrow->left)?(b_arrow->rght):(b_arrow->left), &b_target, &b_residual, tree); if(tree->mod->s_opt->spr_lnL) Update_PMat_At_Given_Edge(b_target,tree); tree->c_lnL = init_lnL; tree->c_pars = init_pars; Free(l0); Free(l1); Free(l2); Free(init_target_len); Free(init_arrow_len); Free(init_residual_len); return move_lnL; } /*********************************************************/ void Speed_Spr_Loop(t_tree *tree) { phydbl lk_old; tree->best_pars = 1E+8; tree->mod->s_opt->spr_lnL = 0; tree->mod->s_opt->spr_pars = 0; tree->mod->s_opt->quickdirty = 0; if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n\n. Maximizing likelihood (using SPR moves)...\n"); SPR_Shuffle(tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); tree->best_lnL = tree->c_lnL; /*****************************/ lk_old = UNLIKELY; tree->mod->s_opt->max_depth_path = tree->n_otu; tree->mod->s_opt->max_delta_lnL_spr = (tree->io->datatype == NT)?(5.):(0.); tree->mod->s_opt->spr_lnL = NO; do { lk_old = tree->c_lnL; Speed_Spr(tree,1); if(tree->n_improvements) Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print)); if(!tree->n_improvements || FABS(lk_old-tree->c_lnL) < 1.) break; } while(1); /*****************************/ /*****************************/ lk_old = UNLIKELY; do { lk_old = tree->c_lnL; if(!Simu(tree,10)) break; Optimiz_All_Free_Param(tree,(tree->io->quiet)?(0):(tree->mod->s_opt->print)); } while(FABS(lk_old - tree->c_lnL) > tree->mod->s_opt->min_diff_lk_local); /*****************************/ /*****************************/ do { Round_Optimize(tree,tree->data,ROUND_MAX); if(!Check_NNI_Five_Branches(tree)) break; } while(1); /*****************************/ /* if((tree->mod->s_opt->print) && (!tree->io->quiet)) PhyML_Printf("\n"); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Speed_Spr(t_tree *tree, int max_cycles) { int step,old_pars; phydbl old_lnL; if(tree->lock_topo == YES) { PhyML_Printf("\n== The tree topology is locked."); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } Set_Both_Sides(YES,tree); Pars(NULL,tree); Lk(NULL,tree); Record_Br_Len(tree); tree->mod->s_opt->deepest_path = 0; tree->best_pars = tree->c_pars; tree->best_lnL = tree->c_lnL; old_lnL = tree->c_lnL; old_pars = tree->c_pars; step = 0; do { ++step; old_lnL = tree->c_lnL; old_pars = tree->c_pars; tree->max_spr_depth = 0; tree->n_improvements = 0; tree->perform_spr_right_away = 1; Spr(UNLIKELY,tree); if(!tree->mod->s_opt->spr_pars) { /* Optimise branch lengths */ Optimize_Br_Len_Serie(tree); /* Update partial likelihoods */ Set_Both_Sides(YES,tree); Lk(NULL,tree); /* Print log-likelihood and parsimony scores */ if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Branch lengths ]"); } else { if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Pars(tree); } Pars(NULL,tree); if(tree->io->print_trace) { char *s = Write_Tree(tree,NO); PhyML_Fprintf(tree->io->fp_out_trace,"[%f]%s\n",tree->c_lnL,s); fflush(tree->io->fp_out_trace); if((tree->io->print_site_lnl) && (!tree->mod->s_opt->spr_pars)) Print_Site_Lk(tree,tree->io->fp_out_lk); fflush(tree->io->fp_out_lk); Free(s); } /* Record the current best log-likelihood and parsimony */ tree->best_lnL = tree->c_lnL; tree->best_pars = tree->c_pars; if(!tree->mod->s_opt->spr_pars) { if(tree->c_lnL < old_lnL-tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== old_lnL = %f c_lnL = %f",old_lnL,tree->c_lnL); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } } else { if(tree->c_pars > old_pars) { PhyML_Printf("\n== old_pars = %d c_pars = %d",old_pars,tree->c_pars); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } } /* Record the current best branch lengths */ Record_Br_Len(tree); /* Exit if no improvements after complete optimization */ if(step+1 > max_cycles) break; if((!tree->mod->s_opt->spr_pars) && (FABS(old_lnL-tree->c_lnL) < tree->mod->s_opt->min_diff_lk_global)) break; /* if(( tree->mod->s_opt->spr_pars) && (FABS(old_pars-tree->c_pars) < 1.)) break; */ if(!tree->n_improvements) break; }while(1); } /*********************************************************/ int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree *tree) { t_spr *move,*orig_move; t_edge *init_target, *b_residual; int i,j,best_move,n; int dir_v0, dir_v1, dir_v2; phydbl *recorded_l; phydbl best_lnL,init_lnL; int recorded; t_tree *orig_tree; if(tree->mixt_tree != NULL) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } best_lnL = UNLIKELY; init_target = b_residual = NULL; best_move = -1; init_lnL = tree->c_lnL; recorded_l = NULL; if(!list_size && !tree->io->fp_in_constraint_tree) { PhyML_Printf("\n== List size is 0 !"); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } recorded = NO; For(i,list_size) { move = spr_list[i]; if(!move) { PhyML_Printf("\n== move is NULL\n"); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } if(move->b_target) { /* Record t_edge lengths */ Record_Br_Len(tree); /* Prune subtree */ Prune_Subtree(move->n_link,move->n_opp_to_link,&init_target,&b_residual,tree); if(recorded == NO) { /*! Rough optimisation of the branch length at prune site * We only need to perform this optimisation for the first * element of spr_list because the pruned subtree is the * same across all the elements of spr_list. It would not * be true in the general case */ recorded = YES; Fast_Br_Len(init_target,tree,NO); /*! Record branch length at prune site */ recorded_l = MIXT_Get_Lengths_Of_This_Edge(init_target,tree); /*! Make sure recorded_l has been updated beforehand */ orig_move = move; orig_tree = tree; n = 0; do { move->init_target_l = recorded_l[n]; move->init_target_v = recorded_l[n+1]; n+=2; if(tree->next) { move = move->next; tree = tree->next; } else { move = move->next; tree = tree->next; } } while(tree); move = orig_move; tree = orig_tree; } else { MIXT_Set_Lengths_Of_This_Edge(recorded_l,init_target,tree); orig_move = move; orig_tree = tree; n = 0; do { move->init_target_l = recorded_l[n]; move->init_target_v = recorded_l[n+1]; n+=2; if(tree->next) { move = move->next; tree = tree->next; } else { move = move->next; tree = tree->next; } } while(tree); move = orig_move; tree = orig_tree; } /* Update the change proba matrix at prune position */ Update_PMat_At_Given_Edge(init_target,tree); /* Update conditional likelihoods along the path from the prune to the regraft position */ MIXT_Set_Alias_Subpatt(YES,tree); Update_P_Lk_Along_A_Path(move->path,move->depth_path+1,tree); MIXT_Set_Alias_Subpatt(NO,tree); /* Regraft subtree */ Graft_Subtree(move->b_target,move->n_link,b_residual,tree); dir_v1 = dir_v2 = dir_v0 = -1; For(j,3) { if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j; else if(dir_v1 < 0) dir_v1 = j; else dir_v2 = j; } orig_tree = tree; orig_move = move; do { move->n_link->b[dir_v0]->l->v = move->l0; move->n_link->b[dir_v0]->l_var->v = move->v0; if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num) { move->n_link->b[dir_v2]->l->v = move->l1; move->n_link->b[dir_v1]->l->v = move->l2; if(tree->io->mod->gamma_mgf_bl == YES) { move->n_link->b[dir_v2]->l_var->v = move->v1; move->n_link->b[dir_v1]->l_var->v = move->v2; } } else { move->n_link->b[dir_v1]->l->v = move->l1; move->n_link->b[dir_v2]->l->v = move->l2; if(tree->io->mod->gamma_mgf_bl == YES) { move->n_link->b[dir_v1]->l_var->v = move->v1; move->n_link->b[dir_v2]->l_var->v = move->v2; } } if(tree->next) { move = move->next; tree = tree->next; } else { move = move->next; tree = tree->next; } } while(tree); move = orig_move; tree = orig_tree; MIXT_Set_Alias_Subpatt(YES,tree); move->lnL = Triple_Dist(move->n_link,tree,YES); MIXT_Set_Alias_Subpatt(NO,tree); if((move->lnL < best_lnL) && (move->lnL > best_lnL - tree->mod->s_opt->max_delta_lnL_spr)) { /* Estimate the three t_edge lengths at the regraft site */ move->lnL = Triple_Dist(move->n_link,tree,NO); } /* Record updated branch lengths for this move */ orig_move = move; orig_tree = tree; do { move->l0 = move->n_link->b[dir_v0]->l->v; move->v0 = move->n_link->b[dir_v0]->l_var->v; if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num) { move->l1 = move->n_link->b[dir_v2]->l->v; move->l2 = move->n_link->b[dir_v1]->l->v; if(tree->io->mod->gamma_mgf_bl == YES) { move->v1 = move->n_link->b[dir_v2]->l_var->v; move->v2 = move->n_link->b[dir_v1]->l_var->v; } } else { move->l1 = move->n_link->b[dir_v1]->l->v; move->l2 = move->n_link->b[dir_v2]->l->v; if(tree->io->mod->gamma_mgf_bl == YES) { move->v1 = move->n_link->b[dir_v1]->l_var->v; move->v2 = move->n_link->b[dir_v2]->l_var->v; } } /* printf("\n. %f %f %f %f",move->l0,move->l1,move->l2,move->lnL); */ /* For(j,2*tree->n_otu-3) */ /* printf("\n== %d %f %f", */ /* j, */ /* tree->a_edges[j]->gamma_prior_mean, */ /* tree->a_edges[j]->l_var->v); */ if(tree->next) { move = move->next; tree = tree->next; } else { move = move->next; tree = tree->next; } } while(tree); move = orig_move; tree = orig_tree; if(move->lnL > best_lnL + tree->mod->s_opt->min_diff_lk_move) { best_lnL = move->lnL; best_move = i; } /* Regraft the subtree at its original position */ Prune_Subtree(move->n_link, move->n_opp_to_link, &move->b_target, &b_residual, tree); Graft_Subtree(init_target, move->n_link, b_residual, tree); /* Restore branch lengths */ Restore_Br_Len(tree); /* Update relevant change proba matrices */ /* Update_PMat_At_Given_Edge(move->n_link->b[0],tree); */ /* Update_PMat_At_Given_Edge(move->n_link->b[1],tree); */ /* Update_PMat_At_Given_Edge(move->n_link->b[2],tree); */ Update_PMat_At_Given_Edge(move->b_target,tree); /* Update_P_Lk(tree,move->n_link->b[0],move->n_link); */ /* Update_P_Lk(tree,move->n_link->b[1],move->n_link); */ /* Update_P_Lk(tree,move->n_link->b[2],move->n_link); */ /* Update conditional likelihoods along the path from the prune to the regraft position */ /* Update_P_Lk_Along_A_Path(move->path,move->depth_path+1,tree); */ tree->c_lnL = init_lnL; } /* Bail out as soon as you've found a true improvement */ if(move->lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) break; } /* PhyML_Printf("\n. [ %4d/%4d ]",i,list_size); */ /* PhyML_Printf("\n. max_improv = %f",max_improv); */ MIXT_Set_Alias_Subpatt(YES,tree); For(i,list_size) { move = spr_list[i]; if(move->b_target) { For(j,3) Update_PMat_At_Given_Edge(move->n_link->b[j],tree); For(j,3) Update_P_Lk(tree,move->n_link->b[j],move->n_link); /* TO DO : we don't need to update all these partial likelihoods here. Would need to record only those that were along the paths examined above */ For(j,3) if(move->n_link->v[j] != move->n_opp_to_link) Pre_Order_Lk(move->n_link,move->n_link->v[j],tree); break; } } MIXT_Set_Alias_Subpatt(NO,tree); #ifdef DEBUG if(best_move < 0 && list_size > 0) { PhyML_Printf("\n\n. Best_move < 0 !"); PhyML_Printf("\n. List size = %d",list_size); For(i,list_size) { move = spr_list[i]; PhyML_Printf("\n. %p %p",move,move->b_target); } PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } #endif Free(recorded_l); return best_move; } /*********************************************************/ int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree) { t_edge *init_target, *b_residual; int j; int dir_v0, dir_v1, dir_v2; int accept; t_edge *orig_b; t_spr *orig_move; t_tree *orig_tree; if(tree->mixt_tree != NULL) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } Record_Br_Len(tree); Prune_Subtree(move->n_link, move->n_opp_to_link, &init_target, &b_residual, tree); orig_tree = tree; orig_b = init_target; orig_move = move; do { init_target->l->v = move->init_target_l; init_target->l_var->v = move->init_target_v; if(tree->next) { init_target = init_target->next; move = move->next; tree = tree->next; } else { init_target = init_target->next; move = move->next; tree = tree->next; } } while(tree); init_target = orig_b; move = orig_move; tree = orig_tree; Graft_Subtree(move->b_target,move->n_link,b_residual,tree); dir_v1 = dir_v2 = dir_v0 = -1; For(j,3) { if(move->n_link->v[j] == move->n_opp_to_link) dir_v0 = j; else if(dir_v1 < 0) dir_v1 = j; else dir_v2 = j; } orig_move = move; orig_tree = tree; do { move->n_link->b[dir_v0]->l->v = move->l0; move->n_link->b[dir_v0]->l_var->v = move->v0; if(move->n_link->v[dir_v1]->num > move->n_link->v[dir_v2]->num) { move->n_link->b[dir_v2]->l->v = move->l1; move->n_link->b[dir_v1]->l->v = move->l2; if(tree->io->mod->gamma_mgf_bl == YES) { move->n_link->b[dir_v2]->l_var->v = move->v1; move->n_link->b[dir_v1]->l_var->v = move->v2; } } else { move->n_link->b[dir_v1]->l->v = move->l1; move->n_link->b[dir_v2]->l->v = move->l2; if(tree->io->mod->gamma_mgf_bl == YES) { move->n_link->b[dir_v1]->l_var->v = move->v1; move->n_link->b[dir_v2]->l_var->v = move->v2; } } if(tree->next) { move = move->next; tree = tree->next; } else { move = move->next; tree = tree->next; } } while(tree); move = orig_move; tree = orig_tree; accept = YES; if(!Check_Topo_Constraints(tree,tree->io->cstr_tree)) accept = NO; if(accept == YES) /* Apply the move */ { time(&(tree->t_current)); Pars(NULL,tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); if(FABS(tree->c_lnL - move->lnL) > tree->mod->s_opt->min_diff_lk_move) { int i; PhyML_Printf("\n== c_lnL = %f move_lnL = %f", tree->c_lnL,move->lnL); printf("\n== l0=%f l1=%f l2=%f v0=%f v1=%f v2=%f",move->l0,move->l1,move->l2,move->v0,move->v1,move->v2); For(i,2*tree->n_otu-3) printf("\n== %d %f %f", i, tree->a_edges[i]->l->v, tree->a_edges[i]->l_var->v); /* printf("\n. %f %f %f %f", */ /* tree->next->c_lnL, */ /* tree->next->next->c_lnL, */ /* tree->next->next->c_lnL, */ /* tree->next->next->next->c_lnL); */ PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } // /* if(!(tree->n_improvements % tree->mod->s_opt->br_len_in_spr)) */ /* { */ /* tree->mod->s_opt->brent_it_max = 10; */ /* Optimize_Br_Len_Serie(tree->a_nodes[0], */ /* tree->a_nodes[0]->v[0], */ /* tree->a_nodes[0]->b[0], */ /* tree, */ /* tree->data); */ /* tree->mod->s_opt->brent_it_max = 500; */ /* tree->both_sides = 1; */ /* Lk(tree); */ /* } */ // if((tree->mod->s_opt->print) && (!tree->io->quiet)) { Print_Lk_And_Pars(tree); PhyML_Printf(" [depth=%5d]",move->depth_path); fflush(NULL); } if(move->depth_path > tree->max_spr_depth) tree->max_spr_depth = move->depth_path; tree->n_improvements++; if(tree->c_lnL > tree->best_lnL) tree->best_lnL = tree->c_lnL; Record_Br_Len(tree); if(move->depth_path > tree->mod->s_opt->deepest_path) tree->mod->s_opt->deepest_path = move->depth_path; return 1; } Prune_Subtree(move->n_link, move->n_opp_to_link, &move->b_target, &b_residual, tree); Graft_Subtree(init_target, move->n_link, b_residual, tree); Restore_Br_Len(tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); Pars(NULL,tree); return 0; } /*********************************************************/ int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree) { t_edge *init_target, *b_residual; Record_Br_Len(tree); Prune_Subtree(move->n_link, move->n_opp_to_link, &init_target, &b_residual, tree); Graft_Subtree(move->b_target,move->n_link,b_residual,tree); MIXT_Set_Alias_Subpatt(YES,tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); Optimize_Br_Len_Serie(tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); if(tree->c_lnL > tree->best_lnL + tree->mod->s_opt->min_diff_lk_move) { Pars(NULL,tree); if((tree->mod->s_opt->print) && (!tree->io->quiet)) Print_Lk(tree,"[Topology ]"); tree->n_improvements++; tree->best_lnL = tree->c_lnL; Record_Br_Len(tree); return 1; } else { Prune_Subtree(move->n_link, move->n_opp_to_link, &move->b_target, &b_residual, tree); Graft_Subtree(init_target, move->n_link, b_residual, tree); Restore_Br_Len(tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); Lk(NULL,tree); MIXT_Set_Alias_Subpatt(NO,tree); Pars(NULL,tree); return 0; } return -1; } /*********************************************************/ void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree) { int i; t_spr *buff_spr,*orig_move, *orig_move_list, *move_list; t_tree *orig_tree; if(tree->mixt_tree != NULL) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } if((( tree->mod->s_opt->spr_lnL) && (move->lnL > tree->spr_list[tree->size_spr_list-1]->lnL)) || ((!tree->mod->s_opt->spr_lnL) && (move->pars <= tree->spr_list[tree->size_spr_list-1]->pars))) { move_list = tree->spr_list[tree->size_spr_list-1]; move_list->depth_path = move->depth_path; move_list->pars = move->pars; move_list->lnL = move->lnL; move_list->dist = move->dist; orig_move = move; orig_move_list = move_list; orig_tree = tree; do { move_list->l0 = move->l0; move_list->l1 = move->l1; move_list->l2 = move->l2; move_list->v0 = move->v0; move_list->v1 = move->v1; move_list->v2 = move->v2; move_list->b_target = move->b_target; move_list->n_link = move->n_link; move_list->n_opp_to_link = move->n_opp_to_link; move_list->b_opp_to_link = move->b_opp_to_link; if(tree->next) { move = move->next; move_list = move_list->next; tree = tree->next; } else { move = move->next; move_list = move_list->next; tree = tree->next; } } while(tree); move = orig_move; move_list = orig_move_list; tree = orig_tree; For(i,move_list->depth_path+1) move_list->path[i] = move->path[i]; for(i=tree->size_spr_list-1;i>0;i--) { if((( tree->mod->s_opt->spr_lnL) && (tree->spr_list[i]->lnL > tree->spr_list[i-1]->lnL)) || ((!tree->mod->s_opt->spr_lnL) && (tree->spr_list[i]->pars <= tree->spr_list[i-1]->pars))) { orig_tree = tree; do { buff_spr = tree->spr_list[i-1]; tree->spr_list[i-1] = tree->spr_list[i]; tree->spr_list[i] = buff_spr; if(tree->next) tree = tree->next; else tree = tree->next; } while(tree); tree = orig_tree; } else break; } } } /*********************************************************/ void Random_Spr(int n_moves, t_tree *tree) { int i; int br_pulled, br_target; t_spr *spr_struct; t_edge *target, *residual; spr_struct = Make_One_Spr(tree); Init_One_Spr(spr_struct); target = residual = NULL; For(i,n_moves) { /* br_pulled = (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-1)); */ br_pulled = Rand_Int(0,2*tree->n_otu-3-1); do { /* br_target = (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-1)); */ br_target = Rand_Int(0,2*tree->n_otu-3-1); } while(br_target == br_pulled); spr_struct->n_link = tree->a_edges[br_pulled]->left; spr_struct->n_opp_to_link = tree->a_edges[br_pulled]->rght; spr_struct->b_opp_to_link = tree->a_edges[br_pulled]; spr_struct->b_target = tree->a_edges[br_target]; spr_struct->b_init_target = NULL; if(!Check_Spr_Move_Validity(spr_struct,tree)) { spr_struct->n_link = tree->a_edges[br_pulled]->rght; spr_struct->n_opp_to_link = tree->a_edges[br_pulled]->left; } #ifdef DEBUG if(!Check_Spr_Move_Validity(spr_struct,tree)) { Warn_And_Exit("\n== Could not find a valid move...\n"); } #endif if(spr_struct->n_link == spr_struct->b_target->left || spr_struct->n_link == spr_struct->b_target->rght) { n_moves++; continue; } Prune_Subtree(spr_struct->n_link, spr_struct->n_opp_to_link, &target, &residual, tree); Graft_Subtree(spr_struct->b_target, spr_struct->n_link, residual,tree); } Free(spr_struct); } /*********************************************************/ void Reset_Spr_List(t_tree *tree) { int i; For(i,tree->size_spr_list) { tree->spr_list[i]->depth_path = 0; tree->spr_list[i]->pars = MAX_PARS; tree->spr_list[i]->lnL = UNLIKELY; tree->spr_list[i]->n_link = NULL; tree->spr_list[i]->n_opp_to_link = NULL; tree->spr_list[i]->b_target = NULL; } } /*********************************************************/ int Check_Spr_Move_Validity(t_spr *this_spr_move, t_tree *tree) { int match; match = 0; Found_In_Subtree(this_spr_move->n_link, this_spr_move->n_opp_to_link, this_spr_move->b_target->left, &match, tree); if(match) return 0; else return 1; } /*********************************************************/ void Spr_Pars(t_tree *tree) { PhyML_Printf("\n. Minimizing parsimony...\n"); tree->best_pars = 1E+8; tree->best_lnL = UNLIKELY; tree->mod->s_opt->spr_lnL = 0; tree->mod->s_opt->spr_pars = 1; do { Speed_Spr(tree,1); }while(tree->n_improvements); tree->mod->s_opt->spr_pars = 0; PhyML_Printf("\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void SPR_Shuffle(t_tree *mixt_tree) { phydbl lk_old; int *orig_catg,n; t_tree *tree,**tree_list; if(mixt_tree->mod->s_opt->print) PhyML_Printf("\n\n. Refining the tree...\n"); /*! Get the number of classes in each mixture */ orig_catg = MIXT_Get_Number_Of_Classes_In_All_Mixtures(mixt_tree); /*! Set the number of rate classes to (at most) 2. ! Propagate this to every mixture tree in the analysis */ tree = mixt_tree; n = 0; do { #ifdef BEAGLE tree->b_inst = create_beagle_instance(tree, tree->io->quiet, tree->io); //Instead of capping the rate categories at 2, just //give the other categories 0 weight if(orig_catg[n] > 2) //should we even bother? { double cat_wghts[orig_catg[n]]; //Give the first two categories equal weights cat_wghts[0] = 0.5; cat_wghts[1] = 0.5; int i; for(i=2;ib_inst,0,cat_wghts); if(ret<0) {fprintf(stderr, "beagleSetCategoryWeights() on instance %i failed:%i\n\n",tree->b_inst,ret);Exit(""); } tree->mod->optimizing_topology = true; } #endif tree->mod->ras->n_catg = MIN(2,orig_catg[n]); if(tree->mod->ras->invar == YES) tree->mod->ras->n_catg--; tree = tree->next_mixt; n++; } while(tree); /*! Make sure the number of trees in each mixture is at most 2 */ tree_list = MIXT_Record_All_Mixtures(mixt_tree); MIXT_Break_All_Mixtures(orig_catg,mixt_tree); Set_Both_Sides(YES,mixt_tree); Lk(NULL,mixt_tree); /* mixt_tree->mod->s_opt->print = YES; */ mixt_tree->best_pars = 1E+8; mixt_tree->mod->s_opt->spr_pars = NO; mixt_tree->mod->s_opt->quickdirty = NO; mixt_tree->best_lnL = mixt_tree->c_lnL; mixt_tree->mod->s_opt->max_delta_lnL_spr = 0.; mixt_tree->mod->s_opt->max_depth_path = mixt_tree->n_otu; mixt_tree->mod->s_opt->spr_lnL = NO; mixt_tree->annealing_temp = 4.; do { Set_Both_Sides(YES,mixt_tree); Lk(NULL,mixt_tree); Pars(NULL,mixt_tree); Record_Br_Len(mixt_tree); mixt_tree->n_improvements = 0; mixt_tree->max_spr_depth = 0; mixt_tree->best_pars = mixt_tree->c_pars; mixt_tree->best_lnL = mixt_tree->c_lnL; lk_old = mixt_tree->c_lnL; Spr(UNLIKELY,mixt_tree); Optimiz_All_Free_Param(mixt_tree,(mixt_tree->io->quiet)?(0):(mixt_tree->mod->s_opt->print)); Optimize_Br_Len_Serie(mixt_tree); mixt_tree->annealing_temp -= 2.; if(mixt_tree->annealing_temp < 0.0) mixt_tree->annealing_temp = 0.0; if((mixt_tree->n_improvements < 20 || mixt_tree->max_spr_depth < 5 || (FABS(lk_old-mixt_tree->c_lnL) < 1.)) && (Are_Equal(mixt_tree->annealing_temp,0.0,1.E-6))) break; /* PhyML_Printf("\n. Temperature: %f",mixt_tree->annealing_temp); */ } while(1); mixt_tree->annealing_temp = 0.0; if(mixt_tree->mod->s_opt->print && (!mixt_tree->io->quiet)) { PhyML_Printf("\n\n. End of refining stage...\n"); } /*! Go back to the original data structure, with potentially more ! than 2 trees per mixture */ MIXT_Reconnect_All_Mixtures(tree_list,mixt_tree); Free(tree_list); /*! Set the number of rate classes to their original values */ tree = mixt_tree; n = 0; do { tree->mod->ras->n_catg = orig_catg[n]; #ifdef BEAGLE tree->mod->optimizing_topology = false; //Reset the rate categories to their original weights if(orig_catg[n] > 2){ update_beagle_ras(tree->mod); } #endif if(tree->mod->ras->invar == YES) tree->mod->ras->n_catg--; tree = tree->next_mixt; n++; } while(tree); Free(orig_catg); /*! Only the first two trees for each mixture have been modified so ! far -> need to update the other trees by copying the modified trees ! onto them. */ tree = mixt_tree; do { if(tree != mixt_tree) Copy_Tree(mixt_tree,tree); tree = tree->next; } while(tree); } /* ** EOF: spr.c */ phyml-3.2.0/src/spr.h000066400000000000000000000060741263450375500144320ustar00rootroot00000000000000/* ** spr.h: Header file for the SPR routines. ** ** Wim Hordijk Last modified: 28 August 2006 */ #include #ifndef _SPR_H_ #define _SPR_H_ #include "utilities.h" #define ALL 1 #define BEST 2 #define ONE 3 /* ** _move_: Structure for holding the relevant information for candidate SPR moves. */ typedef struct { t_node *v_prune, *u_prune, *v_n, *v_nx1, *u_n, **path; t_edge *e_prune, *e_regraft; phydbl l_connect, l_est[3], delta_lk, d_L, d_up_v, d_un_v; int dist, rgrft_rank, optim_rank, globl_rank; } _move_; void Init_SPR (t_tree *tree); void Clean_SPR (t_tree *tree); void Optim_SPR (t_tree *tree, int max_size, int method); int Perform_SPR_Moves (t_tree *tree, int max_size); int Perform_Best_SPR (t_tree *tree, int max_size); int Perform_One_SPR (t_tree *tree, int max_size); void Calc_Tree_Length (t_edge *e_prune, t_node *v_prune, t_tree *tree); void Tree_Length (t_node *v_prune, t_node *u_prune, t_node *v_n, t_node *v_n_1, t_node *v_nx1, t_node *v_0, t_node *u_n, phydbl d_up_v_1, phydbl d_uu, phydbl d_L_1, int n, t_tree *tree); int Est_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree); int Best_Lk_Change (t_edge *e_prune, t_node *v_prune, t_tree *tree); void Make_Move (_move_ *move, int type, t_tree *tree); int Find_Optim_Local (t_tree *tree); int Find_Optim_Globl (t_tree *tree); void Prune (t_edge *e, t_node *v, t_edge **e_connect, t_edge **e_avail, t_tree *tree); void Regraft (t_edge *e, t_node *v, t_edge *avail, t_tree *tree); void PostOrder_v (t_tree *tree, t_node *v, t_edge *e); void PostOrder_w (t_tree *tree, t_node *v, t_edge *v_e, t_node *w, t_edge *e); void Speed_Spr(t_tree *tree, int max_cycles); void Speed_Spr_Loop(t_tree *tree); void Make_Spr_List(t_tree *tree); void Init_One_Spr(t_spr *a_spr); t_spr *Make_One_Spr(t_tree *tree); int Spr(phydbl init_lnL, t_tree *tree); int Spr_Recur(t_node *a, t_node *d, t_tree *tree); int Test_All_Spr_Targets(t_edge *pulled, t_node *link, t_tree *tree); void Randomize_Spr_List(t_tree *tree); void Test_One_Spr_Target_Recur(t_node *a, t_node *d, t_edge *pulled, t_node *link, t_edge *residual, int *best_found, t_tree *tree); phydbl Test_One_Spr_Target(t_edge *target, t_edge *arrow, t_node *link, t_edge *residual, t_tree *tree); void Apply_Spr_Moves_One_By_One(t_tree *tree); int Try_One_Spr_Move_Triple(t_spr *move, t_tree *tree); int Try_One_Spr_Move_Full(t_spr *move, t_tree *tree); void Make_Best_Spr(t_tree *tree); void Random_Spr(int n_moves, t_tree *tree); void Include_One_Spr_To_List_Of_Spr(t_spr *move, t_tree *tree); void Reset_Spr_List(t_tree *tree); int Evaluate_List_Of_Regraft_Pos_Triple(t_spr **spr_list, int list_size, t_tree *tree); void Best_Spr(t_tree *tree); int Check_Spr_Move_Validity(t_spr *this_spr_move, t_tree *tree); void Spr_Subtree(t_edge *b, t_node *link, t_tree *tree); void Spr_Pars(t_tree *tree); void SPR_Shuffle(t_tree *tree); void Sort_Spr_List_Depth(t_tree *tree); void Sort_Spr_List_LnL(t_tree *tree); #endif /* _SPR_H_ */ /* ** EOF: spr.h */ phyml-3.2.0/src/stats.c000066400000000000000000005205261263450375500147620ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "stats.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* RANDOM VARIATES GENERATORS */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*********************************************************************/ /* A C-function for TT800 : July 8th 1996 Version */ /* by M. Matsumoto, email: matumoto@math.keio.ac.jp */ /* tt800() generate one pseudorandom number with double precision */ /* which is uniformly distributed on [0,1]-interval */ /* for each call. One may choose any initial 25 seeds */ /* except all zeros. */ /* See: ACM Transactions on Modelling and Computer Simulation, */ /* Vol. 4, No. 3, 1994, pages 254-266. */ phydbl tt800() { int M=7; unsigned long y; static int k = 0; static unsigned long x[25]={ /* initial 25 seeds, change as you wish */ 0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23, 0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825, 0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f, 0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9, 0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb }; static unsigned long mag01[2]={ 0x0, 0x8ebfd028 /* this is magic vector `a', don't change */ }; if (k==25) { /* generate 25 words at one time */ int kk; for (kk=0;kk<25-M;kk++) { x[kk] = x[kk+M] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2]; } for (; kk<25;kk++) { x[kk] = x[kk+(M-25)] ^ (x[kk] >> 1) ^ mag01[x[kk] % 2]; } k=0; } y = x[k]; y ^= (y << 7) & 0x2b5b2500; /* s and b, magic vectors */ y ^= (y << 15) & 0xdb8b0000; /* t and c, magic vectors */ y &= 0xffffffff; /* you may delete this line if word size = 32 */ /* the following line was added by Makoto Matsumoto in the 1996 version to improve lower bit's corellation. Delete this line to o use the code published in 1994. */ y ^= (y >> 16); /* added to the 1994 version */ k++; return((phydbl)y / (unsigned long) 0xffffffff); } /*********************************************************************/ phydbl Uni() { phydbl r,mx; mx = (phydbl)RAND_MAX; r = (phydbl)rand(); r /= mx; /* r = tt800(); */ return r; } /*********************************************************************/ // Return a uniform draw u s.t., min <= u <= max int Rand_Int(int min, int max) { /* phydbl u; */ /* u = (phydbl)rand(); */ /* u /= (RAND_MAX); */ /* u *= (max - min + 1); */ /* u += min; */ /* return (int)FLOOR(u); */ int u; /* if(max < min) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); */ u = rand(); return (u%(max+1-min)+min); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /********************* random Gamma generator ************************ * Properties: * (1) X = Gamma(alpha,lambda) = Gamma(alpha,1)/lambda * (2) X1 = Gamma(alpha1,1), X2 = Gamma(alpha2,1) independent * then X = X1+X2 = Gamma(alpha1+alpha2,1) * (3) alpha = k = integer then * X = Gamma(k,1) = Erlang(k,1) = -sum(LOG(Ui)) = -LOG(prod(Ui)) * where U1,...Uk iid uniform(0,1) * * Decompose alpha = k+delta with k = [alpha], and 00.) { phydbl y = 0.; phydbl b = (alpha+EXP(1.))/EXP(1.); phydbl p = 1./alpha; int go = 0; while (go==0) { phydbl u = Uni(); phydbl w = Uni(); phydbl v = b*u; if (v<=1.) { x = POW(v,p); y = EXP(-x); } else { x = -LOG(p*(b-v)); y = POW(x,alpha-1.); } go = (w= 1. Algorithm GD in: Ahrens, J.H. and Dieter, U. (1982). Generating gamma variates by a modified rejection technique. Comm. ACM, 25, 47-54. [2] Shape parameter 0 < a < 1. Algorithm GS in: Ahrens, J.H. and Dieter, U. (1974). Computer methods for sampling from gamma, beta, poisson and binomial distributions. Computing, 12, 223-246. */ double a = (double)shape; /* Constants : */ const static double sqrt32 = 5.656854; const static double exp_m1 = 0.36787944117144232159;/* exp(-1) = 1/e */ /* Coefficients q[k] - for q0 = sum(q[k]*a^(-k)) * Coefficients a[k] - for q = q0+(t*t/2)*sum(a[k]*v^k) * Coefficients e[k] - for exp(q)-1 = sum(e[k]*q^k) */ const static double q1 = 0.04166669; const static double q2 = 0.02083148; const static double q3 = 0.00801191; const static double q4 = 0.00144121; const static double q5 = -7.388e-5; const static double q6 = 2.4511e-4; const static double q7 = 2.424e-4; const static double a1 = 0.3333333; const static double a2 = -0.250003; const static double a3 = 0.2000062; const static double a4 = -0.1662921; const static double a5 = 0.1423657; const static double a6 = -0.1367177; const static double a7 = 0.1233795; /* State variables [FIXME for threading!] :*/ static double aa = 0.; static double aaa = 0.; static double s, s2, d; /* no. 1 (step 1) */ static double q0, b, si, c;/* no. 2 (step 4) */ double e, p, q, r, t, u, v, w, x, ret_val; if(a < 0.0 || scale <= 0.0) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if (a < 1.) { /* GS algorithm for parameters a < 1 */ if(a == 0) return 0.; e = 1.0 + exp_m1 * a; for(;;) { p = e * Uni(); if (p >= 1.0) { x = -LOG((e - p) / a); if (Rexp(1.) >= (1.0 - a) * LOG(x)) break; } else { x = EXP(LOG(p) / a); if (Rexp(1.) >= x) break; } } return scale * x; } /* --- a >= 1 : GD algorithm --- */ /* Step 1: Recalculations of s2, s, d if a has changed */ if (a != aa) { aa = a; s2 = a - 0.5; s = SQRT(s2); d = sqrt32 - s * 12.0; } /* Step 2: t = standard normal deviate, x = (s,1/2) -normal deviate. */ /* immediate acceptance (i) */ t = Rnorm(0.0,1.0); x = s + 0.5 * t; ret_val = x * x; if (t >= 0.0) return scale * ret_val; /* Step 3: u = 0,1 - uniform sample. squeeze acceptance (s) */ u = Uni(); if (d * u <= t * t * t) return scale * ret_val; /* Step 4: recalculations of q0, b, si, c if necessary */ if (a != aaa) { aaa = a; r = 1.0 / a; q0 = ((((((q7 * r + q6) * r + q5) * r + q4) * r + q3) * r + q2) * r + q1) * r; /* Approximation depending on size of parameter a */ /* The constants in the expressions for b, si and c */ /* were established by numerical experiments */ if (a <= 3.686) { b = 0.463 + s + 0.178 * s2; si = 1.235; c = 0.195 / s - 0.079 + 0.16 * s; } else if (a <= 13.022) { b = 1.654 + 0.0076 * s2; si = 1.68 / s + 0.275; c = 0.062 / s + 0.024; } else { b = 1.77; si = 0.75; c = 0.1515 / s; } } /* Step 5: no quotient test if x not positive */ if (x > 0.0) { /* Step 6: calculation of v and quotient q */ v = t / (s + s); if (FABS(v) <= 0.25) q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; else q = q0 - s * t + 0.25 * t * t + (s2 + s2) * log(1.0 + v); /* Step 7: quotient acceptance (q) */ if (LOG(1.0 - u) <= q) return scale * ret_val; } for(;;) { /* Step 8: e = standard exponential deviate * u = 0,1 -uniform deviate * t = (b,si)-double exponential (laplace) sample */ e = Rexp(1.0); u = Uni(); u = u + u - 1.0; if (u < 0.0) t = b - si * e; else t = b + si * e; /* Step 9: rejection if t < tau(1) = -0.71874483771719 */ if (t >= -0.71874483771719) { /* Step 10: calculation of v and quotient q */ v = t / (s + s); if (FABS(v) <= 0.25) q = q0 + 0.5 * t * t * ((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v; else q = q0 - s * t + 0.25 * t * t + (s2 + s2) * LOG(1.0 + v); /* Step 11: hat acceptance (h) */ /* (if q not positive go to step 8) */ if (q > 0.0) { w = EXP(q)-1.0; /* if t is rejected sample again at step 8 */ if (c * FABS(u) <= w * EXP(e - 0.5 * t * t)) break; } } } /* repeat .. until `t' is accepted */ x = s + 0.5 * t; return scale * x * x; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Rexp(phydbl lambda) { return -LOG(Uni()+1.E-30)/lambda; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Returns a random deviates from an exponential distribution */ /* left-truncated at 'left' and right-truncated at 'rght' */ phydbl Rexp_Trunc(phydbl lambda, phydbl left, phydbl rght) { phydbl u; u = Uni(); return (left-LOG(1. - u*(1.-EXP(-lambda*(rght-left))))/lambda); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Rnorm(phydbl mean, phydbl sd) { /* Box-Muller transformation */ phydbl u1, u2, res; /* u1=Uni(); */ /* u2=Uni(); */ /* u1 = SQRT(-2.*LOG(u1))*COS(6.28318530717959f*u2); */ /* Polar */ phydbl d,x,y; do { u1=Uni(); u2=Uni(); x = 2.*u1-1.; y = 2.*u2-1.; d = x*x + y*y; if(d>.0 && d<1.) break; } while(1); u1 = x*SQRT((-2.*LOG(d))/d); res = u1*sd+mean; if(isnan(res) || isinf(res)) { printf("\n. res=%f sd=%f mean=%f u1=%f u2=%f",res,sd,mean,u1,u2); } return res; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *Rnorm_Multid(phydbl *mu, phydbl *cov, int dim) { phydbl *L,*x,*y; int i,j; x = (phydbl *)mCalloc(dim,sizeof(phydbl)); y = (phydbl *)mCalloc(dim,sizeof(phydbl)); L = (phydbl *)Cholesky_Decomp(cov,dim); For(i,dim) x[i]=Rnorm(0.0,1.0); For(i,dim) For(j,dim) y[i] += L[i*dim+j]*x[j]; For(i,dim) y[i] += mu[i]; Free(L); Free(x); return(y); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Rnorm_Trunc_Inverse(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error) { phydbl u, ret_val,eps; phydbl z; phydbl z_min,z_max; phydbl cdf_min, cdf_max; z = 0.0; u = -1.0; *error = 0; if(sd < 1.E-100) { PhyML_Printf("\n. Small variance detected in Rnorm_Trunc."); PhyML_Printf("\n. mean=%f sd=%f min=%f max=%f",mean,sd,min,max); *error = 1; return -1.0; } z_min = (min - mean)/sd; z_max = (max - mean)/sd; eps = (z_max-z_min)/1E+6; /* Simple inversion method. Seems to work well. Needs more thorough testing though... */ cdf_min = Pnorm(z_min,0.0,1.0); cdf_max = Pnorm(z_max,0.0,1.0); u = cdf_min + (cdf_max-cdf_min) * Uni(); z = PointNormal(u); if((z < z_min-eps) || (z > z_max+eps)) { *error = 1; PhyML_Printf("\n. Numerical precision issue detected in Rnorm_Trunc."); PhyML_Printf("\n. z = %f",z); PhyML_Printf("\n. mean=%f sd=%f z_min=%f z_max=%f min=%f max=%f",mean,sd,z_min,z_max,min,max); ret_val = (max - min)/2.; Exit("\n"); } ret_val = z*sd+mean; return ret_val; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error) { phydbl ret_val; phydbl z, q, u, a; phydbl z_min,z_max; int n_max_iter,n_iter; int algo; z = 0.0; *error = NO; ret_val = INFINITY; n_max_iter = 100000; if(sd < 1.E-100) { PhyML_Printf("\n. Small variance detected in Rnorm_Trunc."); PhyML_Printf("\n. mean=%f sd=%f min=%f max=%f",mean,sd,min,max); *error = YES; return -1.0; } if(max < min) { PhyML_Printf("\n. Max < Min"); PhyML_Printf("\n. mean=%f sd=%f min=%f max=%f",mean,sd,min,max); *error = YES; return -1.0; } z_min = (min - mean)/sd; z_max = (max - mean)/sd; if(z_min < 0.0 && z_max > 0 && (z_max - z_min > SQRT(2*PI))) { algo = 0; } if((z_min > 0.0 || Are_Equal(z_min,0.0,1.E-10)) && z_max > z_min + 2.*SQRT(EXP(1.0))/(z_min + SQRT(z_min*z_min+4.)) * EXP((z_min*z_min - z_min*SQRT(z_min*z_min+4.))/4.)) { algo = 1; } else if((z_max < 0.0 || Are_Equal(z_max,0.0,1.E-10)) && -z_min > -z_max + 2.*SQRT(EXP(1.0))/(-z_max + SQRT(z_max*z_max+4.)) * EXP((z_max*z_max - (-z_max)*SQRT(z_max*z_max+4.))/4.)) { algo = 2; } else { algo = 3; } switch(algo) { case 0: { n_iter = 0; do { z = Rnorm(0.0,1.0); n_iter++; if(n_iter > n_max_iter) { PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()"); *error = YES; } } while(z < z_min || z > z_max); break; } case 1: { n_iter = 0; do { a = (z_min + SQRT(z_min*z_min+4.))/2.; q = Rexp(a) + z_min; u = Uni(); n_iter++; if(n_iter > n_max_iter) { PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()"); *error = YES; } }while(u > EXP(-POW(q-a,2)/2.)); z = q; break; } case 2: { n_iter = 0; do { a = (-z_max + SQRT(z_max*z_max+4.))/2.; q = Rexp(a) - z_max; u = Uni(); n_iter++; if(n_iter > n_max_iter) { PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()"); *error = YES; } }while(u > EXP(-POW(q-a,2)/2.)); z = -q; break; } case 3: { n_iter = 0; do { z = Uni()*(z_max - z_min) + z_min; if(z_min < 0.0 && z_max > 0.0) q = EXP(-z*z/2.); else if (z_max < 0.0) q = EXP((z_max*z_max-z*z)/2.); else q = EXP((z_min*z_min-z*z)/2.); u = Uni(); n_iter++; if(n_iter > n_max_iter) { PhyML_Printf("\n== Too many iterations in Rnorm_Trunc()"); *error = YES; } }while(u > q); break; } default: Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } ret_val = z*sd+mean; return ret_val; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *Rnorm_Multid_Trunc(phydbl *mean, phydbl *cov, phydbl *min, phydbl *max, int dim) { int i,j; phydbl *L,*x, *u; phydbl up, low, rec; int err; u = (phydbl *)mCalloc(dim,sizeof(phydbl)); x = (phydbl *)mCalloc(dim,sizeof(phydbl)); L = Cholesky_Decomp(cov,dim); low = (min[0]-mean[0])/L[0*dim+0]; up = (max[0]-mean[0])/L[0*dim+0]; u[0] = Rnorm_Trunc(0.0,1.0,low,up,&err); for(i=1;i>>\n"); */ /* For(i,dim) */ /* { */ /* For(j,dim) */ /* { */ /* PhyML_Printf("%10lf ",L[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ /* PhyML_Printf("\n"); */ /* For(i,dim) PhyML_Printf("%f ",u[i]); */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n"); */ /* For(i,dim) PhyML_Printf("%10lf ",x[i]); */ /* PhyML_Printf("\n<<<\n"); */ For(i,dim) x[i] += mean[i]; Free(L); Free(u); return x; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Inversion method for sampling from Geometric distibution */ phydbl Rgeom(phydbl p) { phydbl x,u; u = Uni(); if(u < SMALL) return(0.0); x = LOG(u) / LOG(1. - p); return(CEIL(x)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dgeom(phydbl k, phydbl p, int logit) { phydbl prob; if(k < 1.) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(p > 1.-SMALL) { if(logit == YES) return(-INFINITY); else return(0.0); } if(logit == YES) prob = (k - 1.)*LOG(1. - p) + LOG(p); else prob = POW(1.-p,k-1.)*p; return(prob); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Pgeom(phydbl k, phydbl p) { if(k < 1.) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(p > 1.-SMALL) return(0.0); return(1. - POW((1. - p),k)); } /* * Random variates from the Poisson distribution. Completely stolen from R code. * * REFERENCE * * Ahrens, J.H. and Dieter, U. (1982). * Computer generation of Poisson deviates * from modified normal distributions. * ACM Trans. Math. Software 8, 163-179. */ phydbl Rpois(phydbl mmu) { double mu = (double)mmu; double a0 = -0.5; double a1 = 0.3333333; double a2 = -0.2500068; double a3 = 0.2000118; double a4 = -0.1661269; double a5 = 0.1421878; double a6 = -0.1384794; double a7 = 0.1250060; double one_7 = 0.1428571428571428571; double one_12 = 0.0833333333333333333; double one_24 = 0.0416666666666666667; /* Factorial Table (0:9)! */ const static double fact[10] = { 1., 1., 2., 6., 24., 120., 720., 5040., 40320., 362880. }; /* These are static --- persistent between calls for same mu : */ static int l, m; static double b1, b2, c, c0, c1, c2, c3; static double pp[36], p0, p, q, s, d, omega; static double big_l;/* integer "w/o overflow" */ static double muprev = 0., muprev2 = 0.;/*, muold = 0.*/ /* Local Vars [initialize some for -Wall]: */ double del, difmuk= 0., E= 0., fk= 0., fx, fy, g, px, py, t, u= 0., v, x; double pois = -1.; int k, kflag, big_mu, new_big_mu = FALSE; if (isnan(mu) || mu < 0.0) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if (mu <= 0.) return 0.; big_mu = mu >= 10.; if(big_mu) new_big_mu = FALSE; if (!(big_mu && mu == muprev)) {/* maybe compute new persistent par.s */ if (big_mu) { new_big_mu = TRUE; /* Case A. (recalculation of s,d,l because mu has changed): * The poisson probabilities pk exceed the discrete normal * probabilities fk whenever k >= m(mu). */ muprev = mu; s = sqrt(mu); d = 6. * mu * mu; big_l = floor(mu - 1.1484); /* = an upper bound to m(mu) for all mu >= 10.*/ } else { /* Small mu ( < 10) -- not using normal approx. */ /* Case B. (start new table and calculate p0 if necessary) */ /*muprev = 0.;-* such that next time, mu != muprev ..*/ if (mu != muprev) { muprev = mu; m = MAX(1, (int) mu); l = 0; /* pp[] is already ok up to pp[l] */ q = p0 = p = exp(-mu); } for(;;) { /* Step U. uniform sample for inversion method */ u = Uni(); if (u <= p0) return 0.; /* Step T. table comparison until the end pp[l] of the pp-table of cumulative poisson probabilities (0.458 > ~= pp[9](= 0.45792971447) for mu=10 ) */ if (l != 0) { for (k = (u <= 0.458) ? 1 : MIN(l, m); k <= l; k++) if (u <= pp[k]) return((phydbl)k); if (l == 35) /* u > pp[35] */ continue; } /* Step C. creation of new poisson probabilities p[l..] and their cumulatives q =: pp[k] */ l++; for (k = l; k <= 35; k++) { p *= mu / k; q += p; pp[k] = q; if (u <= q) { l = k; return((phydbl)k); } } l = 35; } /* end(repeat) */ }/* mu < 10 */ } /* end {initialize persistent vars} */ /* Only if mu >= 10 : ----------------------- */ /* Step N. normal sample */ g = mu + s * Rnorm(0.0,1.0);/* norm_rand() ~ N(0,1), standard normal */ if (g >= 0.) { pois = floor(g); /* Step I. immediate acceptance if pois is large enough */ if (pois >= big_l) return((phydbl)pois); /* Step S. squeeze acceptance */ fk = pois; difmuk = mu - fk; u = Uni(); /* ~ U(0,1) - sample */ if (d * u >= difmuk * difmuk * difmuk) return((phydbl)pois); } /* Step P. preparations for steps Q and H. (recalculations of parameters if necessary) */ if (new_big_mu || mu != muprev2) { /* Careful! muprev2 is not always == muprev because one might have exited in step I or S */ muprev2 = mu; omega = M_1_SQRT_2PI / s; /* The quantities b1, b2, c3, c2, c1, c0 are for the Hermite * approximations to the discrete normal probabilities fk. */ b1 = one_24 / mu; b2 = 0.3 * b1 * b1; c3 = one_7 * b1 * b2; c2 = b2 - 15. * c3; c1 = b1 - 6. * b2 + 45. * c3; c0 = 1. - b1 + 3. * b2 - 15. * c3; c = 0.1069 / mu; /* guarantees majorization by the 'hat'-function. */ } if (g >= 0.) { /* 'Subroutine' F is called (kflag=0 for correct return) */ kflag = 0; goto Step_F; } for(;;) { /* Step E. Exponential Sample */ E = Rexp(1.0); /* ~ Exp(1) (standard exponential) */ /* sample t from the laplace 'hat' (if t <= -0.6744 then pk < fk for all mu >= 10.) */ u = 2. * Uni() - 1.; /* t = 1.8 + fsign(E, u); */ t = 1.8 + ((u >= 0.0) ? fabs(E) : -fabs(E)); if (t > -0.6744) { pois = floor(mu + s * t); fk = pois; difmuk = mu - fk; /* 'subroutine' F is called (kflag=1 for correct return) */ kflag = 1; Step_F: /* 'subroutine' F : calculation of px,py,fx,fy. */ if (pois < 10) { /* use factorials from table fact[] */ px = -mu; py = pow(mu, pois) / fact[(int)pois]; } else { /* Case pois >= 10 uses polynomial approximation a0-a7 for accuracy when advisable */ del = one_12 / fk; del = del * (1. - 4.8 * del * del); v = difmuk / fk; if (fabs(v) <= 0.25) px = fk * v * v * (((((((a7 * v + a6) * v + a5) * v + a4) * v + a3) * v + a2) * v + a1) * v + a0) - del; else /* |v| > 1/4 */ px = fk * log(1. + v) - difmuk - del; py = M_1_SQRT_2PI / sqrt(fk); } x = (0.5 - difmuk) / s; x *= x;/* x^2 */ fx = -0.5 * x; fy = omega * (((c3 * x + c2) * x + c1) * x + c0); if (kflag > 0) { /* Step H. Hat acceptance (E is repeated on rejection) */ if (c * fabs(u) <= py * exp(px + E) - fy * exp(fx + E)) break; } else /* Step Q. Quotient acceptance (rare case) */ if (fy - u * fy <= py * exp(px - fx)) break; }/* t > -.67.. */ } return((phydbl)pois); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* DENSITIES / PROBA */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dnorm_Moments(phydbl x, phydbl mean, phydbl var) { phydbl dens,sd,pi; pi = 3.141593; sd = SQRT(var); dens = 1./(SQRT(2*pi)*sd)*EXP(-((x-mean)*(x-mean)/(2.*sd*sd))); return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dnorm(phydbl x, phydbl mean, phydbl sd) { phydbl dens; /* dens = -(.5*LOG2PI+LOG(sd)) - .5*POW(x-mean,2)/POW(sd,2); */ /* return EXP(dens); */ x = (x-mean)/sd; dens = M_1_SQRT_2_PI * EXP(-0.5*x*x); return dens / sd; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Log_Dnorm(phydbl x, phydbl mean, phydbl sd, int *err) { phydbl dens; *err = NO; x = (x-mean)/sd; dens = -(phydbl)LOG(SQRT(2.*PI)) - x*x*0.5 - LOG(sd); if(dens < -BIG) { PhyML_Printf("\n. dens=%f -- x=%f mean=%f sd=%f\n",dens,x,mean,sd); *err = 1; } return dens; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Log_Dnorm_Trunc(phydbl x, phydbl mean, phydbl sd, phydbl lo, phydbl up, int *err) { phydbl log_dens; phydbl cdf_up, cdf_lo; if(x < lo || x > up) return -230.; *err = NO; cdf_lo = cdf_up = 0.0; log_dens = Log_Dnorm(x,mean,sd,err); if(*err == YES) { PhyML_Printf("\n== mean=%f sd=%f lo=%f up=%f cdf_lo=%G CDF_up=%G log_dens=%G",mean,sd,lo,up,cdf_lo,cdf_up,log_dens); PhyML_Printf("\n== Warning in file %s at line %d\n",__FILE__,__LINE__); *err = YES; } cdf_up = Pnorm(up,mean,sd); cdf_lo = Pnorm(lo,mean,sd); if(cdf_up - cdf_lo < 1.E-20) { log_dens = -230.; /* ~LOG(1.E-100) */ } else { log_dens -= LOG(cdf_up - cdf_lo); } if(isnan(log_dens) || isinf(FABS(log_dens))) { PhyML_Printf("\n. x=%f mean=%f sd=%f lo=%f up=%f cdf_lo=%G CDF_up=%G log_dens=%G",x,mean,sd,lo,up,cdf_lo,cdf_up,log_dens); PhyML_Printf("\n. Warning in file %s at line %d\n",__FILE__,__LINE__); *err = YES; } return log_dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dnorm_Trunc(phydbl x, phydbl mean, phydbl sd, phydbl lo, phydbl up) { phydbl dens; phydbl cdf_up, cdf_lo; dens = Dnorm(x,mean,sd); cdf_up = Pnorm(up,mean,sd); cdf_lo = Pnorm(lo,mean,sd); dens /= (cdf_up - cdf_lo); if(isnan(dens) || isinf(FABS(dens))) { PhyML_Printf("\n== mean=%f sd=%f lo=%f up=%f cdf_lo=%G CDF_up=%G",mean,sd,lo,up,cdf_lo,cdf_up); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dnorm_Multi(phydbl *x, phydbl *mu, phydbl *cov, int size, int _log) { phydbl *xmmu,*invcov; phydbl *buff1,*buff2; int i; phydbl det,density; xmmu = (phydbl *)mCalloc(size,sizeof(phydbl)); invcov = (phydbl *)mCalloc(size*size,sizeof(phydbl)); For(i,size) xmmu[i] = x[i] - mu[i]; For(i,size*size) invcov[i] = cov[i]; if(!Matinv(invcov,size,size,NO)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } buff1 = Matrix_Mult(xmmu,invcov,1,size,size,size); buff2 = Matrix_Mult(buff1,xmmu,1,size,size,1); det = Matrix_Det(cov,size,NO); /* det_1D(cov,size,&det); */ density = size * LOG2PI + LOG(det) + buff2[0]; density /= -2.; /* density = (1./(POW(2.*PI,size/2.)*SQRT(FABS(det)))) * EXP(-0.5*buff2[0]); */ Free(xmmu); Free(invcov); Free(buff1); Free(buff2); return (_log)?(density):(EXP(density)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dnorm_Multi_Given_InvCov_Det(phydbl *x, phydbl *mu, phydbl *invcov, phydbl log_det, int size, int _log) { phydbl *xmmu; phydbl *buff1,*buff2; int i; phydbl density; xmmu = (phydbl *)mCalloc(size,sizeof(phydbl)); For(i,size) xmmu[i] = x[i] - mu[i]; buff1 = Matrix_Mult(xmmu,invcov,1,size,size,size); buff2 = Matrix_Mult(buff1,xmmu,1,size,size,1); density = size * LOG2PI + log_det + buff2[0]; density /= -2.; Free(xmmu); Free(buff1); Free(buff2); return (_log)?(density):(EXP(density)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Pbinom(int N, int ni, phydbl p) { return Bico(N,ni)*POW(p,ni)*POW(1-p,N-ni); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Bivariate_Normal_Density(phydbl x, phydbl y, phydbl mux, phydbl muy, phydbl sdx, phydbl sdy, phydbl rho) { phydbl cx, cy; phydbl pi; phydbl dens; phydbl rho2; pi = 3.141593; cx = x - mux; cy = y - muy; rho2 = rho*rho; dens = 1./(2*pi*sdx*sdy*SQRT(1.-rho2)); dens *= EXP((-1./(2.*(1.-rho2)))*(cx*cx/(sdx*sdx)+cy*cy/(sdy*sdy)+2*rho*cx*cy/(sdx*sdy))); return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // E(X) = n(1-p)/p ; V(X) = n(1-p)/p^2 phydbl Dnbinom(phydbl x, phydbl n, phydbl p, int logit) { phydbl lnDens = LnGamma(x+n) - LnGamma(n) - LnFact(x) + n*LOG(p) + x*LOG(1.-p); if(logit == TRUE) { return(lnDens); } else { return(EXP(lnDens)); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Rnbinom(phydbl n, phydbl p) { phydbl y,x; y = Rgamma(n,(1.-p)/p); x = Rpois(y); return(x); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dgamma_Moments(phydbl x, phydbl mean, phydbl var) { phydbl shape, scale; if(var < 1.E-20) { /* var = 1.E-20; */ PhyML_Printf("\n. var=%f mean=%f",var,mean); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(mean < 1.E-20) { /* mean = 1.E-20; */ PhyML_Printf("\n. var=%f mean=%f",var,mean); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } shape = mean * mean / var; scale = var / mean; return(Dgamma(x,shape,scale)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Dgamma(phydbl x, phydbl shape, phydbl scale) { phydbl v; if(x > INFINITY) { PhyML_Printf("\n. WARNING: huge value of x -> x = %G",x); x = 1.E+10; } if(x < 1.E-20) { if(x < 0.0) return 0.0; else { PhyML_Printf("\n. WARNING: small value of x -> x = %G",x); x = 1.E-20; } } if(scale < 0.0 || shape < 0.0) { PhyML_Printf("\n. scale=%f shape=%f",scale,shape); Exit("\n"); } v = (shape-1.) * LOG(x) - shape * LOG(scale) - x / scale - LnGamma(shape); if(v < 500.) { v = EXP(v); } else { PhyML_Printf("\n. WARNING v=%f x=%f shape=%f scale=%f",v,x,shape,scale); PhyML_Printf("\n. LOG(x) = %G LnGamma(shape)=%G",LOG(x),LnGamma(shape)); v = EXP(v); /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ } return v; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Dexp(phydbl x, phydbl param) { return param * EXP(-param * x); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Returns the density of an exponential distribution left-truncated */ /* at 'left' and right-truncated at 'rght' */ phydbl Dexp_Trunc(phydbl x, phydbl lambda, phydbl left, phydbl rght) { return (lambda * EXP(-lambda * x))/(EXP(-lambda * left) - EXP(-lambda * rght)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Poisson probability */ phydbl Dpois(phydbl x, phydbl param, int logit) { phydbl v; if(x < .0) { if(logit == YES) return(-INFINITY); else return 0.0; } v = x * LOG(param) - param - Factln(x); if(logit == YES) return v; else { if(v < 500.) { v = EXP(v); } else { PhyML_Printf("\n. WARNING v=%f x=%f param=%f",v,x,param); v = EXP(500); } /* PhyML_Printf("\n. Poi %f %f (x=%f param=%f)", */ /* v, */ /* POW(param,x) * EXP(-param) / EXP(LnGamma(x+1)), */ /* x,param); */ /* return POW(param,x) * EXP(-param) / EXP(LnGamma(x+1)); */ return v; } return(-1.0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* CDFs */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Pnorm(phydbl x, phydbl mean, phydbl sd) { /* const phydbl b1 = 0.319381530; */ /* const phydbl b2 = -0.356563782; */ /* const phydbl b3 = 1.781477937; */ /* const phydbl b4 = -1.821255978; */ /* const phydbl b5 = 1.330274429; */ /* const phydbl p = 0.2316419; */ /* const phydbl c = 0.39894228; */ x = (x-mean)/sd; /* if(x >= 0.0) */ /* { */ /* phydbl t = 1.0 / ( 1.0 + p * x ); */ /* return (1.0 - c * EXP( -x * x / 2.0 ) * t * */ /* ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 )); */ /* } */ /* else */ /* { */ /* phydbl t = 1.0 / ( 1.0 - p * x ); */ /* return ( c * EXP( -x * x / 2.0 ) * t * */ /* ( t *( t * ( t * ( t * b5 + b4 ) + b3 ) + b2 ) + b1 )); */ /* } */ /* i_tail in {0,1,2} means: "lower", "upper", or "both" : if(lower) return *cum := P[X <= x] if(upper) return *ccum := P[X > x] = 1 - P[X <= x] */ /* return Pnorm_Marsaglia(x); */ return Pnorm_Ihaka_Derived_From_Cody(x); } /* G. Marsaglia. "Evaluating the Normal distribution". Journal of Statistical Software. 2004. Vol. 11. Issue 4. */ phydbl Pnorm_Marsaglia(phydbl x) { long double s=x,t=0,b=x,q=x*x,i=1; while(s!=t) s=(t=s)+(b*=q/(i+=2)); return .5+s*exp(-.5*q-.91893853320467274178L); } /* Stolen from R source code */ #define SIXTEN 16 phydbl Pnorm_Ihaka_Derived_From_Cody(phydbl x) { const static double a[5] = { 2.2352520354606839287, 161.02823106855587881, 1067.6894854603709582, 18154.981253343561249, 0.065682337918207449113 }; const static double b[4] = { 47.20258190468824187, 976.09855173777669322, 10260.932208618978205, 45507.789335026729956 }; const static double c[9] = { 0.39894151208813466764, 8.8831497943883759412, 93.506656132177855979, 597.27027639480026226, 2494.5375852903726711, 6848.1904505362823326, 11602.651437647350124, 9842.7148383839780218, 1.0765576773720192317e-8 }; const static double d[8] = { 22.266688044328115691, 235.38790178262499861, 1519.377599407554805, 6485.558298266760755, 18615.571640885098091, 34900.952721145977266, 38912.003286093271411, 19685.429676859990727 }; const static double p[6] = { 0.21589853405795699, 0.1274011611602473639, 0.022235277870649807, 0.001421619193227893466, 2.9112874951168792e-5, 0.02307344176494017303 }; const static double q[5] = { 1.28426009614491121, 0.468238212480865118, 0.0659881378689285515, 0.00378239633202758244, 7.29751555083966205e-5 }; double xden, xnum, temp, del, eps, xsq, y; int i, lower, upper; double cum,ccum; int i_tail; i_tail = 0; cum = ccum = 0.0; if(isnan(x)) { cum = ccum = x; return (phydbl)cum; } /* Consider changing these : */ eps = DBL_EPSILON * 0.5; /* i_tail in {0,1,2} =^= {lower, upper, both} */ lower = i_tail != 1; upper = i_tail != 0; y = fabs(x); if (y <= 0.67448975) { /* qnorm(3/4) = .6744.... -- earlier had 0.66291 */ if (y > eps) { xsq = x * x; xnum = a[4] * xsq; xden = xsq; for (i = 0; i < 3; ++i) { xnum = (xnum + a[i]) * xsq; xden = (xden + b[i]) * xsq; } } else xnum = xden = 0.0; temp = x * (xnum + a[3]) / (xden + b[3]); if(lower) cum = 0.5 + temp; if(upper) ccum = 0.5 - temp; } else if (y <= M_SQRT_32) { /* Evaluate pnorm for 0.674.. = qnorm(3/4) < |x| <= SQRT(32) ~= 5.657 */ xnum = c[8] * y; xden = y; for (i = 0; i < 7; ++i) { xnum = (xnum + c[i]) * y; xden = (xden + d[i]) * y; } temp = (xnum + c[7]) / (xden + d[7]); #define do_del(X) \ xsq = floor(X * SIXTEN) / SIXTEN; \ del = (X - xsq) * (X + xsq); \ cum = exp(-xsq * xsq * 0.5) * exp(-del * 0.5) * temp; \ ccum = 1.0 - cum; \ #define swap_tail \ if (x > 0.) {/* swap ccum <--> cum */ \ temp = cum; if(lower) cum = ccum; ccum = temp; \ } do_del(y); swap_tail; } /* else |x| > SQRT(32) = 5.657 : * the next two case differentiations were really for lower=T, log=F * Particularly *not* for log_p ! * Cody had (-37.5193 < x && x < 8.2924) ; R originally had y < 50 * * Note that we do want symmetry(0), lower/upper -> hence use y */ else if((lower && -37.5193 < x && x < 8.2924) || (upper && -8.2924 < x && x < 37.5193)) { /* Evaluate pnorm for x in (-37.5, -5.657) union (5.657, 37.5) */ xsq = 1.0 / (x * x); xnum = p[5] * xsq; xden = xsq; for (i = 0; i < 4; ++i) { xnum = (xnum + p[i]) * xsq; xden = (xden + q[i]) * xsq; } temp = xsq * (xnum + p[4]) / (xden + q[4]); temp = (M_1_SQRT_2_PI - temp) / y; do_del(x); swap_tail; } else { /* no log_p , large x such that probs are 0 or 1 */ if(x > 0) { cum = 1.; ccum = 0.; } else { cum = 0.; ccum = 1.; } } return (phydbl)cum; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Pgamma(phydbl x, phydbl shape, phydbl scale) { return IncompleteGamma(x/scale,shape,LnGamma(shape)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Ppois(phydbl x, phydbl param) { /* Press et al. (1990) approximation of the CDF for the Poisson distribution */ if(param < SMALL || x < 0.0) { PhyML_Printf("\n== param = %G x=%G",param,x); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } return IncompleteGamma(x,param,LnGamma(param)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Inverse CDFs */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl PointChi2 (phydbl prob, phydbl v) { /* returns z so that Prob{x.999998 || v<=0) return ((phydbl)-1); g = (double)LnGamma(v/2); xx=v/2; c=xx-1; if (v >= -1.24*log(p)) goto l1; ch=pow((p*xx*exp(g+xx*aa)), 1/xx); if (ch-e<0) return (ch); goto l4; l1: if (v>.32) goto l3; ch=0.4; a=log(1-p); l2: q=ch; p1=1+ch*(4.67+ch); p2=ch*(6.73+ch*(6.66+ch)); t=-0.5+(4.67+2*ch)/p1 - (6.73+ch*(13.32+3*ch))/p2; ch-=(1-exp(a+g+.5*ch+c*aa)*p2/p1)/t; if (fabs(q/ch-1)-.01 <= 0) goto l4; else goto l2; l3: x=(double)PointNormal (p); p1=0.222222/v; ch=v*pow((x*sqrt(p1)+1-p1), 3.0); if (ch>2.2*v+6) ch=-2*(log(1-p)-c*log(.5*ch)+g); l4: q=ch; p1=.5*ch; if ((t=(double)IncompleteGamma (p1, xx, g))<0) { PhyML_Printf ("\nerr IncompleteGamma"); return ((phydbl)-1.); } p2=p-t; t=p2*exp(xx*aa+g+p1-c*log(ch)); b=t/ch; a=0.5*t-b*c; s1=(210+a*(140+a*(105+a*(84+a*(70+60*a))))) / 420; s2=(420+a*(735+a*(966+a*(1141+1278*a))))/2520; s3=(210+a*(462+a*(707+932*a)))/2520; s4=(252+a*(672+1182*a)+c*(294+a*(889+1740*a)))/5040; s5=(84+264*a+c*(175+606*a))/2520; s6=(120+c*(346+127*c))/5040; ch+=t*(1+0.5*t*s1-b*c*(s1-b*(s2-b*(s3-b*(s4-b*(s5-b*s6)))))); if (FABS(q/ch-1) > e) goto l4; return (phydbl)(ch); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* The following function was extracted from the source code of R. It implements the methods referenced below. * REFERENCE * * Beasley, J. D. and S. G. Springer (1977). * Algorithm AS 111: The percentage points of the normal distribution, * Applied Statistics, 26, 118-121. * * Wichura, M.J. (1988). * Algorithm AS 241: The Percentage Points of the Normal Distribution. * Applied Statistics, 37, 477-484. */ phydbl PointNormal (phydbl prob) { /* returns z so that Prob{x 0) */ /* r = 1-p;/\* 1-p *\/ */ /* else */ /* r = p_;/\* = R_DT_Iv(p) ^= p *\/ */ /* r = sqrt(-log(r)); */ /* /\* r = sqrt(-log(r)) <==> min(p, 1-p) = exp( - r^2 ) *\/ */ /* if (r <= 5.) { /\* <==> min(p,1-p) >= exp(-25) ~= 1.3888e-11 *\/ */ /* r += -1.6; */ /* val = (((((((r * 7.7454501427834140764e-4 + */ /* .0227238449892691845833) * r + .24178072517745061177) * */ /* r + 1.27045825245236838258) * r + */ /* 3.64784832476320460504) * r + 5.7694972214606914055) * */ /* r + 4.6303378461565452959) * r + */ /* 1.42343711074968357734) */ /* / (((((((r * */ /* 1.05075007164441684324e-9 + 5.475938084995344946e-4) * */ /* r + .0151986665636164571966) * r + */ /* .14810397642748007459) * r + .68976733498510000455) * */ /* r + 1.6763848301838038494) * r + */ /* 2.05319162663775882187) * r + 1.); */ /* } */ /* else */ /* { /\* very close to 0 or 1 *\/ */ /* r += -5.; */ /* val = (((((((r * 2.01033439929228813265e-7 + */ /* 2.71155556874348757815e-5) * r + */ /* .0012426609473880784386) * r + .026532189526576123093) * */ /* r + .29656057182850489123) * r + */ /* 1.7848265399172913358) * r + 5.4637849111641143699) * */ /* r + 6.6579046435011037772) */ /* / (((((((r * */ /* 2.04426310338993978564e-15 + 1.4215117583164458887e-7)* */ /* r + 1.8463183175100546818e-5) * r + */ /* 7.868691311456132591e-4) * r + .0148753612908506148525) */ /* * r + .13692988092273580531) * r + */ /* .59983220655588793769) * r + 1.); */ /* } */ /* if(q < 0.0) */ /* val = -val; */ /* /\* return (q >= 0.)? r : -r ;*\/ */ /* } */ /* return (phydbl)val; */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* MISCs */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Bico(int n, int k) { return FLOOR(0.5+EXP(Factln(n)-Factln(k)-Factln(n-k))); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Factln(int n) { static phydbl a[101]; if (n < 0) { Warn_And_Exit("\n== Err: negative factorial in routine FACTLN"); } if (n <= 1) return 0.0; if (n <= 100) return (a[n]>SMALL) ? a[n] : (a[n]=Gammln(n+1.0)); else return Gammln(n+1.0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Gammln(phydbl xx) { double x,tmp,ser; static double cof[6]={76.18009173,-86.50532033,24.01409822, -1.231739516,0.120858003e-2,-0.536382e-5}; int j; x=xx-1.0; tmp=x+5.5; tmp -= (x+0.5)*log(tmp); ser=1.0; for (j=0;j<=5;j++) { x += 1.0; ser += cof[j]/x; } return (phydbl)(-tmp+log(2.50662827465*ser)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* void Plim_Binom(phydbl pH0, int N, phydbl *pinf, phydbl *psup) */ /* { */ /* *pinf = pH0 - 1.64*SQRT(pH0*(1-pH0)/(phydbl)N); */ /* if(*pinf < 0) *pinf = .0; */ /* *psup = pH0 + 1.64*SQRT(pH0*(1-pH0)/(phydbl)N); */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl LnGamma (phydbl alpha) { /* returns ln(gamma(alpha)) for alpha>0, accurate to 10 decimal places. Stirling's formula is used for the central polynomial part of the procedure. Pike MC & Hill ID (1966) Algorithm 291: Logarithm of the gamma function. Communications of the Association for Computing Machinery, 9:684 */ double x=alpha, f=0, z; if (x<7) { f=1; z=x-1; while (++z<7) f*=z; x=z; f=-log(f); } z = 1/(x*x); return (phydbl)(f + (x-0.5)*log(x) - x + .918938533204673 + (((-.000595238095238*z+.000793650793651)*z-.002777777777778)*z +.083333333333333)/x); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl IncompleteGamma(phydbl x, phydbl alpha, phydbl ln_gamma_alpha) { /* returns the incomplete gamma ratio I(x,alpha) where x is the upper limit of the integration and alpha is the shape parameter. returns (-1) if in error ln_gamma_alpha = ln(Gamma(alpha)), is almost redundant. (1) series expansion if (alpha>x || x<=1) (2) continued fraction otherwise RATNEST FORTRAN by Bhattacharjee GP (1970) The incomplete gamma integral. Applied Statistics, 19: 285-287 (AS32) */ int i; double p=alpha, g=ln_gamma_alpha; double accurate=1e-8, overflow=1e30; double factor, gin=0, rn=0, a=0,b=0,an=0,dif=0, term=0, pn[6]; if (fabs(x) < SMALL) return ((phydbl).0); if (x<0 || p<=0) return ((phydbl)-1); factor=exp(p*log(x)-x-g); if (x>1 && x>=p) goto l30; /* (1) series expansion */ gin=1; term=1; rn=p; l20: rn++; term*=x/rn; gin+=term; if (term > accurate) goto l20; gin*=factor/p; goto l50; l30: /* (2) continued fraction */ a=1-p; b=a+x+1; term=0; pn[0]=1; pn[1]=x; pn[2]=x+1; pn[3]=x*b; gin=pn[2]/pn[3]; l32: a++; b+=2; term++; an=a*term; for (i=0; i<2; i++) pn[i+4]=b*pn[i+2]-an*pn[i]; if (fabs(pn[5]) < .0) goto l35; rn=pn[4]/pn[5]; dif=fabs(gin-rn); if (dif>accurate) goto l34; if (dif<=accurate*rn) goto l42; l34: gin=rn; l35: for (i=0; i<4; i++) pn[i]=pn[i+2]; if (fabs(pn[4]) < overflow) goto l32; for (i=0; i<4; i++) pn[i]/=overflow; goto l32; l42: gin=1-factor*gin; l50: return (phydbl)(gin); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int DiscreteGamma (phydbl freqK[], phydbl rK[], phydbl alfa, phydbl beta, int K, int median) { /* discretization of gamma distribution with equal proportions in each category */ int i; phydbl gap05=1.0/(2.0*K), t, factor=alfa/beta*K, lnga1; if(K==1) { freqK[0] = 1.0; rK[0] = 1.0; return 0; } if (median) { for (i=0; i n) return(0); if (k > n/2) k = n-k; if(!k) return(1); accum = 1.; for(i=1;in_otu-3; cov = (phydbl *)mCalloc(dim*dim,sizeof(phydbl)); mean = (phydbl *)mCalloc( dim,sizeof(phydbl)); ori_wght = (int *)mCalloc(tree->data->crunch_len,sizeof(int)); site_num = (int *)mCalloc(tree->data->init_len,sizeof(int)); For(i,tree->data->crunch_len) ori_wght[i] = tree->data->wght[i]; n_site = 0; For(i,tree->data->crunch_len) For(j,tree->data->wght[i]) { site_num[n_site] = i; n_site++; } tree->mod->s_opt->print = 0; For(replicate,sample_size) { For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = .1; For(i,tree->data->crunch_len) tree->data->wght[i] = 0; For(i,tree->data->init_len) { position = Rand_Int(0,(int)(tree->data->init_len-1.0)); tree->data->wght[site_num[position]] += 1; } Round_Optimize(tree,tree->data,ROUND_MAX); For(i,2*tree->n_otu-3) For(j,2*tree->n_otu-3) cov[i*dim+j] += LOG(tree->a_edges[i]->l->v) * LOG(tree->a_edges[j]->l->v); For(i,2*tree->n_otu-3) mean[i] += LOG(tree->a_edges[i]->l->v); PhyML_Printf("[%3d/%3d]",replicate,sample_size); fflush(NULL); /* PhyML_Printf("\n. %3d %12f %12f %12f ", */ /* replicate, */ /* cov[1*dim+1]/(replicate+1)-mean[1]*mean[1]/POW(replicate+1,2), */ /* tree->a_edges[1]->l->v, */ /* mean[1]/(replicate+1)); */ } For(i,2*tree->n_otu-3) mean[i] /= (phydbl)sample_size; For(i,2*tree->n_otu-3) For(j,2*tree->n_otu-3) cov[i*dim+j] /= (phydbl)sample_size; For(i,2*tree->n_otu-3) For(j,2*tree->n_otu-3) cov[i*dim+j] -= mean[i]*mean[j]; /* For(i,2*tree->n_otu-3) if(cov[i*dim+i] < var_min) cov[i*dim+i] = var_min; */ /* PhyML_Printf("\n"); */ /* For(i,2*tree->n_otu-3) PhyML_Printf("%f %f\n",mean[i],tree->a_edges[i]->l->v); */ /* PhyML_Printf("\n"); */ /* PhyML_Printf("\n"); */ /* For(i,2*tree->n_otu-3) */ /* { */ /* For(j,2*tree->n_otu-3) */ /* { */ /* PhyML_Printf("%G\n",cov[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ For(i,tree->data->crunch_len) tree->data->wght[i] = ori_wght[i]; Free(mean); Free(ori_wght); Free(site_num); return cov; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Work out the Hessian for the likelihood function. Only branch lengths are considered as variable. This function is very much inspired from Jeff Thorne's 'hessian' function in his program 'estbranches'. */ phydbl *Hessian(t_tree *tree) { phydbl *hessian; phydbl *plus_plus, *minus_minus, *plus_zero, *minus_zero, *plus_minus, zero_zero; phydbl *ori_bl,*inc,*buff; int *ok_edges,*is_ok; int dim; int n_ok_edges; int i,j; phydbl eps; phydbl lk; phydbl lnL,lnL1,lnL2,ori_lnL; phydbl l_inf; dim = 2*tree->n_otu-3; eps = (tree->mod->log_l == YES)?(0.2):(1E-4); hessian = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); ori_bl = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); plus_plus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); minus_minus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); plus_minus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); plus_zero = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); minus_zero = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); inc = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); buff = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); ok_edges = (int *)mCalloc((int)dim,sizeof(int)); is_ok = (int *)mCalloc((int)dim,sizeof(int)); lnL = lnL1 = lnL2 = UNLIKELY; Set_Both_Sides(YES,tree); Lk(NULL,tree); ori_lnL = tree->c_lnL; For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v; if(tree->mod->log_l == NO) l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len); else l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len)); n_ok_edges = 0; For(i,dim) { if(tree->a_edges[i]->l->v*(1.-eps) > l_inf) { inc[i] = eps * tree->a_edges[i]->l->v; ok_edges[n_ok_edges] = i; n_ok_edges++; is_ok[i] = 1; } else { inc[i] = -1.0; is_ok[i] = 0; } } /* Fine tune the increments */ For(i,dim) { do { tree->a_edges[i]->l->v += inc[i]; lnL1 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v = ori_bl[i]; inc[i] *= 1.1; }while((FABS(lnL1 - ori_lnL) < 1.E-1) && (tree->a_edges[i]->l->v+inc[i] < tree->mod->l_max)); inc[i] /= 1.1; } /* zero zero */ zero_zero = tree->c_lnL; /* plus zero */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; lk = Lk(tree->a_edges[i],tree); plus_zero[i] = lk; tree->a_edges[i]->l->v = ori_bl[i]; } } /* minus zero */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v -= inc[i]; lk = Lk(tree->a_edges[i],tree); minus_zero[i] = lk; tree->a_edges[i]->l->v = ori_bl[i]; } } For(i,dim) Update_PMat_At_Given_Edge(tree->a_edges[i],tree); /* plus plus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],1,inc,plus_plus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],1,inc,plus_plus+i*dim,is_ok,tree); tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } /* plus minus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,plus_minus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,plus_minus+i*dim,is_ok,tree); tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } /* minus minus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v -= inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,minus_minus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,minus_minus+i*dim,is_ok,tree); tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } For(i,dim) { if(is_ok[i]) { hessian[i*dim+i] = (plus_zero[i]-2*zero_zero+minus_zero[i])/(POW(inc[i],2)); for(j=i+1;jdata->init_len; */ /* Approximate variance for very short branches */ For(i,dim) if(inc[i] < 0.0 || hessian[i*dim+i] < MIN_VAR_BL) { eps = 0.2 * tree->a_edges[i]->l->v; do { lnL = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v += eps; lnL1 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v += eps; lnL2 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v -= 2.*eps; hessian[i*dim+i] = (lnL2 - 2.*lnL1 + lnL) / POW(eps,2); /* printf("\n* l=%G eps=%f lnL=%f lnL1=%f lnL2=%f var=%f",tree->a_edges[i]->l->v,eps,lnL,lnL1,lnL2,hessian[i*dim+i]); */ eps *= 5.; }while(FABS(lnL2 - lnL) < 1.E-3); hessian[i*dim+i] = -1.0 / hessian[i*dim+i]; } /* Fit a straight line to the log-likelihood (i.e., an exponential to the likelihood) */ /* It is only a straight line when considering branch length (rather than log(branch lengths)) */ For(i,dim) if((tree->a_edges[i]->l->v / tree->mod->l_min < 1.1) && (tree->a_edges[i]->l->v / tree->mod->l_min > 0.9)) { phydbl *x,*y,l; phydbl cov,var; x=plus_plus; y=minus_minus; l=(tree->mod->log_l == YES)?(EXP(tree->a_edges[i]->l->v)):(tree->a_edges[i]->l->v); /* Get actual branch length */ For(j,dim) { x[j] = l + (100.*l-l)*((phydbl)j/dim); tree->a_edges[i]->l->v = (tree->mod->log_l)?(LOG(x[j])):(x[j]); /* Transform to log if necessary */ y[j] = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v = (tree->mod->log_l)?(LOG(l)):(l); /* Go back to initial edge length */ } cov = Covariance(x,y,dim); var = Covariance(x,x,dim); /* cov/var is minus the parameter of the exponential distribution. The variance is therefore : */ hessian[i*dim+i] = 1.0 / pow(cov/var,2); /* printf("\n. Hessian = %G cov=%G var=%G",hessian[i*dim+i],cov,var); */ } /* } */ For(i,dim) if(hessian[i*dim+i] < 0.0) { PhyML_Printf("\n. l=%G var=%G",tree->a_edges[i]->l->v,hessian[i*dim+i]); /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ hessian[i*dim+i] = MIN_VAR_BL; } For(i,dim) { if(hessian[i*dim+i] < MIN_VAR_BL) { PhyML_Printf("\n. l=%10G var(l)=%12G. WARNING: numerical precision issues may affect this analysis.", tree->a_edges[i]->l->v,hessian[i*dim+i]); hessian[i*dim+i] = MIN_VAR_BL; } if(hessian[i*dim+i] > MAX_VAR_BL) { PhyML_Printf("\n. l=%10G var(l)=%12G. WARNING: numerical precision issues may affect this analysis.", tree->a_edges[i]->l->v,hessian[i*dim+i]); hessian[i*dim+i] = MAX_VAR_BL; } } Iter_Matinv(hessian,dim,dim,NO); For(i,dim*dim) hessian[i] = -1.0*hessian[i]; For(i,dim) { For(j,dim) { if(FABS(hessian[i*dim+j]-hessian[j*dim+i]) > 1.E-3) { PhyML_Printf("\n. Hessian not symmetrical."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } hessian[i*dim+j] = (hessian[i*dim+j] + hessian[j*dim+i]) / 2.; hessian[j*dim+i] = hessian[i*dim+j]; } } /* printf("\n"); */ /* printf("HESSIAN\n"); */ /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */ /* For(j,dim) */ /* { */ /* PhyML_Printf("%12lf ",hessian[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ /* Matinv(hessian,dim,dim,NO); */ /* PhyML_Printf("\n"); */ /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */ /* For(j,dim) */ /* { */ /* PhyML_Printf("%12G ",-hessian[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ /* Exit("\n"); */ /* Make sure to update likelihood before bailing out */ Set_Both_Sides(YES,tree); Lk(NULL,tree); Free(ori_bl); Free(plus_plus); Free(minus_minus); Free(plus_zero); Free(minus_zero); Free(plus_minus); Free(inc); Free(buff); Free(ok_edges); Free(is_ok); return hessian; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Work out the gradient for the likelihood function. Only branch lengths are considered as variable. */ phydbl *Gradient(t_tree *tree) { phydbl *gradient; phydbl *plus, *minus; phydbl *ori_bl,*inc; int *is_ok; int dim; int i; phydbl eps; phydbl lk; phydbl lnL,lnL1,lnL2; phydbl l_inf; dim = 2*tree->n_otu-3; eps = (tree->mod->log_l == YES)?(0.2):(1.E-6); gradient = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); ori_bl = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); plus = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); minus = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); inc = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); is_ok = (int *)mCalloc((int)dim,sizeof(int)); lnL = lnL1 = lnL2 = UNLIKELY; Set_Both_Sides(YES,tree); Lk(NULL,tree); For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v; if(tree->mod->log_l == NO) l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len); else l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len)); For(i,dim) { if(tree->a_edges[i]->l->v*(1.-eps) > l_inf) { inc[i] = eps * tree->a_edges[i]->l->v; is_ok[i] = YES; } else { inc[i] = -1.0; is_ok[i] = NO; } } /* plus */ For(i,dim) { if(is_ok[i] == YES) { tree->a_edges[i]->l->v += inc[i]; lk = Lk(tree->a_edges[i],tree); plus[i] = lk; tree->a_edges[i]->l->v = ori_bl[i]; } } /* minus */ For(i,dim) { if(is_ok[i] == YES) { tree->a_edges[i]->l->v -= inc[i]; lk = Lk(tree->a_edges[i],tree); minus[i] = lk; tree->a_edges[i]->l->v = ori_bl[i]; } } For(i,dim) { if(is_ok[i] == YES) { gradient[i] = (plus[i] - minus[i])/(2.*inc[i]); } } For(i,dim) { if(is_ok[i] == NO) { eps = FABS(0.2 * tree->a_edges[i]->l->v); lnL = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v += eps; lnL1 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v += eps; lnL2 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v -= eps; tree->a_edges[i]->l->v -= eps; gradient[i] = (4.*lnL1 - lnL2 - 3.*lnL) / (2.*eps); } } /* Make sure to update likelihood before bailing out */ Set_Both_Sides(YES,tree); Lk(NULL,tree); Free(ori_bl); Free(plus); Free(minus); Free(inc); Free(is_ok); /* printf("\n"); */ /* printf("GRADIENT\n"); */ /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */ /* For(j,dim) */ /* { */ /* printf("%12lf ",gradient[i]*gradient[j]); */ /* } */ /* printf("\n"); */ /* } */ /* printf("\n"); */ /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] [%f]\n",tree->a_edges[i]->l->v,gradient[i]); */ /* } */ /* Exit("\n"); */ return gradient; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Work out the Hessian for the likelihood function using the method described by Seo et al., 2004, MBE. Corresponds to the outer product of the scores approach described in Porter, 2002. (matrix J1) */ phydbl *Hessian_Seo(t_tree *tree) { phydbl *hessian,*site_hessian; phydbl *gradient; phydbl *plus, *minus, *plusplus, *zero; phydbl *ori_bl,*inc_plus,*inc_minus,*inc; int *is_ok; int dim; int i,j,k; phydbl eps; phydbl ori_lnL,lnL1,lnL2; phydbl l_inf; int l,n; phydbl small_var; dim = 2*tree->n_otu-3; eps = (tree->mod->log_l == YES)?(0.2):(1.E-4); hessian = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); site_hessian = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); gradient = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); ori_bl = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); plus = (phydbl *)mCalloc((int)dim*tree->n_pattern,sizeof(phydbl)); plusplus = (phydbl *)mCalloc((int)dim*tree->n_pattern,sizeof(phydbl)); minus = (phydbl *)mCalloc((int)dim*tree->n_pattern,sizeof(phydbl)); zero = (phydbl *)mCalloc((int)dim*tree->n_pattern,sizeof(phydbl)); inc_plus = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); inc_minus = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); inc = (phydbl *)mCalloc((int)dim,sizeof(phydbl)); is_ok = (int *)mCalloc((int)dim,sizeof(int)); lnL1 = lnL2 = UNLIKELY; For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v; Set_Both_Sides(YES,tree); Lk(NULL,tree); ori_lnL = tree->c_lnL; if(tree->mod->log_l == NO) l_inf = MAX(tree->mod->l_min,1./(phydbl)tree->data->init_len); else l_inf = MAX(tree->mod->l_min,-LOG((phydbl)tree->data->init_len)); For(i,dim) { if(tree->a_edges[i]->l->v*(1.-eps) > l_inf) { inc_plus[i] = FABS(eps * MAX(tree->mod->l_min,tree->a_edges[i]->l->v)); inc_minus[i] = FABS(eps * MAX(tree->mod->l_min,tree->a_edges[i]->l->v)); is_ok[i] = YES; } else { inc_plus[i] = FABS(0.2 * MAX(tree->mod->l_min,tree->a_edges[i]->l->v)); inc_minus[i] = FABS(0.2 * MAX(tree->mod->l_min,tree->a_edges[i]->l->v)); is_ok[i] = NO; } } /* Fine tune the increments */ For(i,dim) { do { tree->a_edges[i]->l->v += inc_plus[i]; lnL1 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v = ori_bl[i]; inc_plus[i] *= 1.1; }while((FABS(lnL1 - ori_lnL) < 1.E-1) && (tree->a_edges[i]->l->v+inc_plus[i] < tree->mod->l_max)); inc_plus[i] /= 1.1; } For(i,dim) { do { tree->a_edges[i]->l->v -= inc_minus[i]; lnL1 = Lk(tree->a_edges[i],tree); tree->a_edges[i]->l->v = ori_bl[i]; inc_minus[i] *= 1.1; }while((FABS(lnL1 - ori_lnL) < 1.E-1) && (tree->a_edges[i]->l->v -inc_minus[i] > tree->mod->l_min)); inc_minus[i] /= 1.1; } For(i,dim) { inc[i] = MIN(inc_plus[i],inc_minus[i]); } /* plus */ For(i,dim) { if(is_ok[i] == YES) { tree->a_edges[i]->l->v += inc[i]; Lk(tree->a_edges[i],tree); For(j,tree->n_pattern) plus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]); tree->a_edges[i]->l->v = ori_bl[i]; } } /* minus */ For(i,dim) { if(is_ok[i] == YES) { tree->a_edges[i]->l->v -= inc[i]; Lk(tree->a_edges[i],tree); For(j,tree->n_pattern) minus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]); tree->a_edges[i]->l->v = ori_bl[i]; } } For(i,dim) { if(is_ok[i] == NO) { Lk(tree->a_edges[i],tree); For(j,tree->n_pattern) zero[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]); tree->a_edges[i]->l->v += inc[i]; lnL1 = Lk(tree->a_edges[i],tree); For(j,tree->n_pattern) plus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]); tree->a_edges[i]->l->v += inc[i]; lnL2 = Lk(tree->a_edges[i],tree); For(j,tree->n_pattern) plusplus[i*tree->n_pattern+j] = LOG(tree->cur_site_lk[j]); tree->a_edges[i]->l->v = ori_bl[i]; } } For(i,dim*dim) hessian[i] = 0.0; For(k,tree->n_pattern) { For(i,dim) { if(is_ok[i] == YES) gradient[i] = (plus[i*tree->n_pattern+k] - minus[i*tree->n_pattern+k])/(inc[i] + inc[i]); else gradient[i] = (4.*plus[i*tree->n_pattern+k] - plusplus[i*tree->n_pattern+k] - 3.*zero[i*tree->n_pattern+k])/(inc[i] + inc[i]); /* if(is_ok[i] == NO) */ /* printf("\n. i=%d site=%d l=%G plus=%G plusplus=%G zero=%G num=%f grad=%G", */ /* i,k,tree->a_edges[i]->l->v, */ /* plus[i*tree->n_pattern+k],plusplus[i*tree->n_pattern+k],zero[i*tree->n_pattern+k], */ /* (4.*plus[i*tree->n_pattern+k] - plusplus[i*tree->n_pattern+k] - 3.*zero[i*tree->n_pattern+k]), */ /* gradient[i]); */ } For(i,dim) For(j,dim) site_hessian[i*dim+j] = gradient[i] * gradient[j]; For(i,dim*dim) hessian[i] -= site_hessian[i] * tree->data->wght[k]; } /* Make sure to update likelihood before bailing out */ Set_Both_Sides(YES,tree); Lk(NULL,tree); l = tree->data->init_len; n = tree->mod->ns; /* Delta method for variance. Assumes Jukes and Cantor with p=1/n */ small_var = (1./(l*l))*(1.-1./l)*(n-1.)*(n-1.)/(n-1.-n/l); For(i,dim) if(is_ok[i] == NO) { For(j,dim) { hessian[i*dim+j] = 0.; hessian[j*dim+i] = 0.; } hessian[i*dim+i] = -1./small_var; if(tree->mod->log_l == YES) { hessian[i*dim+i] = small_var * POW(EXP(tree->a_edges[i]->l->v),-2); hessian[i*dim+i] = -1./hessian[i*dim+i]; } } For(i,dim) if(is_ok[i] == YES && hessian[i*dim+i] < -1./small_var) { For(j,dim) { hessian[i*dim+j] = 0.; hessian[j*dim+i] = 0.; } hessian[i*dim+i] = -1./small_var; if(tree->mod->log_l == YES) { hessian[i*dim+i] = small_var * POW(EXP(tree->a_edges[i]->l->v),-2); hessian[i*dim+i] = -1./hessian[i*dim+i]; } } For(i,dim) { For(j,dim) { if(FABS(hessian[i*dim+j]-hessian[j*dim+i]) > 1.E-3) { PhyML_Printf("\n== Hessian not symmetrical."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } hessian[i*dim+j] = (hessian[i*dim+j] + hessian[j*dim+i]) / 2.; hessian[j*dim+i] = hessian[i*dim+j]; } } /* printf("\n"); */ /* printf("HESSIAN SEO\n"); */ /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */ /* For(j,dim) */ /* { */ /* PhyML_Printf("%12lf ",hessian[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ Free(site_hessian); Free(ori_bl); Free(plus); Free(minus); Free(plusplus); Free(zero); Free(inc); Free(inc_plus); Free(inc_minus); Free(is_ok); Free(gradient); return hessian; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Recurr_Hessian(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *res, int *is_ok, t_tree *tree) { int i; phydbl ori_l; For(i,3) if(a->v[i] == d) { Update_P_Lk(tree,a->b[i],a); ori_l = a->b[i]->l->v; if(is_ok[a->b[i]->num]) { if(plus_minus > 0) a->b[i]->l->v += inc[a->b[i]->num]; else a->b[i]->l->v -= inc[a->b[i]->num]; res[a->b[i]->num] = Lk(a->b[i],tree); a->b[i]->l->v = ori_l; Update_PMat_At_Given_Edge(a->b[i],tree); } break; } if(d->tax) return; else For(i,3) if(d->v[i] != a) Recurr_Hessian(d,d->v[i],plus_minus,inc,res,is_ok,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Work out the Hessian for the likelihood function. Only LOGARITHM of branch lengths are considered as variable. This function is very much inspired from Jeff Thorne's 'hessian' function in his program 'estbranches'. */ phydbl *Hessian_Log(t_tree *tree) { phydbl *hessian; phydbl *plus_plus, *minus_minus, *plus_zero, *minus_zero, *plus_minus, *zero_zero; phydbl *ori_bl,*inc,*buff; int *ok_edges,*is_ok; int dim; int n_ok_edges; int i,j; phydbl eps; phydbl lk; dim = 2*tree->n_otu-3; eps = 1.E-4; hessian = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); ori_bl = (phydbl *)mCalloc((int)dim, sizeof(phydbl)); plus_plus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); minus_minus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); plus_minus = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); plus_zero = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); minus_zero = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); zero_zero = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); inc = (phydbl *)mCalloc((int)dim ,sizeof(phydbl)); buff = (phydbl *)mCalloc((int)dim*dim,sizeof(phydbl)); ok_edges = (int *)mCalloc((int)dim, sizeof(int)); is_ok = (int *)mCalloc((int)dim, sizeof(int)); Set_Both_Sides(YES,tree); Lk(NULL,tree); For(i,dim) ori_bl[i] = tree->a_edges[i]->l->v; n_ok_edges = 0; For(i,dim) { if(tree->a_edges[i]->l->v > 3.0/(phydbl)tree->data->init_len) { inc[i] = FABS(eps * tree->a_edges[i]->l->v); ok_edges[n_ok_edges] = i; n_ok_edges++; is_ok[i] = 1; } else is_ok[i] = 0; } /* zero zero */ lk = Log_Det(is_ok,tree); For(i,dim) if(is_ok[i]) zero_zero[i] = tree->c_lnL+lk; /* plus zero */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; lk = Lk(tree->a_edges[i],tree); plus_zero[i] = lk+Log_Det(is_ok,tree); tree->a_edges[i]->l->v = ori_bl[i]; } } /* minus zero */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v -= inc[i]; lk = Lk(tree->a_edges[i],tree); minus_zero[i] = lk+Log_Det(is_ok,tree); tree->a_edges[i]->l->v = ori_bl[i]; } } For(i,dim) Update_PMat_At_Given_Edge(tree->a_edges[i],tree); /* plus plus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],1,inc,plus_plus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],1,inc,plus_plus+i*dim,is_ok,tree); /* For(j,dim) */ /* if(j != i) */ /* { */ /* if(inc[j] > 0.0) */ /* { */ /* tree->a_edges[j]->l->v += inc[j]; */ /* Lk(tree); */ /* plus_plus[i*dim+j]=tree->c_lnL; */ /* tree->a_edges[j]->l->v = ori_bl[j]; */ /* } */ /* } */ tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } /* plus minus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v += inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,plus_minus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,plus_minus+i*dim,is_ok,tree); /* For(j,dim) */ /* if(j != i) */ /* { */ /* if(inc[j] > 0.0) */ /* { */ /* tree->a_edges[j]->l->v -= inc[j]; */ /* Lk(tree); */ /* plus_minus[i*dim+j] = tree->c_lnL; */ /* tree->a_edges[j]->l->v = ori_bl[j]; */ /* } */ /* } */ tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } /* minus minus */ For(i,dim) { if(is_ok[i]) { tree->a_edges[i]->l->v -= inc[i]; Update_PMat_At_Given_Edge(tree->a_edges[i],tree); For(j,3) if((!tree->a_edges[i]->left->tax) && (tree->a_edges[i]->left->v[j] != tree->a_edges[i]->rght)) Recurr_Hessian_Log(tree->a_edges[i]->left,tree->a_edges[i]->left->v[j],-1,inc,minus_minus+i*dim,is_ok,tree); For(j,3) if((!tree->a_edges[i]->rght->tax) && (tree->a_edges[i]->rght->v[j] != tree->a_edges[i]->left)) Recurr_Hessian_Log(tree->a_edges[i]->rght,tree->a_edges[i]->rght->v[j],-1,inc,minus_minus+i*dim,is_ok,tree); /* For(j,dim) */ /* if(j != i) */ /* { */ /* if(inc[j] > 0.0) */ /* { */ /* tree->a_edges[j]->l->v -= inc[j]; */ /* Lk(tree); */ /* minus_minus[i*dim+j] = tree->c_lnL; */ /* tree->a_edges[j]->l->v = ori_bl[j]; */ /* } */ /* } */ tree->a_edges[i]->l->v = ori_bl[i]; Lk(NULL,tree); } } /* For(i,dim) if(is_ok[i]) inc[i] = POW(tree->a_edges[i]->l->v+inc[i],2)-POW(tree->a_edges[i]->l->v,2); */ For(i,dim) if(is_ok[i]) inc[i] = LOG(tree->a_edges[i]->l->v+inc[i])-LOG(tree->a_edges[i]->l->v); /* For(i,dim) inc[i] = 2.*inc[i]; */ /* For(i,dim) if(is_ok[i]) inc[i] = SQRT(tree->a_edges[i]->l->v+inc[i])-SQRT(tree->a_edges[i]->l->v); */ For(i,dim) { if(is_ok[i]) { hessian[i*dim+i] = (plus_zero[i]-2*zero_zero[i]+minus_zero[i])/(POW(inc[i],2)); for(j=i+1;jdata->init_len,2); } if(!Matinv(hessian,dim,dim,NO)) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } For(i,dim*dim) hessian[i] = -1.0*hessian[i]; /* For(i,dim) */ /* { */ /* PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); */ /* For(j,i+1) */ /* { */ /* PhyML_Printf("%12lf ",hessian[i*dim+j]); */ /* } */ /* PhyML_Printf("\n"); */ /* } */ /* Matinv(hessian,dim,dim); */ /* PhyML_Printf("\n"); */ For(i,dim) { PhyML_Printf("[%f] ",tree->a_edges[i]->l->v); For(j,i+1) { PhyML_Printf("%12lf ",hessian[i*dim+j]); } PhyML_Printf("\n"); } /* Exit("\n"); */ Free(ori_bl); Free(plus_plus); Free(minus_minus); Free(plus_zero); Free(minus_zero); Free(plus_minus); Free(zero_zero); Free(inc); Free(buff); Free(ok_edges); Free(is_ok); return hessian; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Recurr_Hessian_Log(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *res, int *is_ok, t_tree *tree) { int i; phydbl ori_l; For(i,3) if(a->v[i] == d) { Update_P_Lk(tree,a->b[i],a); ori_l = a->b[i]->l->v; if(is_ok[a->b[i]->num]) { if(plus_minus > 0) a->b[i]->l->v += inc[a->b[i]->num]; else a->b[i]->l->v -= inc[a->b[i]->num]; res[a->b[i]->num] = Lk(a->b[i],tree); res[a->b[i]->num] += Log_Det(is_ok,tree); a->b[i]->l->v = ori_l; Update_PMat_At_Given_Edge(a->b[i],tree); } break; } if(d->tax) return; else For(i,3) if(d->v[i] != a) Recurr_Hessian_Log(d,d->v[i],plus_minus,inc,res,is_ok,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Log_Det(int *is_ok, t_tree *tree) { int i; phydbl ldet; ldet = 0.0; /* For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += LOG(2.*SQRT(tree->a_edges[i]->l->v)); */ For(i,2*tree->n_otu-3) if(is_ok[i]) ldet += LOG(tree->a_edges[i]->l->v); /* For(i,2*tree->n_otu-3) if(is_ok[i]) ldet -= LOG(2*tree->a_edges[i]->l->v); */ return ldet; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Normal_Trunc_Mean(phydbl mu, phydbl sd, phydbl min, phydbl max) { phydbl mean; mean = mu + sd * (Dnorm((min-mu)/sd,0.,1.)-Dnorm((max-mu)/sd,0.,1.))/ (Pnorm((max-mu)/sd,0.,1.)-Pnorm((min-mu)/sd,0.,1.)); return mean; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Constraint_Normal_Trunc_Mean(phydbl wanted_mu, phydbl sd, phydbl min, phydbl max) { int j; phydbl dx,f,fmid,xmid,rtb; phydbl x1, x2; x1 = min; x2 = max; f = Normal_Trunc_Mean(x1,sd,min,max) - wanted_mu; fmid = Normal_Trunc_Mean(x2,sd,min,max) - wanted_mu; if(f*fmid >= 0.0) { PhyML_Printf("\n. Root must be bracketed for bisection!"); PhyML_Printf("\n. f=%f fmid=%f",f,fmid); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } rtb = f < 0.0 ? (dx=x2-x1,x1) : (dx=x1-x2,x2); For(j,100) { xmid=rtb+(dx *= 0.5); fmid=Normal_Trunc_Mean(xmid,sd,min,max)-wanted_mu; if(fmid <= 0.0) rtb=xmid; if(fmid > -1.E-10 && fmid < 1.E-10) return rtb; } Exit("Too many bisections in RTBIS"); return(-1.); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Matinv(phydbl *x, int n, int m, int verbose) { /* x[n*m] ... m>=n */ int i,j,k; int *irow; phydbl ee, t,t1,xmax; phydbl det; ee = 1.0E-10; det = 1.0; irow = (int *)mCalloc(n,sizeof(int)); For (i,n) { xmax = 0.; for (j=i; j=0; i--) { if (irow[i] == i) continue; For(j,n) { t = x[j*m+i]; x[j*m+i] = x[j*m + irow[i]]; x[j*m + irow[i]] = t; } } Free(irow); return (1); /* int i, j, k, lower, upper; */ /* phydbl temp; */ /* phydbl *a; */ /* int nsize; */ /* nsize = n; */ /* a = x; */ /* /\*Gauss-Jordan reduction -- invert matrix a in place, */ /* overwriting previous contents of a. On exit, matrix a */ /* contains the inverse.*\/ */ /* lower = 0; */ /* upper = nsize-1; */ /* for(i = lower; i <= upper; i++) */ /* { */ /* temp = 1.0 / a[i*n+i]; */ /* a[i*n+i] = 1.0; */ /* for (j = lower; j <= upper; j++) */ /* { */ /* a[i*n+j] *= temp; */ /* } */ /* for (j = lower; j <= upper; j++) */ /* { */ /* if (j != i) */ /* { */ /* temp = a[j*n+i]; */ /* a[j*n+i] = 0.0; */ /* for (k = lower; k <= upper; k++) */ /* { */ /* a[j*n+k] -= temp * a[i*n+k]; */ /* } */ /* } */ /* } */ /* } */ return(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Iter_Matinv(phydbl *x, int n, int m, int verbose) { phydbl *buff; int i,iter; phydbl scaler; int pb; buff = (phydbl *)mCalloc(n*m,sizeof(phydbl)); pb = NO; iter = 0; scaler = 1.; For(i,n*m) buff[i] = x[i]; while(!Matinv(buff,n,m,verbose)) { pb = YES; For(i,n*m) buff[i] = x[i]; scaler *= 10.; For(i,n*m) buff[i] *= scaler; iter++; if(iter > 100) { PhyML_Printf("\n== Err in file %s at line %d.",__FILE__,__LINE__); return 0; } } if(pb) PhyML_Printf("\n== Managed to fix the problem by rescaling the matrix."); For(i,n*m) x[i] = buff[i]*scaler; Free(buff); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *Matrix_Mult(phydbl *A, phydbl *B, int nra, int nca, int nrb, int ncb) { int i,j,k; phydbl *C; C = (phydbl *)mCalloc(nra*ncb,sizeof(phydbl)); if(nca != nrb) { PhyML_Printf("\n. Matrices dimensions don't match."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } For(i,nra) For(j,ncb) For(k,nca) C[i*ncb+j] += A[i*nca+k] * B[k*ncb+j]; return C; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl *Matrix_Transpose(phydbl *A, int dim) { phydbl *tA,buff; int i,j; tA = (phydbl *)mCalloc(dim*dim,sizeof(phydbl)); For(i,dim*dim) tA[i]=A[i]; For(i,dim) for(j=i+1;j 1.E-3) */ /* { */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* } */ For(i,n) { for(j=i+1;j 1.E-3) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } } Free(mu1); Free(mu2); Free(sig11); Free(sig12); Free(sig21); Free(sig22); Free(ctrd_a); Free(cond_cov_norder); Free(cond_mu_norder); Free(sig12_invsig22); Free(buff_mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* http://en.wikipedia.org/wiki/Multivariate_normal_distribution (Conditional distributions) */ void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, int n1, phydbl *cond_mu, phydbl *cond_cov) { phydbl *mu1,*mu2; phydbl *sig11,*sig12,*sig21,*sig22,*sig12_invsig22,*buff; phydbl *ctrd_a; int n2; int i,j,nr,nc; n2 = n-n1; mu1 = (phydbl *)mCalloc(n1, sizeof(phydbl)); mu2 = (phydbl *)mCalloc(n2, sizeof(phydbl)); sig11 = (phydbl *)mCalloc(n1*n1,sizeof(phydbl)); sig12 = (phydbl *)mCalloc(n1*n2,sizeof(phydbl)); sig21 = (phydbl *)mCalloc(n2*n1,sizeof(phydbl)); sig22 = (phydbl *)mCalloc(n2*n2,sizeof(phydbl)); ctrd_a = (phydbl *)mCalloc(n2, sizeof(phydbl)); nr=0; For(i,n) { if(!is_1[i]) { ctrd_a[nr] = a[i]-mu[i]; nr++; } } nr=0; For(i,n) { if( is_1[i]) { mu1[nr] = mu[i]; nr++; } } nr=0; For(i,n) { if(!is_1[i]) { mu2[nr] = mu[i]; nr++; } } nr=0; nc=0; For(i,n) { if(is_1[i]) { nc = nr; for(j=i;jrates->cov_l; mean = tree->rates->mean_l; dim = 2*tree->n_otu-3; fp = fopen("covariance","w"); fprintf(fp,"\n"); fprintf(fp,"Run\t"); fprintf(fp,"lnL\t"); For(i,dim) fprintf(fp,"Edge%d[%f]\t",i,tree->rates->u_ml_l[i]); For(i,dim) mean[i] = .0; For(i,dim*dim) cov[i] = .0; MCMC_Randomize_Branch_Lengths(tree); /* For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v *= Rgamma(5.,1./5.); */ Set_Both_Sides(YES,tree); Lk(NULL,tree); iter = 0; do { /* tree->both_sides = YES; */ /* Lk(tree); */ MCMC_Br_Lens(tree); /* MCMC_Scale_Br_Lens(tree); */ max_diff_mean = 0.0; For(i,dim) { cur_mean = mean[i]; mean[i] *= (phydbl)iter; mean[i] += tree->a_edges[i]->l->v; mean[i] /= (phydbl)(iter+1); new_mean = mean[i]; diff_mean = MAX(cur_mean,new_mean)/MIN(cur_mean,new_mean); if(diff_mean > max_diff_mean) max_diff_mean = diff_mean; /* printf("\n. %d diff_mean = %f %f %f %f",i,diff_mean,cur_mean,new_mean,tree->a_edges[i]->l->v); */ } max_diff_cov = 0.0; For(i,dim) { For(j,dim) { cur_cov = cov[i*dim+j]; cov[i*dim+j] *= (phydbl)iter; cov[i*dim+j] += tree->a_edges[i]->l->v * tree->a_edges[j]->l->v; cov[i*dim+j] /= (phydbl)(iter+1); new_cov = cov[i*dim+j]; diff_cov = MAX(cur_cov,new_cov)/MIN(cur_cov,new_cov); if(diff_cov > max_diff_cov) max_diff_cov = diff_cov; } } iter++; /* if(!(iter%10)) */ /* printf("\n. iter=%d max_diff_mean=%f max_diff_cov=%f",iter,max_diff_mean,max_diff_cov); */ /* if(iter && max_diff_mean < 1.01 && max_diff_cov < 1.01) break; */ if(!(iter%20)) { fprintf(fp,"\n"); fprintf(fp,"%d\t",iter); fprintf(fp,"%f\t",tree->c_lnL); For(i,dim) fprintf(fp,"%f\t",tree->a_edges[i]->l->v); fflush(NULL); } }while(iter < 5000); For(i,dim) { For(j,dim) { cov[i*dim+j] = cov[i*dim+j] - mean[i]*mean[j]; if(i == j && cov[i*dim+j] < MIN_VAR_BL) cov[i*dim+j] = MIN_VAR_BL; } } fclose(fp); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Order statistic. x_is are uniformily distributed in [min,max] */ phydbl Dorder_Unif(phydbl x, int r, int n, phydbl min, phydbl max) { phydbl cons; phydbl Fx; phydbl dens; if(x < min || x > max || min > max) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } cons = LnGamma(n+1) - LnGamma(r) - LnGamma(n-r+1); cons = EXP(cons); cons = ROUND(cons); Fx = (x-min)/(max-min); dens = cons * pow(Fx,r-1) * pow(1.-Fx,n-r) * (1./(max-min)); /* printf("\n. x=%f r=%d n=%d min=%f max=%f dens=%f",x,r,n,min,max,dens); */ /* Exit("\n"); */ return(dens); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Covariance(phydbl *x, phydbl *y, int n) { int i; phydbl mean_x,mean_y,mean_xy; mean_x = .0; For(i,n) mean_x += x[i]; mean_x /= (phydbl)n; mean_y = .0; For(i,n) mean_y += y[i]; mean_y /= (phydbl)n; mean_xy = .0; For(i,n) mean_xy += x[i]*y[i]; mean_xy /= (phydbl)n; return (mean_xy - mean_x*mean_y); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Sample X from a multivariate normal with mean mu and covariance cov, within the interval [min,max], under the linear constraint X.lambda=k */ phydbl *Rnorm_Multid_Trunc_Constraint(phydbl *mu, phydbl *cov, phydbl *min, phydbl *max, phydbl *lambda, phydbl k, phydbl *res, int len) { phydbl *loc_res; int i,j,cond,iter; phydbl *x; phydbl cond_mean,cond_var; phydbl cov_zic,cov_zii,cov_zcc; phydbl mean_zi, mean_zc; phydbl alpha; phydbl sum; int err; phydbl zi; cond = 0; loc_res = NULL; if(!res) { loc_res = (phydbl *)mCalloc(len,sizeof(phydbl)); x = loc_res; } else x = res; /* zi = x[i] . lambda[i] */ iter = 0; do { sum = 0.0; For(i,len) { if(i != cond) { cov_zic = lambda[i] * lambda[cond] * cov[i*len+cond]; cov_zii = lambda[i] * lambda[i] * cov[i*len+i]; cov_zcc = lambda[cond] * lambda[cond] * cov[cond*len+cond]; mean_zi = lambda[i]; mean_zc = lambda[cond]; /* alpha = k - \sum_{j != cond, j !=i} z_j */ alpha = k; For(j,len) if(j != cond && j != i) alpha -= lambda[j] * x[j]; cond_mean = mean_zi + (cov_zii + cov_zic) / (cov_zii + 2.*cov_zic + cov_zcc) * (alpha - mean_zi - mean_zc); cond_var = cov_zii - POW(cov_zii + cov_zic,2)/(cov_zii + 2.*cov_zic + cov_zcc); if(lambda[i]*min[i] > alpha - lambda[cond]*min[i]) { PhyML_Printf("\n. Cannot satisfy the constraint.\n"); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } err = NO; zi = Rnorm_Trunc(cond_mean,SQRT(cond_var), MAX(lambda[i]*min[i],alpha-lambda[cond]*max[cond]), MIN(lambda[i]*max[i],alpha-lambda[cond]*min[cond]),&err); if(err == YES) { PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } sum += zi; x[i] = zi / lambda[i]; } } x[cond] = (k - sum)/lambda[cond]; }while(iter++ < 10); return(loc_res); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Integrated_Brownian_Bridge_Moments(phydbl x_beg, phydbl x_end, phydbl y_beg, phydbl y_end, phydbl brownian_var, phydbl *mean, phydbl *var) { /* phydbl *y; */ /* phydbl *y_mean; */ /* int n_rep; */ int n_breaks; int i; /* int j; */ /* phydbl traj_mean, traj_sd; */ /* phydbl x_prev, x_curr; */ phydbl x; phydbl x_step; phydbl sum; /* phydbl sumsum; */ phydbl scaled_var; scaled_var = brownian_var/FABS(x_end - x_beg); n_breaks = 100; /* n_rep = 500; */ /* x_step = (x_end - x_beg)/(n_breaks+1); */ /* y = (phydbl *)mCalloc(n_breaks+2,sizeof(phydbl)); */ /* y_mean = (phydbl *)mCalloc(n_rep,sizeof(phydbl)); */ /* y[0] = y_beg; */ /* y[n_breaks+1] = y_end; */ /* For(i,n_rep) */ /* { */ /* for(j=1;j 1. + 1.E-10) || (cum_pi[i-1] < 1. - 1.E-10)) { PhyML_Printf("\n== Sum of probabilities is different from 1.0 (%f).",cum_pi[i-1]); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } i = 0; u = Uni(); For(i,len) if(cum_pi[i] > u) break; if(i == len) { For(i,len) printf("\n== idx:%d prob:%g",i,pi[i]); PhyML_Printf("\n== Len = %d",len); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } Free(cum_pi); return(i); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Return the value y such that Prob(x obs_stat) p_val += 1.; } return(p_val / (phydbl)npermut); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Weighted_Mean(phydbl *x, phydbl *w, int l) { int i; phydbl wm; wm = .0; if(w) For(i,l) wm += x[i]*w[i]; else { For(i,l) wm += x[i]; wm /= (phydbl)l; } return(wm); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Variance(phydbl *x, int l) { phydbl mean,sum; int i; mean = Weighted_Mean(x,NULL,l); sum = 0.0; For(i,l) sum += x[i]*x[i]; return(sum/l - mean*mean); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sum_Bits(int value, int range) { int i; int sum; if(range > 8*(int)sizeof(int)) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } sum = 0; For(i,range) { sum += (value >> i) & 1; } return(sum); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Modulo (int a, int b) { if(b < 0) return Modulo(-a, -b); int ret = a % b; if(ret < 0) ret+=b; return ret; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Runif_Disk(phydbl *sampled_x, phydbl *sampled_y, phydbl centrx, phydbl centry, phydbl radius) { phydbl r,theta; r = Uni(); theta = Uni()*2.*PI; (*sampled_x) = SQRT(r)*COS(theta); (*sampled_y) = SQRT(r)*SIN(theta); (*sampled_x) *= radius; (*sampled_y) *= radius; (*sampled_x) += centrx; (*sampled_y) += centry; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Random_String(char *s, int len) { int i; For(i,len) s[i] = Rand_Int(97,121); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int *Random_Permut(int n) { int *permut; int i,j; int tmp; if(n < 3) { PhyML_Printf("\n== Number of vertices in a polygon has to be at least 3."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } permut = (int *)mCalloc(n,sizeof(int)); For(i,n) permut[i] = i; For(i,n-1) { j = Rand_Int(i,n-1); tmp = permut[i]; permut[i] = permut[j]; permut[j] = tmp; } return(permut); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Generate a random polygon with n vertices. Each point lies in [0,1] */ t_poly *Rpoly(int n) { t_poly *p; int i; p = (t_poly *)Make_Poly(n); p->n_poly_vert = n; For(i,n) { p->poly_vert[i]->lonlat[0] = Uni(); p->poly_vert[i]->lonlat[1] = Uni(); } return(p); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Area_Of_Poly_Monte_Carlo(t_poly **poly, int n_poly, t_geo_coord *lim) { int n_hit,n_trials,trial,i; t_geo_coord *point; point = (t_geo_coord *)GEO_Make_Geo_Coord(2); n_trials = 1E+7; trial = 0; n_hit = 0; do { point->lonlat[0] = Uni()*lim->lonlat[0]; point->lonlat[1] = Uni()*lim->lonlat[1]; For(i,n_poly) if(Is_In_Polygon(point,poly[i]) == YES) { n_hit++; break; } trial++; } while(trial < n_trials); Free_Geo_Coord(point); return((phydbl)(n_hit)/n_trials); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ int Is_In_Polygon(t_geo_coord *point, t_poly *poly) { int i,j; phydbl x,y,x1,y1,x2,y2; phydbl x_intersect; short int is_in; /* Coordinates of the point to test */ x = point->lonlat[0]; y = point->lonlat[1]; j = poly->n_poly_vert-1; is_in = NO; For(i,poly->n_poly_vert) { /* Edge of polygon goes from (x1,y1) to (x2,y2) */ x1 = poly->poly_vert[i]->lonlat[0]; y1 = poly->poly_vert[i]->lonlat[1]; x2 = poly->poly_vert[j]->lonlat[0]; y2 = poly->poly_vert[j]->lonlat[1]; j = i; /* Shoot an horizontal ray to the right. Find out if this ray hits the polygon edge */ if((y1 < y && y2 > y) || (y2 < y && y1 > y)) { /* Coordinates along X-axis of the intersection between ray and edge */ x_intersect = (y-y1)/(y1-y2)*(x1-x2)+x1; if(x_intersect > x) /* Intersection is on the righthand side */ is_in = (is_in == YES)?NO:YES; } } return is_in; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Modified Bessel function of the first kind. Stolen from Numerical Recipes in C. */ phydbl Bessi0(phydbl x) { phydbl ax,ans; phydbl y; if ((ax=fabs(x)) < 3.75) { y=x/3.75; y*=y; ans=1.0+y*(3.5156229+y*(3.0899424+y*(1.2067492+y*(0.2659732+y*(0.360768e-1+y*0.45813e-2))))); } else { y=3.75/ax; ans=(exp(ax)/sqrt(ax))*(0.39894228+y*(0.1328592e-1+y*(0.225319e-2+y*(-0.157565e-2+y*(0.916281e-2+y*(-0.2057706e-1+y*(0.2635537e-1+y*(-0.1647633e-1+y*0.392377e-2)))))))); } return ans; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Modified Bessel function of the second kind (degree 0). Stolen from Numerical Recipes in C. */ phydbl Bessk0(phydbl x) { phydbl y,ans; if (x <= 2.0) { y=x*x/4.0; ans=(-log(x/2.0)*Bessi0(x))+(-0.57721566+y*(0.42278420+y*(0.23069756+y*(0.3488590e-1+y*(0.262698e-2+y*(0.10750e-3+y*0.74e-5)))))); } else { y=2.0/x; ans=(exp(-x)/sqrt(x))*(1.25331414+y*(-0.7832358e-1+y*(0.2189568e-1+y*(-0.1062446e-1+y*(0.587872e-2+y*(-0.251540e-2+y*0.53208e-3)))))); } return ans; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Euclidean_Dist(t_geo_coord *x, t_geo_coord *y) { int i; phydbl dist; if(x->dim != y->dim) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); dist = 0.0; For(i,x->dim) dist += POW(x->lonlat[i]-y->lonlat[i],2); return(SQRT(dist)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Return the ranks of elements in x */ int *Ranks(phydbl *x, int len) { int *rk,tmp; int i,swap; rk = (int *)mCalloc(len,sizeof(int)); For(i,len) rk[i] = i; do { swap = NO; For(i,len-1) { if(x[rk[i]] > x[rk[i+1]]) { swap = YES; tmp = rk[i]; rk[i] = rk[i+1]; rk[i+1] = tmp; } } } while(swap == YES); return(rk); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl *Brownian_Bridge_Generate(phydbl start, phydbl end, phydbl var, phydbl beg_time, phydbl end_time, int n_steps, phydbl *time) { phydbl *state,end_brown; int i; if(n_steps == 0) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(beg_time > end_time) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); For(i,n_steps-1) if(!(time[i+1] > time[i])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); state = Brownian_Generate(var,n_steps,beg_time,time); end_brown = Rnorm(state[n_steps-1],SQRT((time[n_steps-1] - end_time)*var)); For(i,n_steps) { state[i] = state[i] - (time[i]/end_time) * end_brown; state[i] = start + (end - start)/end_time * time[i] + state[i]; } return(state); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl *Brownian_Generate(phydbl var, int n_steps, phydbl beg_time, phydbl *time) { phydbl *state; int i; if(n_steps == 0) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); state = (phydbl *)mCalloc(n_steps,sizeof(phydbl)); state[0] = Rnorm(0.0,SQRT((time[0] - beg_time)*var)); for(i=1;i up) ref = up - (ref - up); if(ref < down) ref = down + (down - ref); }while(!(ref < up && ref > down)); return(ref); } phyml-3.2.0/src/stats.h000066400000000000000000000152031263450375500147560ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef STATS_H #define STATS_H #include "utilities.h" #include "free.h" #include "lk.h" #include "optimiz.h" #include "models.h" #include "eigen.h" phydbl *Covariance_Matrix(t_tree *tree); phydbl *Hessian(t_tree *tree); void Recurr_Hessian(t_node *a, t_node *b, int plus_minus, phydbl *inc, phydbl *res, int *is_ok, t_tree *tree); phydbl stdnormal_inv(phydbl p); phydbl Uni(); int Rand_Int(int min, int max); phydbl Ahrensdietergamma(phydbl alpha); phydbl Rgamma(phydbl shape, phydbl scale); phydbl Rexp(phydbl lambda); phydbl Bico(int n, int k); phydbl Factln(int n); phydbl Gammln(phydbl xx); phydbl Pbinom(int N, int ni, phydbl p); phydbl LnGamma (phydbl alpha); phydbl IncompleteGamma(phydbl x, phydbl alpha, phydbl ln_gamma_alpha); phydbl PointChi2 (phydbl prob, phydbl v); phydbl Bivariate_Normal_Density(phydbl x, phydbl y, phydbl mux, phydbl muy, phydbl sdx, phydbl sdy, phydbl rho); phydbl PointNormal (phydbl prob); int DiscreteGamma (phydbl freqK[], phydbl rK[],phydbl alfa, phydbl beta, int K, int median); phydbl Pnorm(phydbl x, phydbl mean, phydbl var); phydbl Dnorm_Moments(phydbl x, phydbl mean, phydbl var); phydbl Dnorm(phydbl x, phydbl mean, phydbl sd); phydbl Pgamma(phydbl x, phydbl shape, phydbl scale); phydbl Dgamma_Moments(phydbl x, phydbl mean, phydbl var); phydbl Dgamma(phydbl x, phydbl shape, phydbl scale); phydbl LnFact(int n); int Choose(int n, int k); phydbl LnChoose(int n, int k); phydbl Ppois(phydbl x, phydbl param); phydbl Dexp(phydbl x, phydbl param); phydbl Dpois(phydbl x, phydbl param, int logit); phydbl Rand_Normal_Deviate(phydbl mean, phydbl sd); phydbl Rnorm(phydbl mean, phydbl sd); phydbl *Rnorm_Multid(phydbl *mu, phydbl *cov, int dim); phydbl Rnorm_Trunc(phydbl mean, phydbl sd, phydbl min, phydbl max, int *err); phydbl *Rnorm_Multid_Trunc(phydbl *mean, phydbl *cov, phydbl *min, phydbl *max, int dim); phydbl *Hessian_Log(t_tree *tree); void Recurr_Hessian_Log(t_node *a, t_node *d, int plus_minus, phydbl *inc, phydbl *res, int *is_ok, t_tree *tree); phydbl Log_Det(int *is_ok, t_tree *tree); phydbl Dnorm_Trunc(phydbl x, phydbl mean, phydbl sd, phydbl lo, phydbl up); phydbl Normal_Trunc_Mean(phydbl mu, phydbl sd, phydbl min, phydbl max); phydbl Constraint_Normal_Trunc_Mean(phydbl wanted_mu, phydbl sd, phydbl min, phydbl max); phydbl Dnorm_Multi(phydbl *x, phydbl *mu, phydbl *cov, int size, int _log); phydbl Dnorm_Multi_Given_InvCov_Det(phydbl *x, phydbl *mu, phydbl *invcov, phydbl det, int size, int _log); phydbl Prop_Log_Dnorm_Multi_Given_InvCov_Det(phydbl *x, phydbl *mu, phydbl *invcov, phydbl det, int size); phydbl Log_Dnorm(phydbl x, phydbl mean, phydbl sd, int *err); phydbl tt800(); phydbl Pnorm_Ihaka_Derived_From_Cody(phydbl x); int Matinv(phydbl *x, int n, int m, int verbose); phydbl *Matrix_Mult(phydbl *A, phydbl *B, int nra, int nca, int nrb, int ncb); phydbl *Matrix_Transpose(phydbl *A, int dim); void Normal_Conditional(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, int n1, phydbl *cond_mu, phydbl *cond_var); void Normal_Conditional_Unsorted(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, int n1, phydbl *cond_mu, phydbl *cond_cov); phydbl Matrix_Det(phydbl *A, int size, int _log); void Get_Reg_Coeff(phydbl *mu, phydbl *cov, phydbl *a, int n, short int *is_1, int n1, phydbl *reg_coeff); phydbl Rnorm_Trunc_Inverse(phydbl mean, phydbl sd, phydbl min, phydbl max, int *error); phydbl Norm_Trunc_Sd(phydbl mu, phydbl sd, phydbl a, phydbl b); phydbl Norm_Trunc_Mean(phydbl mu, phydbl sd, phydbl a, phydbl b); int Norm_Trunc_Mean_Sd(phydbl mu, phydbl sd, phydbl a, phydbl b, phydbl *trunc_mu, phydbl *trunc_sd); phydbl Log_Dnorm_Trunc(phydbl x, phydbl mean, phydbl sd, phydbl lo, phydbl up, int *err); phydbl Pnorm_Marsaglia(phydbl x); int Iter_Matinv(phydbl *x, int n, int m, int verbose); phydbl Dorder_Unif(phydbl x, int r, int n, phydbl min, phydbl max); phydbl Covariance(phydbl *x, phydbl *y, int n); phydbl *Rnorm_Multid_Trunc_Constraint(phydbl *mu, phydbl *cov, phydbl *min, phydbl *max, phydbl *lambda, phydbl k, phydbl *res, int len); phydbl *Gradient(t_tree *tree); phydbl *Hessian_Seo(t_tree *tree); void Integrated_Brownian_Bridge_Moments(phydbl x_beg, phydbl x_end, phydbl y_beg, phydbl y_end, phydbl sd, phydbl *mean, phydbl *var); void Integrated_Geometric_Brownian_Bridge_Moments(phydbl T, phydbl A, phydbl B, phydbl u, phydbl *mean, phydbl *var); void Integrated_Geometric_Brownian_Bridge_Mean(phydbl T, phydbl A, phydbl B, phydbl u, phydbl *mean); void Integrated_Geometric_Brownian_Bridge_Var(phydbl T, phydbl A, phydbl B, phydbl u, phydbl *mean); int Sample_i_With_Proba_pi(phydbl *pi, int len); phydbl Quantile(phydbl *x, int len, phydbl p); phydbl Prob(phydbl *x, int len, phydbl z); phydbl Inverse_Truncated_Normal(phydbl y, phydbl mu, phydbl sigma, phydbl lim_inf, phydbl lim_sup); phydbl Progressive_EXP(phydbl x); int *Permutate(int len); phydbl Mantel(phydbl *x, phydbl *y, int nrow, int ncol); phydbl Weighted_Mean(phydbl *x, phydbl *w, int l); int Sum_Bits(int value, int range); int Modulo (int a, int b); void Runif_Disk(phydbl *sampled_x, phydbl *sampled_y, phydbl centrx, phydbl centry, phydbl radius); void Random_String(char *s, int len); int *Random_Permut(int n); phydbl Dexp_Trunc(phydbl x, phydbl lambda, phydbl left, phydbl rght); phydbl Rexp_Trunc(phydbl lambda, phydbl left, phydbl rght); t_poly *Rpoly(int n); phydbl Area_Of_Poly_Monte_Carlo(t_poly **poly, int n_poly, t_geo_coord *lim); int Is_In_Polygon(t_geo_coord *point, t_poly *poly); phydbl Variance(phydbl *x, int l); phydbl Bessi0(phydbl x); phydbl Bessk0(phydbl x); phydbl Euclidean_Dist(t_geo_coord *x, t_geo_coord *y); int *Ranks(phydbl *x, int len); phydbl Rpois(phydbl mmu); phydbl Rgeom(phydbl p); phydbl Dgeom(phydbl k, phydbl p, int logit); phydbl Pgeom(phydbl k, phydbl p); phydbl *Brownian_Bridge_Generate(phydbl start, phydbl end, phydbl var, phydbl beg_time, phydbl end_time, int n_steps, phydbl *time); phydbl *Brownian_Generate(phydbl var, int n_steps, phydbl beg_time, phydbl *time); phydbl Brownian_Bridge_Logdensity(phydbl start, phydbl end, phydbl *state, phydbl var, phydbl end_time, int n_steps, phydbl *time); phydbl Reflected(phydbl x, phydbl down, phydbl up); phydbl *Random_Walk_Generate(phydbl var, int n_steps); phydbl *Random_Walk_Bridged_Generate(phydbl start, phydbl end, phydbl var, int n_steps); phydbl Dnbinom(phydbl x, phydbl n, phydbl p, int logit); phydbl Rnbinom(phydbl n, phydbl p); #endif phyml-3.2.0/src/times.c000066400000000000000000001330741263450375500147430ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Routines for molecular clock trees and molecular dating */ #include "times.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// #ifdef PHYTIME int TIMES_main(int argc, char **argv) { align **data; calign *cdata; option *io; t_tree *tree; int num_data_set; int num_tree,num_rand_tree; t_mod *mod; time_t t_beg,t_end; int r_seed; char *most_likely_tree; int i; int user_lk_approx; #ifdef MPI int rc; rc = MPI_Init(&argc,&argv); if (rc != MPI_SUCCESS) { PhyML_Printf("\n. Error starting MPI program. Terminating.\n"); MPI_Abort(MPI_COMM_WORLD, rc); } MPI_Comm_size(MPI_COMM_WORLD,&Global_numTask); MPI_Comm_rank(MPI_COMM_WORLD,&Global_myRank); #endif #ifdef QUIET setvbuf(stdout,NULL,_IOFBF,2048); #endif tree = NULL; mod = NULL; data = NULL; most_likely_tree = NULL; io = (option *)Get_Input(argc,argv); r_seed = (io->r_seed < 0)?(time(NULL)):(io->r_seed); io->r_seed = r_seed; srand(r_seed); rand(); PhyML_Printf("\n. Seed: %d\n",r_seed); PhyML_Printf("\n. Pid: %d\n",getpid()); Make_Model_Complete(io->mod); mod = io->mod; if(io->in_tree == 2) Test_Multiple_Data_Set_Format(io); else io->n_trees = 1; if((io->n_data_sets > 1) && (io->n_trees > 1)) { io->n_data_sets = MIN(io->n_trees,io->n_data_sets); io->n_trees = MIN(io->n_trees,io->n_data_sets); } For(num_data_set,io->n_data_sets) { data = Get_Seq(io); if(data) { if(io->n_data_sets > 1) PhyML_Printf("\n. Data set [#%d]\n",num_data_set+1); PhyML_Printf("\n. Compressing sequences...\n"); cdata = Compact_Data(data,io); Free_Seq(data,cdata->n_otu); Check_Ambiguities(cdata,io->mod->io->datatype,io->state_len); for(num_tree=(io->n_trees == 1)?(0):(num_data_set);num_tree < io->n_trees;num_tree++) { if(!io->mod->s_opt->random_input_tree) io->mod->s_opt->n_rand_starts = 1; For(num_rand_tree,io->mod->s_opt->n_rand_starts) { if((io->mod->s_opt->random_input_tree) && (io->mod->s_opt->topo_search != NNI_MOVE)) PhyML_Printf("\n. [Random start %3d/%3d]\n",num_rand_tree+1,io->mod->s_opt->n_rand_starts); Init_Model(cdata,mod,io); if(io->mod->use_m4mod) M4_Init_Model(mod->m4mod,cdata,mod); /* A BioNJ tree is built here */ if(!io->in_tree) tree = Dist_And_BioNJ(cdata,mod,io); /* A user-given tree is used here instead of BioNJ */ else tree = Read_User_Tree(cdata,mod,io); if(io->fp_in_constraint_tree != NULL) { io->cstr_tree = Read_Tree_File_Phylip(io->fp_in_constraint_tree); io->cstr_tree->rates = RATES_Make_Rate_Struct(io->cstr_tree->n_otu); RATES_Init_Rate_Struct(io->cstr_tree->rates,io->rates,io->cstr_tree->n_otu); } if(!tree) continue; if(!tree->n_root) { PhyML_Printf("\n== Sorry, PhyTime requires a rooted tree as input."); Exit("\n"); } time(&t_beg); time(&(tree->t_beg)); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,io->rates,tree->n_otu); Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); RATES_Fill_Lca_Table(tree); tree->mod = mod; tree->io = io; tree->data = cdata; tree->n_pattern = tree->data->crunch_len/tree->io->state_len; Set_Both_Sides(YES,tree); Prepare_Tree_For_Lk(tree); /* Read node age priors */ Read_Clade_Priors(io->clade_list_file,tree); /* Set upper and lower bounds for all node ages */ TIMES_Set_All_Node_Priors(tree); /* Count the number of time slices */ TIMES_Get_Number_Of_Time_Slices(tree); TIMES_Label_Edges_With_Calibration_Intervals(tree); tree->write_br_lens = NO; PhyML_Printf("\n"); PhyML_Printf("\n. Input tree with calibration information ('almost' compatible with MCMCtree).\n"); PhyML_Printf("\n%s\n",Write_Tree(tree,YES)); tree->write_br_lens = YES; /* Get_Edge_Binary_Coding_Number(tree); */ /* Exit("\n"); */ /* Print_CSeq_Select(stdout,NO,tree->data,tree); */ /* Exit("\n"); */ /* TIMES_Set_Root_Given_Tip_Dates(tree); */ /* int i; */ /* char *s; */ /* FILE *fp; */ /* For(i,2*tree->n_otu-2) tree->rates->cur_l[i] = 1.; */ /* s = Write_Tree(tree,NO); */ /* fp = fopen("rooted_tree","w"); */ /* fprintf(fp,"%s\n",s); */ /* fclose(fp); */ /* Exit("\n"); */ /* Work with log of branch lengths? */ if(tree->mod->log_l == YES) Log_Br_Len(tree); if(io->mcmc->use_data == YES) { /* Force the exact likelihood score */ user_lk_approx = tree->io->lk_approx; tree->io->lk_approx = EXACT; /* printf("\n. Lk: %f",Lk(NULL,tree)); */ /* Exit("\n"); */ /* MLE for branch lengths */ Round_Optimize(tree,tree->data,ROUND_MAX); /* Set vector of mean branch lengths for the Normal approximation of the likelihood */ RATES_Set_Mean_L(tree); /* Estimate the matrix of covariance for the Normal approximation of the likelihood */ PhyML_Printf("\n"); PhyML_Printf("\n. Computing Hessian..."); tree->rates->bl_from_rt = 0; Free(tree->rates->cov_l); tree->rates->cov_l = Hessian_Seo(tree); /* tree->rates->cov_l = Hessian_Log(tree); */ For(i,(2*tree->n_otu-3)*(2*tree->n_otu-3)) tree->rates->cov_l[i] *= -1.0; if(!Iter_Matinv(tree->rates->cov_l,2*tree->n_otu-3,2*tree->n_otu-3,YES)) Exit("\n"); tree->rates->covdet = Matrix_Det(tree->rates->cov_l,2*tree->n_otu-3,YES); For(i,(2*tree->n_otu-3)*(2*tree->n_otu-3)) tree->rates->invcov[i] = tree->rates->cov_l[i]; if(!Iter_Matinv(tree->rates->invcov,2*tree->n_otu-3,2*tree->n_otu-3,YES)) Exit("\n"); tree->rates->grad_l = Gradient(tree); /* Pre-calculation of conditional variances to speed up calculations */ RATES_Bl_To_Ml(tree); RATES_Get_Conditional_Variances(tree); RATES_Get_All_Reg_Coeff(tree); RATES_Get_Trip_Conditional_Variances(tree); RATES_Get_All_Trip_Reg_Coeff(tree); Lk(NULL,tree); PhyML_Printf("\n"); PhyML_Printf("\n. p(data|model) [exact ] ~ %.2f",tree->c_lnL); tree->io->lk_approx = NORMAL; For(i,2*tree->n_otu-3) tree->rates->u_cur_l[i] = tree->rates->mean_l[i] ; tree->c_lnL = Lk(NULL,tree); PhyML_Printf("\n. p(data|model) [approx] ~ %.2f",tree->c_lnL); tree->io->lk_approx = user_lk_approx; } tree->rates->model = io->rates->model; PhyML_Printf("\n. Selected model '%s'",RATES_Get_Model_Name(io->rates->model)); if(tree->rates->model == GUINDON) tree->mod->gamma_mgf_bl = YES; tree->rates->bl_from_rt = YES; if(tree->io->cstr_tree) Find_Surviving_Edges_In_Small_Tree(tree,tree->io->cstr_tree); time(&t_beg); tree->mcmc = MCMC_Make_MCMC_Struct(); MCMC_Copy_MCMC_Struct(tree->io->mcmc,tree->mcmc,"phytime"); MCMC_Complete_MCMC(tree->mcmc,tree); tree->mcmc->is_burnin = NO; tree->mod->ras->sort_rate_classes = YES; MCMC(tree); MCMC_Close_MCMC(tree->mcmc); MCMC_Free_MCMC(tree->mcmc); Add_Root(tree->a_edges[0],tree); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); } break; } Free_Cseq(cdata); } } Free_Model(mod); if(io->fp_in_align) fclose(io->fp_in_align); if(io->fp_in_tree) fclose(io->fp_in_tree); if(io->fp_out_lk) fclose(io->fp_out_lk); if(io->fp_out_tree) fclose(io->fp_out_tree); if(io->fp_out_trees) fclose(io->fp_out_trees); if(io->fp_out_stats) fclose(io->fp_out_stats); Free(most_likely_tree); Free_Input(io); time(&t_end); Print_Time_Info(t_beg,t_end); #ifdef MPI MPI_Finalize(); #endif return 0; } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Least_Square_Node_Times(t_edge *e_root, t_tree *tree) { /* Solve A.x = b, where x are the t_node time estimated under the least square criterion. A is a n x n matrix, with n being the number of nodes in a rooted tree (i.e. 2*n_otu-1). */ phydbl *A, *b, *x; int n; int i,j; t_node *root; n = 2*tree->n_otu-1; A = (phydbl *)mCalloc(n*n,sizeof(phydbl)); b = (phydbl *)mCalloc(n, sizeof(phydbl)); x = (phydbl *)mCalloc(n, sizeof(phydbl)); if(!tree->n_root && e_root) Add_Root(e_root,tree); else if(!e_root) Add_Root(tree->a_edges[0],tree); root = tree->n_root; TIMES_Least_Square_Node_Times_Pre(root,root->v[2],A,b,n,tree); TIMES_Least_Square_Node_Times_Pre(root,root->v[1],A,b,n,tree); b[root->num] = tree->e_root->l->v/2.; A[root->num * n + root->num] = 1.0; A[root->num * n + root->v[2]->num] = -.5; A[root->num * n + root->v[1]->num] = -.5; if(!Matinv(A, n, n,YES)) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } For(i,n) x[i] = .0; For(i,n) For(j,n) x[i] += A[i*n+j] * b[j]; For(i,n-1) { tree->rates->nd_t[tree->a_nodes[i]->num] = -x[i]; } tree->rates->nd_t[root->num] = -x[n-1]; tree->n_root->l[2] = tree->rates->nd_t[root->v[2]->num] - tree->rates->nd_t[root->num]; tree->n_root->l[1] = tree->rates->nd_t[root->v[1]->num] - tree->rates->nd_t[root->num]; //////////////////////////////////////// return; //////////////////////////////////////// /* Rescale the t_node times such that the time at the root is -100. This constraint implies that the clock rate is fixed to the actual tree length divided by the tree length measured in term of differences of t_node times */ phydbl scale_f,time_tree_length,tree_length; scale_f = -100./tree->rates->nd_t[root->num]; For(i,2*tree->n_otu-1) tree->rates->nd_t[i] *= scale_f; For(i,2*tree->n_otu-1) if(tree->rates->nd_t[i] > .0) tree->rates->nd_t[i] = .0; time_tree_length = 0.0; For(i,2*tree->n_otu-3) if(tree->a_edges[i] != tree->e_root) time_tree_length += FABS(tree->rates->nd_t[tree->a_edges[i]->left->num] - tree->rates->nd_t[tree->a_edges[i]->rght->num]); time_tree_length += FABS(tree->rates->nd_t[root->num] - tree->rates->nd_t[root->v[2]->num]); time_tree_length += FABS(tree->rates->nd_t[root->num] - tree->rates->nd_t[root->v[1]->num]); tree_length = 0.0; For(i,2*tree->n_otu-3) tree_length += tree->a_edges[i]->l->v; tree->rates->clock_r = tree_length / time_tree_length; Free(A); Free(b); Free(x); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Least_Square_Node_Times_Pre(t_node *a, t_node *d, phydbl *A, phydbl *b, int n, t_tree *tree) { if(d->tax) { A[d->num * n + d->num] = 1.; /* Set the time stamp at tip nodes to 0.0 */ /* PhyML_Printf("\n. Tip t_node date set to 0"); */ b[d->num] = 0.0; return; } else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) TIMES_Least_Square_Node_Times_Pre(d,d->v[i],A,b,n,tree); A[d->num * n + d->num] = 1.; b[d->num] = .0; For(i,3) { A[d->num * n + d->v[i]->num] = -1./3.; if(d->v[i] != a) b[d->num] += d->b[i]->l->v; else b[d->num] -= d->b[i]->l->v; } b[d->num] /= 3.; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Adjust t_node times in order to have correct time stamp ranking with respect to the tree topology */ void TIMES_Adjust_Node_Times(t_tree *tree) { TIMES_Adjust_Node_Times_Pre(tree->n_root->v[2],tree->n_root->v[1],tree); TIMES_Adjust_Node_Times_Pre(tree->n_root->v[1],tree->n_root->v[2],tree); if(tree->rates->nd_t[tree->n_root->num] > MIN(tree->rates->nd_t[tree->n_root->v[2]->num], tree->rates->nd_t[tree->n_root->v[1]->num])) { tree->rates->nd_t[tree->n_root->num] = MIN(tree->rates->nd_t[tree->n_root->v[2]->num], tree->rates->nd_t[tree->n_root->v[1]->num]); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Adjust_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; phydbl min_height; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { TIMES_Adjust_Node_Times_Pre(d,d->v[i],tree); } min_height = 0.0; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(tree->rates->nd_t[d->v[i]->num] < min_height) { min_height = tree->rates->nd_t[d->v[i]->num]; } } } if(tree->rates->nd_t[d->num] > min_height) tree->rates->nd_t[d->num] = min_height; if(tree->rates->nd_t[d->num] < -100.) tree->rates->nd_t[d->num] = -100.; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Multiply each time stamp at each internal t_node by 'tree->time_stamp_mult'. */ void TIMES_Mult_Time_Stamps(t_tree *tree) { int i; For(i,2*tree->n_otu-2) tree->rates->nd_t[tree->a_nodes[i]->num] *= FABS(tree->mod->s_opt->tree_size_mult); tree->rates->nd_t[tree->n_root->num] *= FABS(tree->mod->s_opt->tree_size_mult); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Print_Node_Times(t_node *a, t_node *d, t_tree *tree) { t_edge *b; int i; b = NULL; For(i,3) if((d->v[i]) && (d->v[i] == a)) {b = d->b[i]; break;} PhyML_Printf("\n. (%3d %3d) a->t = %12f d->t = %12f (#=%12f) b->l->v = %12f [%12f;%12f]", a->num,d->num, tree->rates->nd_t[a->num], tree->rates->nd_t[d->num], tree->rates->nd_t[a->num]-tree->rates->nd_t[d->num], (b)?(b->l->v):(-1.0), tree->rates->t_prior_min[d->num], tree->rates->t_prior_max[d->num]); if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) TIMES_Print_Node_Times(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors(t_tree *tree) { int i; phydbl min_prior; /* Set all t_prior_max values */ TIMES_Set_All_Node_Priors_Bottom_Up(tree->n_root,tree->n_root->v[2],tree); TIMES_Set_All_Node_Priors_Bottom_Up(tree->n_root,tree->n_root->v[1],tree); tree->rates->t_prior_max[tree->n_root->num] = MIN(tree->rates->t_prior_max[tree->n_root->num], MIN(tree->rates->t_prior_max[tree->n_root->v[2]->num], tree->rates->t_prior_max[tree->n_root->v[1]->num])); /* Set all t_prior_min values */ if(!tree->rates->t_has_prior[tree->n_root->num]) { min_prior = 1.E+10; For(i,2*tree->n_otu-2) { if(tree->rates->t_has_prior[i]) { if(tree->rates->t_prior_min[i] < min_prior) min_prior = tree->rates->t_prior_min[i]; } } tree->rates->t_prior_min[tree->n_root->num] = 2.0 * min_prior; /* tree->rates->t_prior_min[tree->n_root->num] = 10. * min_prior; */ } if(tree->rates->t_prior_min[tree->n_root->num] > 0.0) { PhyML_Printf("\n== Failed to set the lower bound for the root node."); PhyML_Printf("\n== Make sure at least one of the calibration interval"); PhyML_Printf("\n== provides a lower bound."); Exit("\n"); } TIMES_Set_All_Node_Priors_Top_Down(tree->n_root,tree->n_root->v[2],tree); TIMES_Set_All_Node_Priors_Top_Down(tree->n_root,tree->n_root->v[1],tree); Get_Node_Ranks(tree); TIMES_Set_Floor(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors_Bottom_Up(t_node *a, t_node *d, t_tree *tree) { int i; phydbl t_sup; if(d->tax) return; else { t_node *v1, *v2; /* the two sons of d */ For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { TIMES_Set_All_Node_Priors_Bottom_Up(d,d->v[i],tree); } } v1 = v2 = NULL; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } if(tree->rates->t_has_prior[d->num] == YES) { t_sup = MIN(tree->rates->t_prior_max[d->num], MIN(tree->rates->t_prior_max[v1->num], tree->rates->t_prior_max[v2->num])); tree->rates->t_prior_max[d->num] = t_sup; if(tree->rates->t_prior_max[d->num] < tree->rates->t_prior_min[d->num]) { PhyML_Printf("\n== prior_min=%f prior_max=%f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]); PhyML_Printf("\n== Inconsistency in the prior settings detected at node %d",d->num); PhyML_Printf("\n== Err. in file %s at line %d (function %s)\n\n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit("\n"); } } else { tree->rates->t_prior_max[d->num] = MIN(tree->rates->t_prior_max[v1->num], tree->rates->t_prior_max[v2->num]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_All_Node_Priors_Top_Down(t_node *a, t_node *d, t_tree *tree) { if(d->tax) return; else { int i; if(tree->rates->t_has_prior[d->num] == YES) { tree->rates->t_prior_min[d->num] = MAX(tree->rates->t_prior_min[d->num],tree->rates->t_prior_min[a->num]); if(tree->rates->t_prior_max[d->num] < tree->rates->t_prior_min[d->num]) { PhyML_Printf("\n. prior_min=%f prior_max=%f",tree->rates->t_prior_min[d->num],tree->rates->t_prior_max[d->num]); PhyML_Printf("\n. Inconsistency in the prior settings detected at t_node %d",d->num); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit("\n"); } } else { tree->rates->t_prior_min[d->num] = tree->rates->t_prior_min[a->num]; } For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { TIMES_Set_All_Node_Priors_Top_Down(d,d->v[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_Floor(t_tree *tree) { TIMES_Set_Floor_Post(tree->n_root,tree->n_root->v[2],tree); TIMES_Set_Floor_Post(tree->n_root,tree->n_root->v[1],tree); tree->rates->t_floor[tree->n_root->num] = MIN(tree->rates->t_floor[tree->n_root->v[2]->num], tree->rates->t_floor[tree->n_root->v[1]->num]); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_Floor_Post(t_node *a, t_node *d, t_tree *tree) { if(d->tax) { tree->rates->t_floor[d->num] = tree->rates->nd_t[d->num]; d->rank_max = d->rank; return; } else { int i; t_node *v1,*v2; v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIMES_Set_Floor_Post(d,d->v[i],tree); if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } } tree->rates->t_floor[d->num] = MIN(tree->rates->t_floor[v1->num], tree->rates->t_floor[v2->num]); if(tree->rates->t_floor[v1->num] < tree->rates->t_floor[v2->num]) { d->rank_max = v1->rank_max; } else if(tree->rates->t_floor[v2->num] < tree->rates->t_floor[v1->num]) { d->rank_max = v2->rank_max; } else { d->rank_max = MAX(v1->rank_max,v2->rank_max); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Does it work for serial samples? */ phydbl TIMES_Log_Conditional_Uniform_Density(t_tree *tree) { phydbl min,max; phydbl dens; int i; min = tree->rates->nd_t[tree->n_root->num]; dens = 0.0; For(i,2*tree->n_otu-1) { if((tree->a_nodes[i]->tax == NO) && (tree->a_nodes[i] != tree->n_root)) { max = tree->rates->t_floor[i]; dens += LOG(Dorder_Unif(tree->rates->nd_t[i], tree->a_nodes[i]->rank-1, tree->a_nodes[i]->rank_max-2, min,max)); } } return dens; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the marginal density of tree height assuming the // Yule model of speciation. phydbl TIMES_Lk_Yule_Root_Marginal(t_tree *tree) { int n; int j; t_node *nd; phydbl *t,*ts; phydbl lbda; phydbl T; lbda = tree->rates->birth_rate; t = tree->rates->nd_t; ts = tree->rates->time_slice_lims; T = ts[0] - t[tree->n_root->num]; n = 0; nd = NULL; For(j,2*tree->n_otu-2) { nd = tree->a_nodes[j]; if((t[nd->num] > ts[0] && t[nd->anc->num] < ts[0]) || // lineage that is crossing ts[0] (nd->tax == YES && Are_Equal(t[nd->num],ts[0],1.E-6) == YES)) // tip that is lying on ts[0] n++; } return LnGamma(n+1) + LOG(lbda) - 2.*lbda*T + (n-2.)*LOG(1. - EXP(-lbda*T)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the joint density of internal node heights assuming // the Yule model of speciation. phydbl TIMES_Lk_Yule_Joint(t_tree *tree) { int i,j; phydbl loglk; phydbl *t; phydbl dt; int n; // number of lineages at a given time point phydbl lbda; t_node *nd; phydbl *ts; int *tr; phydbl top_t; short int *interrupted; phydbl sumdt; interrupted = (short int *)mCalloc(tree->n_otu,sizeof(short int)); t = tree->rates->nd_t; ts = tree->rates->time_slice_lims; tr = tree->rates->t_rank; lbda = tree->rates->birth_rate; TIMES_Update_Node_Ordering(tree); For(j,tree->n_otu) interrupted[j] = NO; loglk = .0; sumdt = .0; n = 1; For(i,2*tree->n_otu-2) // t[tr[0]] is the time of the oldest node, t[tr[1]], the second oldest and so on... { For(j,tree->n_otu) if((t[j] < t[tr[i]]) && (interrupted[j] == NO)) { interrupted[j] = YES; n--; // How many lineages have stopped above t[tr[i]]? } top_t = t[tr[i+1]]; dt = top_t - t[tr[i]]; sumdt += dt; /* printf("\n. %d node up=%d [%f] node do=%d [%f] dt=%f",i,tr[i],t[tr[i]],tr[i+1],t[tr[i+1]],dt); */ if(n<1) { PhyML_Printf("\n== i=%d tr[i]=%f",i,t[tr[i]]); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(dt > 1.E-10) loglk += LOG((n+1)*lbda) - (n+1)*lbda*dt; n++; } /* printf("\n. sumdt = %f th=%f",sumdt,tree->rates->nd_t[tree->n_root->num]); */ /* printf("\n0 loglk = %f",loglk); */ For(i,tree->rates->n_time_slices-1) { n = 0; dt = 0.; For(j,2*tree->n_otu-2) { nd = tree->a_nodes[j]; if(t[nd->num] > ts[i] && t[nd->anc->num] < ts[i]) // How many lineages are crossing this time slice limit? { n++; if(t[nd->num] < dt) dt = t[nd->num]; // take the oldest node younger than the time slice } } dt -= ts[i]; loglk += LOG(n*lbda) - n*lbda*dt; } /* printf("\n1 loglk = %f",loglk); */ Free(interrupted); return loglk; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the conditional density of internal node heights // given the tree height under the Yule model. Uses the order // statistics 'simplification' as described in Yang and Rannala, 2005. phydbl TIMES_Lk_Yule_Order(t_tree *tree) { int j; phydbl *t,*tf; t_node *n; phydbl loglk; phydbl loglbda; phydbl lbda; phydbl *tp_min,*tp_max; phydbl lower_bound,upper_bound; /* phydbl root_height; */ tp_min = tree->rates->t_prior_min; tp_max = tree->rates->t_prior_max; tf = tree->rates->t_floor; t = tree->rates->nd_t; n = NULL; loglbda = LOG(tree->rates->birth_rate); lbda = tree->rates->birth_rate; lower_bound = -1.; upper_bound = -1.; /* root_height = FABS(tree->rates->nd_t[tree->n_root->num]); */ /*! Adapted from Equation (6) in T. Stadler's Systematic Biology, 2012 paper with sampling fraction set to 1 and death rate set to 0. Dropped the 1/(n-1) scaling factor. */ /* loglk = 0.0; */ /* For(j,2*tree->n_otu-2) */ /* { */ /* n = tree->a_nodes[j]; */ /* lower_bound = MAX(FABS(tf[j]),FABS(tp_max[j])); */ /* upper_bound = MIN(FABS(t[tree->n_root->num]),FABS(tp_min[j])); */ /* if(n->tax == NO) */ /* { */ /* loglk += (loglbda - lbda * FABS(t[j])); */ /* /\* loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */ /* } */ /* } */ /*! Adapted from Equation (7) in T. Stadler's Systematic Biology, 2012 paper with sampling fraction set to 1 and death rate set to 0. */ // Check that each node is within its calibration-derived interval For(j,2*tree->n_otu-1) if(t[j] < tp_min[j] || t[j] > tp_max[j]) return(-INFINITY); loglk = 0.0; For(j,2*tree->n_otu-2) { n = tree->a_nodes[j]; lower_bound = MAX(FABS(tf[j]),FABS(tp_max[j])); upper_bound = FABS(tp_min[j]); if(n->tax == NO) { loglk += (loglbda - lbda * FABS(t[j])); loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. } if(isinf(loglk) || isnan(loglk)) { /* PhyML_Printf("\n. Lower bound: %f",lower_bound); */ /* PhyML_Printf("\n. Upper bound: %f",upper_bound); */ /* PhyML_Printf("\n. tf: %f tp_max: %f tp_min: %f ",tf[j],tp_max[j],tp_min[j]); */ /* PhyML_Printf("\n. exp1: %f",EXP(-lbda*lower_bound)); */ /* PhyML_Printf("\n. exp2: %f",EXP(-lbda*upper_bound)); */ /* PhyML_Printf("\n. diff: %f",EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); */ /* Exit("\n"); */ return(-INFINITY); } } lower_bound = MAX(FABS(tf[tree->n_root->num]),FABS(tp_max[tree->n_root->num])); upper_bound = FABS(tp_min[tree->n_root->num]); loglk += LOG(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]); loglk -= LOG(EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound)); if(isinf(loglk) || isnan(loglk)) { /* PhyML_Printf("\n. * Lower bound: %f",lower_bound); */ /* PhyML_Printf("\n. * Upper bound: %f",upper_bound); */ /* PhyML_Printf("\n. * tf: %f tp_max: %f tp_min: %f",tf[tree->n_root->num],tp_max[tree->n_root->num],tp_min[tree->n_root->num]); */ /* PhyML_Printf("\n. * exp1: %f",EXP(-2.*lbda*lower_bound)); */ /* PhyML_Printf("\n. * exp2: %f",EXP(-2.*lbda*upper_bound)); */ /* PhyML_Printf("\n. * diff: %f",EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound)); */ /* Exit("\n"); */ return(-INFINITY); } return(loglk); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIMES_Lk_Times(t_tree *tree) { #ifdef PHYTIME tree->rates->c_lnL_times = TIMES_Lk_Yule_Order(tree); #elif INVITEE /* tree->rates->c_lnL_times = TIMES_Calib_Cond_Prob(tree); */ /* tree->rates->c_lnL_times = TIMES_Lk_Yule_Order(tree); */ tree->rates->c_lnL_times = TIMES_Lk_Yule_Order_Root_Cond(tree); if(isinf(tree->rates->c_lnL_times)) return(tree->rates->c_lnL_times); else { if(tree->rates->update_time_norm_const == YES) tree->rates->log_K_cur = K_Constant_Prior_Times_Log(tree); tree->rates->c_lnL_times += tree->rates->log_K_cur; } #endif return(tree->rates->c_lnL_times); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Lk_Times_Trav(t_node *a, t_node *d, phydbl lim_inf, phydbl lim_sup, phydbl *logdens, t_tree *tree) { int i; if(!d->tax) { /* if(tree->rates->nd_t[d->num] > lim_sup) */ /* { */ /* lim_inf = lim_sup; */ /* lim_sup = 0.0; */ /* For(i,2*tree->n_otu-2) */ /* if((tree->rates->t_floor[i] < lim_sup) && (tree->rates->t_floor[i] > tree->rates->nd_t[d->num])) */ /* lim_sup = tree->rates->t_floor[i]; */ /* } */ /* if(tree->rates->nd_t[d->num] < lim_inf || tree->rates->nd_t[d->num] > lim_sup) */ /* { */ /* PhyML_Printf("\n. nd_t = %f lim_inf = %f lim_sup = %f",tree->rates->nd_t[d->num],lim_inf,lim_sup); */ /* PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); */ /* Exit("\n"); */ /* } */ lim_inf = tree->rates->nd_t[tree->n_root->num]; lim_sup = tree->rates->t_floor[d->num]; *logdens = *logdens + LOG(lim_sup - lim_inf); } if(d->tax == YES) return; else { For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIMES_Lk_Times_Trav(d,d->v[i],lim_inf,lim_sup,logdens,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIMES_Log_Number_Of_Ranked_Labelled_Histories(t_node *root, int per_slice, t_tree *tree) { int i; phydbl logn; t_node *v1,*v2; int n1,n2; TIMES_Update_Curr_Slice(tree); logn = .0; v1 = v2 = NULL; if(root == tree->n_root) { TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(root,root->v[2],per_slice,&logn,tree); TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(root,root->v[1],per_slice,&logn,tree); v1 = root->v[2]; v2 = root->v[1]; } else { For(i,3) { if(root->v[i] != root->anc && root->b[i] != tree->e_root) { TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(root,root->v[i],per_slice,&logn,tree); if(!v1) v1 = root->v[i]; else v2 = root->v[i]; } } } if(per_slice == NO) { n1 = tree->rates->n_tips_below[v1->num]; n2 = tree->rates->n_tips_below[v2->num]; } else { if(tree->rates->curr_slice[v1->num] == tree->rates->curr_slice[root->num]) n1 = tree->rates->n_tips_below[v1->num]; else n1 = 1; if(tree->rates->curr_slice[v2->num] == tree->rates->curr_slice[root->num]) n2 = tree->rates->n_tips_below[v2->num]; else n2 = 1; } tree->rates->n_tips_below[root->num] = n1+n2; logn += Factln(n1+n2-2) - Factln(n1-1) - Factln(n2-1); return(logn); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(t_node *a, t_node *d, int per_slice, phydbl *logn, t_tree *tree) { if(d->tax == YES) { tree->rates->n_tips_below[d->num] = 1; return; } else { int i,n1,n2; t_node *v1, *v2; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(d,d->v[i],per_slice,logn,tree); } } v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(v1 == NULL) {v1 = d->v[i];} else {v2 = d->v[i];} } } if(per_slice == NO) { n1 = tree->rates->n_tips_below[v1->num]; n2 = tree->rates->n_tips_below[v2->num]; } else { if(tree->rates->curr_slice[v1->num] == tree->rates->curr_slice[d->num]) n1 = tree->rates->n_tips_below[v1->num]; else n1 = 1; if(tree->rates->curr_slice[v2->num] == tree->rates->curr_slice[d->num]) n2 = tree->rates->n_tips_below[v2->num]; else n2 = 1; } tree->rates->n_tips_below[d->num] = n1+n2; (*logn) += Factln(n1+n2-2) - Factln(n1-1) - Factln(n2-1); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Update_Curr_Slice(t_tree *tree) { int i,j; For(i,2*tree->n_otu-1) { For(j,tree->rates->n_time_slices) { if(!(tree->rates->nd_t[i] > tree->rates->time_slice_lims[j])) break; } tree->rates->curr_slice[i] = j; /* PhyML_Printf("\n. Node %3d [%12f] is in slice %3d.",i,tree->rates->nd_t[i],j); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIMES_Lk_Uniform_Core(t_tree *tree) { phydbl logn; logn = TIMES_Log_Number_Of_Ranked_Labelled_Histories(tree->n_root,YES,tree); tree->rates->c_lnL_times = 0.0; TIMES_Lk_Uniform_Post(tree->n_root,tree->n_root->v[2],tree); TIMES_Lk_Uniform_Post(tree->n_root,tree->n_root->v[1],tree); /* printf("\n. ^ %f %f %f", */ /* (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.), */ /* LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */ /* tree->rates->nd_t[tree->n_root->num]), */ /* (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.) * */ /* LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - */ /* tree->rates->nd_t[tree->n_root->num])); */ tree->rates->c_lnL_times += Factln(tree->rates->n_tips_below[tree->n_root->num]-2.) - (phydbl)(tree->rates->n_tips_below[tree->n_root->num]-2.) * LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[tree->n_root->num]] - tree->rates->nd_t[tree->n_root->num]); tree->rates->c_lnL_times -= logn; return(tree->rates->c_lnL_times); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Get_Number_Of_Time_Slices(t_tree *tree) { int i; tree->rates->n_time_slices=0; TIMES_Get_Number_Of_Time_Slices_Post(tree->n_root,tree->n_root->v[2],tree); TIMES_Get_Number_Of_Time_Slices_Post(tree->n_root,tree->n_root->v[1],tree); Qksort(tree->rates->time_slice_lims,NULL,0,tree->rates->n_time_slices-1); if(tree->rates->n_time_slices > 1) { PhyML_Printf("\n"); PhyML_Printf("\n. Sequences were collected at %d different time points.",tree->rates->n_time_slices); For(i,tree->rates->n_time_slices) printf("\n+ [%3d] time point @ %12f ",i+1,tree->rates->time_slice_lims[i]); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Get_Number_Of_Time_Slices_Post(t_node *a, t_node *d, t_tree *tree) { int i; if(d->tax == YES) { For(i,tree->rates->n_time_slices) if(Are_Equal(tree->rates->t_floor[d->num],tree->rates->time_slice_lims[i],1.E-6)) break; if(i == tree->rates->n_time_slices) { tree->rates->time_slice_lims[i] = tree->rates->t_floor[d->num]; tree->rates->n_time_slices++; } return; } else { For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) TIMES_Get_Number_Of_Time_Slices_Post(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Get_N_Slice_Spans(t_tree *tree) { int i,j; For(i,2*tree->n_otu-2) { if(tree->a_nodes[i]->tax == NO) { For(j,tree->rates->n_time_slices) { if(Are_Equal(tree->rates->t_floor[i],tree->rates->time_slice_lims[j],1.E-6)) { tree->rates->n_time_slice_spans[i] = j+1; /* PhyML_Printf("\n. Node %3d spans %3d slices [%12f].", */ /* i+1, */ /* tree->rates->n_slice_spans[i], */ /* tree->rates->t_floor[i]); */ break; } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Lk_Uniform_Post(t_node *a, t_node *d, t_tree *tree) { if(d->tax == YES) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIMES_Lk_Uniform_Post(d,d->v[i],tree); } } if(tree->rates->curr_slice[a->num] != tree->rates->curr_slice[d->num]) { tree->rates->c_lnL_times += Factln(tree->rates->n_tips_below[d->num]-1.) - (phydbl)(tree->rates->n_tips_below[d->num]-1.) * LOG(tree->rates->time_slice_lims[tree->rates->curr_slice[d->num]] - tree->rates->nd_t[d->num]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Set the root position so that most of the taxa in the outgroup correspond to the most ancient time point. */ void TIMES_Set_Root_Given_Tip_Dates(t_tree *tree) { int i,j; t_node *left,*rght; int n_left_in, n_left_out; int n_rght_in, n_rght_out; t_edge *b,*best; phydbl eps,score,max_score; Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); left = rght = NULL; b = best = NULL; n_left_in = n_left_out = -1; n_rght_in = n_rght_out = -1; eps = 1.E-6; score = max_score = -1.; For(i,2*tree->n_otu-3) { left = tree->a_edges[i]->left; rght = tree->a_edges[i]->rght; b = tree->a_edges[i]; n_left_in = 0; For(j,left->bip_size[b->l_r]) if(FABS(tree->rates->nd_t[left->bip_node[b->l_r][j]->num] - tree->rates->time_slice_lims[0]) < eps) n_left_in++; n_left_out = left->bip_size[b->l_r]-n_left_in; n_rght_in = 0; For(j,rght->bip_size[b->r_l]) if(FABS(tree->rates->nd_t[rght->bip_node[b->r_l][j]->num] - tree->rates->time_slice_lims[0]) < eps) n_rght_in++; n_rght_out = rght->bip_size[b->r_l]-n_rght_in; /* score = POW((phydbl)(n_left_in)/(phydbl)(n_left_in+n_left_out)- */ /* (phydbl)(n_rght_in)/(phydbl)(n_rght_in+n_rght_out),2); */ /* score = (phydbl)(n_left_in * n_rght_out + eps)/(n_left_out * n_rght_in + eps); */ /* score = (phydbl)(n_left_in * n_rght_out + eps); */ score = FABS((phydbl)((n_left_in+1.) * (n_rght_out+1.)) - (phydbl)((n_left_out+1.) * (n_rght_in+1.))); if(score > max_score) { max_score = score; best = b; } } Add_Root(best,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Survival_Duration(t_tree *tree) { Get_Survival_Duration_Post(tree->n_root,tree->n_root->v[2],tree); Get_Survival_Duration_Post(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Survival_Duration_Post(t_node *a, t_node *d, t_tree *tree) { if(d->tax) { tree->rates->survival_dur[d->num] = tree->rates->nd_t[d->num]; return; } else { int i; t_node *v1, *v2; For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) Get_Survival_Duration_Post(d,d->v[i],tree); v1 = v2 = NULL; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(!v1) v1 = d->v[i]; else v2 = d->v[i]; } } tree->rates->survival_dur[d->num] = MAX(tree->rates->survival_dur[v1->num], tree->rates->survival_dur[v2->num]); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Update the ranking of node heights. Use bubble sort algorithm */ void TIMES_Update_Node_Ordering(t_tree *tree) { int buff; int i; phydbl *t; int swap = NO; t = tree->rates->nd_t; do { swap = NO; For(i,2*tree->n_otu-2) { if(t[tree->rates->t_rank[i]] > t[tree->rates->t_rank[i+1]]) // Sort in ascending order { swap = YES; buff = tree->rates->t_rank[i]; tree->rates->t_rank[i] = tree->rates->t_rank[i+1]; tree->rates->t_rank[i+1] = buff; } } } while(swap == YES); /* For(i,2*tree->n_otu-1) */ /* { */ /* printf("\n. ..... %f",t[tree->rates->t_rank[i]]); */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Label_Edges_With_Calibration_Intervals(t_tree *tree) { char *s; int i; s = (char *)mCalloc(T_MAX_LINE,sizeof(char)); tree->write_labels = YES; For(i,2*tree->n_otu-2) { if(tree->a_nodes[i]->tax == NO) { if(tree->rates->t_has_prior[i] == YES && tree->a_nodes[i]->b[0] != tree->e_root) { tree->a_nodes[i]->b[0]->n_labels = 1; Make_New_Edge_Label(tree->a_nodes[i]->b[0]); sprintf(s,"'>%f<%f'",FABS(tree->rates->t_prior_max[i])/100.,FABS(tree->rates->t_prior_min[i])/100.); tree->a_nodes[i]->b[0]->labels[0] = (char *)mCalloc(strlen(s)+1,sizeof(char)); strcpy(tree->a_nodes[i]->b[0]->labels[0],s); } } } Free(s); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Set_Calibration(t_tree *tree) { t_cal *cal; int i; For(i,2*tree->n_otu-1) { tree->rates->t_has_prior[i] = NO; tree->rates->t_prior_min[i] = BIG; tree->rates->t_prior_max[i] = BIG; } cal = tree->rates->calib; while(cal) { /* if(cal->is_active == YES) */ /* { */ /* tree->rates->t_has_prior[cal->node_num] = YES; */ /* tree->rates->t_prior_min[cal->node_num] = cal->lower; */ /* tree->rates->t_prior_max[cal->node_num] = cal->upper; */ /* } */ cal = cal->next; } TIMES_Set_All_Node_Priors(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Record_Prior_Times(t_tree *tree) { int i; For(i,2*tree->n_otu-1) { tree->rates->t_prior_min_ori[i] = tree->rates->t_prior_min[i]; tree->rates->t_prior_max_ori[i] = tree->rates->t_prior_max[i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIMES_Reset_Prior_Times(t_tree *tree) { int i; For(i,2*tree->n_otu-1) { tree->rates->t_prior_min[i] = tree->rates->t_prior_min_ori[i]; tree->rates->t_prior_max[i] = tree->rates->t_prior_max_ori[i]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the conditional density of internal node heights // given the tree height under the Yule model. Uses the order // statistics 'simplification' as described in Yang and Rannala, 2005. phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree) { int j; phydbl *t,*tf; t_node *n; phydbl loglk; phydbl loglbda; phydbl lbda; phydbl *tp_min,*tp_max; phydbl lower_bound,upper_bound; phydbl root_height; tp_min = tree->rates->t_prior_min; tp_max = tree->rates->t_prior_max; tf = tree->rates->t_floor; t = tree->rates->nd_t; n = NULL; loglbda = LOG(tree->rates->birth_rate); lbda = tree->rates->birth_rate; lower_bound = -1.; upper_bound = -1.; root_height = FABS(tree->rates->nd_t[tree->n_root->num]); /*! Adapted from Equation (6) in T. Stadler's Systematic Biology, 2012 paper with sampling fraction set to 1 and death rate set to 0. Dropped the 1/(n-1) scaling factor. */ /* loglk = 0.0; */ /* For(j,2*tree->n_otu-2) */ /* { */ /* n = tree->a_nodes[j]; */ /* lower_bound = MAX(FABS(tf[j]),FABS(tp_max[j])); */ /* upper_bound = MIN(FABS(t[tree->n_root->num]),FABS(tp_min[j])); */ /* if(n->tax == NO) */ /* { */ /* loglk += (loglbda - lbda * FABS(t[j])); */ /* /\* loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. *\/ */ /* } */ /* } */ /*! Adapted from Equation (7) in T. Stadler's Systematic Biology, 2012 paper with sampling fraction set to 1 and death rate set to 0. */ // Check that each node is within its calibration-derived interval For(j,2*tree->n_otu-1) if(t[j] < tp_min[j] || t[j] > tp_max[j]) return(-INFINITY); loglk = 0.0; For(j,2*tree->n_otu-2) { n = tree->a_nodes[j]; lower_bound = MAX(FABS(tf[j]),FABS(tp_max[j])); upper_bound = MIN(FABS(tp_min[j]),root_height); if(n->tax == NO) { loglk += (loglbda - lbda * FABS(t[j])); loglk -= LOG(EXP(-lbda*lower_bound) - EXP(-lbda*upper_bound)); // incorporate calibration boundaries here. } if(isinf(loglk) || isnan(loglk)) { PhyML_Printf("\n. Lower bound: %f",lower_bound); PhyML_Printf("\n. Upper bound: %f",upper_bound); PhyML_Printf("\n. tf: %f tp_max: %f tp_min: %f root: %f",tf[j],tp_max[j],tp_min[j],root_height); Exit("\n"); } } /* lower_bound = MAX(FABS(tf[tree->n_root->num]),FABS(tp_max[tree->n_root->num])); */ /* upper_bound = FABS(tp_min[tree->n_root->num]); */ /* loglk += LOG(2) + loglbda - 2.*lbda * FABS(t[tree->n_root->num]); */ /* loglk -= LOG(EXP(-2.*lbda*lower_bound) - EXP(-2.*lbda*upper_bound)); */ return(loglk); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/times.h000066400000000000000000000066701263450375500147510ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef TIMES_H #define TIMES_H #include "utilities.h" int TIMES_main(int argc, char **argv); void TIMES_Bl_From_T_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree); void TIMES_Bl_From_T(t_tree *tree); void TIMES_Optimize_Node_Times_Serie(t_node *a, t_node *d, t_tree *tree); void TIMES_Round_Optimize(t_tree *tree); void TIMES_Print_Node_Times(t_node *a, t_node *d, t_tree *tree); t_edge *TIMES_Find_Best_Root_Position(t_tree *tree); void TIMES_Least_Square_Node_Times(t_edge *e_root, t_tree *tree); void TIMES_Least_Square_Node_Times_Pre(t_node *a, t_node *d, phydbl *A, phydbl *b, int n, t_tree *tree); void TIMES_Mult_Time_Stamps(t_tree *tree); void TIMES_Div_Time_Stamps(t_tree *tree); void TIMES_Optimize_Tree_Height(t_tree *tree); void TIMES_Adjust_Node_Times(t_tree *tree); void TIMES_Adjust_Node_Times_Pre(t_node *a, t_node *d, t_tree *tree); void TIMES_Optimize_Root_Height(t_tree *tree); void TIMES_Estimate_Branch_Rates(t_tree *tree); t_edge *TIMES_Find_Best_Root_Position_Approx(t_tree *tree); void TIMES_Estimate_Branch_Rate_Parameter(t_tree *tree); phydbl TIMES_Classify_Branch_In_Rate_Class(t_tree *tree); void TIMES_Compute_Rates_And_Times_Least_Square_Adjustments(t_tree *tree); void TIMES_Compute_Rates_And_Times_Least_Square_Adjustments_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree); void TIMES_Classify_Branch_Rates(t_tree *tree); int TIMES_Check_MC(t_tree *tree); void TIMES_Set_All_Node_Priors(t_tree *tree); void TIMES_Set_All_Node_Priors_Bottom_Up(t_node *a, t_node *d, t_tree *tree); void TIMES_Set_All_Node_Priors_Top_Down(t_node *a, t_node *d, t_tree *tree); void TIMES_Set_Floor(t_tree *tree); void TIMES_Set_Floor_Post(t_node *a, t_node *d, t_tree *tree); phydbl TIMES_Log_Conditional_Uniform_Density(t_tree *tree); phydbl TIMES_Log_Yule(t_tree *tree); phydbl TIMES_Lk_Times(t_tree *tree); void TIMES_Lk_Times_Trav(t_node *a, t_node *d, phydbl lim_inf, phydbl lim_sup, phydbl *logdens, t_tree *tree); phydbl TIMES_Log_Number_Of_Ranked_Labelled_Histories(t_node *root, int per_slice, t_tree *tree); void TIMES_Log_Number_Of_Ranked_Labelled_Histories_Post(t_node *a, t_node *d, int per_slice, phydbl *logn, t_tree *tree); phydbl TIMES_Lk_Uniform_Core(t_tree *tree); void TIMES_Get_Number_Of_Time_Slices(t_tree *tree); void TIMES_Get_Number_Of_Time_Slices_Post(t_node *a, t_node *d, t_tree *tree); void TIMES_Get_N_Slice_Spans(t_tree *tree); void TIMES_Allocate_Vectors_Time_Slice_Combin(t_tree *tree); void TIMES_Allocate_Vectors_Time_Slice_Combin_Post(t_node *a, t_node *d, t_tree *tree); void TIMES_Update_Curr_Slice(t_tree *tree); void TIMES_Lk_Uniform_Post(t_node *a, t_node *d, t_tree *tree); void TIMES_Set_Root_Given_Tip_Dates(t_tree *tree); void Get_Survival_Duration(t_tree *tree); void Get_Survival_Duration_Post(t_node *a, t_node *d, t_tree *tree); phydbl TIMES_Lk_Yule_Root_Marginal(t_tree *tree); phydbl TIMES_Lk_Yule_Joint(t_tree *tree); void TIMES_Update_Node_Ordering(t_tree *tree); phydbl TIMES_Lk_Yule_Order(t_tree *tree); void TIMES_Label_Edges_With_Calibration_Intervals(t_tree *tree); void TIMES_Record_Prior_Times(t_tree *tree); void TIMES_Reset_Prior_Times(t_tree *tree); phydbl TIMES_Lk_Yule_Order_Root_Cond(t_tree *tree); #endif phyml-3.2.0/src/tiporder.c000066400000000000000000001112201263450375500154370ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phyLOGenies from DNA or AA homoLOGous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ /* Routines for molecular clock trees and molecular dating */ #include "tiporder.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* int TIPO_main(int argc, char **argv) */ /* { */ /* t_tree **list_tree,*ref_tree,*tree; */ /* FILE *fp_ref_tree,*fp_list_tree,*fp_coord,*ps_tree; */ /* int i,j,k; */ /* int n_trees; */ /* option *ref_io,*list_io; */ /* char **name_table; */ /* int r_seed; */ /* r_seed = time(NULL); */ /* srand(r_seed); */ /* ref_io = (option *)Make_Input(); */ /* list_io = (option *)Make_Input(); */ /* fp_ref_tree = (FILE *)fopen(argv[1],"r"); */ /* fp_list_tree = (FILE *)fopen(argv[2],"r"); */ /* fp_coord = (FILE *)fopen(argv[3],"r"); */ /* if(!fp_ref_tree) */ /* { */ /* PhyML_Printf("\n. Can't find %s",argv[1]); */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* if(!fp_list_tree) */ /* { */ /* PhyML_Printf("\n. Can't find %s",argv[2]); */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* ref_io->fp_in_tree = fp_ref_tree; */ /* Read_Tree_File(ref_io); */ /* fclose(ref_io->fp_in_tree); */ /* ref_tree = ref_io->treelist->tree[0]; */ /* ref_tree->io = ref_io; */ /* list_io->fp_in_tree = fp_list_tree; */ /* Read_Tree_File(list_io); */ /* fclose(list_io->fp_in_tree); */ /* list_tree = list_io->treelist->tree; */ /* n_trees = list_io->treelist->list_size; */ /* PhyML_Printf("\n. Read %d trees\n",n_trees); */ /* For(i,n_trees) list_tree[i]->io = list_io; */ /* name_table = (char **)mCalloc(ref_tree->n_otu,sizeof(char **)); */ /* For(i,ref_tree->n_otu) name_table[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); */ /* /\* Sort translation table such that tree->a_nodes[i]->name == tree->io->short_tax_name[i] for all i *\/ */ /* TIPO_Sort_Translation_Table(ref_tree); */ /* ref_tree->io->z_scores = (phydbl *)mCalloc(ref_tree->n_otu,sizeof(phydbl)); */ /* /\* TIPO_Read_Taxa_Zscores(fp_coord,ref_tree); *\/ */ /* For(i,ref_tree->n_otu) ref_tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord,ref_tree->a_nodes[i]->name,ref_tree); */ /* TIPO_Normalize_Zscores(ref_tree); */ /* /\* Find matching tips *\/ */ /* For(i,n_trees) */ /* { */ /* TIPO_Sort_Translation_Table(list_tree[i]); */ /* For(j,ref_tree->n_otu) */ /* { */ /* For(k,ref_tree->n_otu) */ /* { */ /* if(!strcmp(ref_io->long_tax_names[j],list_io->long_tax_names[k])) */ /* { */ /* list_tree[i]->a_nodes[k]->ext_node = ref_tree->a_nodes[j]; */ /* break; */ /* } */ /* } */ /* if(k == ref_tree->n_otu) */ /* { */ /* PhyML_Printf("\n. Could not find matching tips for \"%s\" (tree %d)",ref_tree->a_nodes[j]->name,i); */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* } */ /* } */ /* PhyML_Printf("\n. Getting ancestors"); fflush(NULL); */ /* Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[2],ref_tree); */ /* Update_Ancestors(ref_tree->n_root,ref_tree->n_root->v[1],ref_tree); */ /* For(i,n_trees) */ /* { */ /* Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[2],list_tree[i]); */ /* Update_Ancestors(list_tree[i]->n_root,list_tree[i]->n_root->v[1],list_tree[i]); */ /* list_tree[i]->n_root->anc = NULL; */ /* } */ /* PhyML_Printf("\n. Getting bipartitions"); fflush(NULL); */ /* Free_Bip(ref_tree); */ /* Alloc_Bip(ref_tree); */ /* Get_Bip(ref_tree->a_nodes[0], */ /* ref_tree->a_nodes[0]->v[0], */ /* ref_tree); */ /* For(i,n_trees) */ /* { */ /* if(!(i%10)) */ /* PhyML_Printf("\n. Getting bipartition for tree %d",i); */ /* Free_Bip(list_tree[i]); */ /* Alloc_Bip(list_tree[i]); */ /* Get_Bip(list_tree[i]->a_nodes[0], */ /* list_tree[i]->a_nodes[0]->v[0], */ /* list_tree[i]); */ /* } */ /* PhyML_Printf("\n. Getting tip ranks"); fflush(NULL); */ /* /\* TIPO_Get_Tips_Y_Rank(ref_tree); *\/ */ /* TIPO_Get_Tips_Y_Rank_From_Zscores(ref_tree); */ /* /\* PhyML_Printf("\n. Minimizing"); fflush(NULL); *\/ */ /* /\* TIPO_Minimize_Tip_Order_Score(n_trees,list_tree,ref_tree); *\/ */ /* PhyML_Printf("\n. N_OTU = %d",ref_tree->n_otu); */ /* TIPO_Untangle_Tree(ref_tree); */ /* PhyML_Printf("\n ** ORIGINAL %f",ref_tree->tip_order_score); */ /* /\* i = 0; *\/ */ /* /\* do *\/ */ /* /\* { *\/ */ /* /\* /\\* TIPO_Get_Tips_Y_Rank_From_Zscores(ref_tree); *\\/ *\/ */ /* /\* TIPO_Randomize_Tip_Y_Ranks(ref_tree); *\/ */ /* /\* TIPO_Untangle_Tree(ref_tree); *\/ */ /* /\* PhyML_Printf("\n ** %f",ref_tree->tip_order_score); *\/ */ /* /\* i++; *\/ */ /* /\* }while(i < 5000); *\/ */ /* Test_Node_Table_Consistency(ref_tree); */ /* ref_tree->ps_tree = DR_Make_Tdraw_Struct(ref_tree); */ /* DR_Get_Tree_Coord(ref_tree); */ /* For(j,ref_tree->n_otu) */ /* { */ /* ref_tree->ps_tree->ycoord[j] = */ /* (ref_tree->a_nodes[j]->y_rank/ref_tree->n_otu)* */ /* ref_tree->ps_tree->page_height; */ /* } */ /* ps_tree = (FILE *)fopen("order_tree.ps","w"); */ /* list_io->z_scores = (phydbl *)mCalloc(ref_tree->n_otu,sizeof(phydbl)); */ /* DR_Print_Postscript_Header(1,ps_tree); */ /* For(i,n_trees) */ /* { */ /* tree = list_tree[i]; */ /* Test_Node_Table_Consistency(tree); */ /* tree->rates = RATES_Make_Rate_Struct(tree->n_otu); */ /* RATES_Init_Rate_Struct(tree->rates,tree->n_otu); */ /* TIMES_Least_Square_Node_Times(tree->e_root,tree); */ /* TIMES_Adjust_Node_Times(tree); */ /* RATES_Update_Cur_Bl(tree); */ /* tree->ps_tree = DR_Make_Tdraw_Struct(tree); */ /* DR_Init_Tdraw_Struct(tree->ps_tree); */ /* DR_Get_Tree_Box_Width(tree->ps_tree,tree); */ /* Dist_To_Root(tree->n_root,tree); */ /* tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); */ /* For(j,ref_tree->n_otu) tree->io->z_scores[j] = ref_tree->io->z_scores[tree->a_nodes[j]->ext_node->num]; */ /* TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */ /* TIPO_Untangle_Tree(tree); */ /* For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] = (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */ /* /\* For(j,ref_tree->n_otu) tree->ps_tree->ycoord[j] = ref_tree->ps_tree->ycoord[tree->a_nodes[j]->ext_node->num]; *\/ */ /* For(j,ref_tree->n_otu) list_io->z_scores[j] = ref_io->z_scores[tree->a_nodes[j]->ext_node->num]; */ /* DR_Get_Y_Coord(YES,tree->ps_tree,tree); */ /* DR_Get_X_Coord( NO,tree->ps_tree,tree); */ /* if(!i) DR_Print_Tree_Postscript(1,YES,ps_tree,tree); */ /* else DR_Print_Tree_Postscript(1, NO,ps_tree,tree); */ /* } */ /* DR_Print_Postscript_EOF(ps_tree); */ /* fclose(ps_tree); */ /* ps_tree = (FILE *)fopen("ref_tree.ps","w"); */ /* DR_Print_Postscript_Header(1,ps_tree); */ /* tree = ref_tree; */ /* tree->rates = RATES_Make_Rate_Struct(tree->n_otu); */ /* RATES_Init_Rate_Struct(tree->rates,tree->n_otu); */ /* TIMES_Least_Square_Node_Times(tree->e_root,tree); */ /* TIMES_Adjust_Node_Times(tree); */ /* RATES_Update_Cur_Bl(tree); */ /* DR_Init_Tdraw_Struct(tree->ps_tree); */ /* DR_Get_Tree_Box_Width(tree->ps_tree,tree); */ /* Dist_To_Root(tree->n_root,tree); */ /* tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); */ /* TIPO_Get_Tips_Y_Rank_From_Zscores(tree); */ /* /\* TIPO_Untangle_Tree(tree); *\/ */ /* For(j,tree->n_otu) tree->ps_tree->ycoord[j] = (tree->a_nodes[j]->y_rank/tree->n_otu)*tree->ps_tree->page_height; */ /* DR_Get_Y_Coord(YES,tree->ps_tree,tree); */ /* DR_Get_X_Coord( NO,tree->ps_tree,tree); */ /* DR_Print_Tree_Postscript(1,YES,ps_tree,tree); */ /* DR_Print_Postscript_EOF(ps_tree); */ /* fclose(ps_tree); */ /* PhyML_Printf("\n"); */ /* fclose(fp_ref_tree); */ /* fclose(fp_list_tree); */ /* fclose(fp_coord); */ /* } */ int TIPO_main(int argc, char **argv) { t_tree *tree; option *io; FILE *fp_tree_file, *fp_coord_file; int i; /* Rprintf("%s\n",tree_file_name[0]); */ /* Rprintf("%s\n",coord_file_name[0]); */ srand(time(NULL)); rand(); fp_tree_file = (FILE *)fopen(argv[1],"r"); fp_coord_file = (FILE *)fopen(argv[2],"r"); io = (option *)Make_Input(); io->fp_in_tree = fp_tree_file; Read_Tree_File(io); tree = io->treelist->tree[0]; tree->io = io; tree->io->z_scores = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl)); For(i,tree->n_otu) tree->io->z_scores[i] = TIPO_Read_One_Taxon_Zscore(fp_coord_file,tree->a_nodes[i]->name,1,tree); /* TIPO_Normalize_Zscores(tree); */ Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); TIPO_Get_Tips_Y_Rank_From_Zscores(tree); /* TIPO_Get_Tips_Y_Rank(tree); */ tree->geo_mig_sd = 0.1; Generic_Brent_Lk(&(tree->geo_mig_sd), 1.E-3,1.E+2,1.E-6, 100,NO, &Wrap_Geo_Lk, NULL,tree,NULL,NO); PhyML_Printf("\n. sd=%f",tree->geo_mig_sd); fclose(fp_tree_file); fclose(fp_coord_file); return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Z_scores have already been recorder here */ void TIPO_Get_Min_Number_Of_Tip_Permut(t_tree *tree) { Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); TIPO_Get_Tips_Y_Rank_From_Zscores(tree); TIPO_Untangle_Tree(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Get_Tips_Y_Rank(t_tree *tree) { phydbl curr_rank; curr_rank = .0; TIPO_Get_Tips_Y_Rank_Pre(tree->n_root,tree->n_root->v[2],&curr_rank,tree); TIPO_Get_Tips_Y_Rank_Pre(tree->n_root,tree->n_root->v[1],&curr_rank,tree); if(curr_rank != tree->n_otu) { PhyML_Printf("\n. tree->n_otu = %d curr_rank = %d",tree->n_otu,curr_rank); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Get_Tips_Y_Rank_Pre(t_node *a, t_node *d, phydbl *curr_rank, t_tree *tree) { if(d->tax) { d->y_rank = *curr_rank; *curr_rank += 1.; return; } else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIPO_Get_Tips_Y_Rank_Pre(d,d->v[i],curr_rank,tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Get_All_Y_Rank(t_tree *tree) { tree->sum_y_dist_sq = .0; tree->sum_y_dist = .0; TIPO_Get_All_Y_Rank_Pre(tree->n_root,tree->n_root->v[2],tree); TIPO_Get_All_Y_Rank_Pre(tree->n_root,tree->n_root->v[1],tree); tree->n_root->y_rank = (tree->n_root->v[2]->y_rank+tree->n_root->v[1]->y_rank)/2.; tree->n_root->y_rank_min = MIN(tree->n_root->v[2]->y_rank_min,tree->n_root->v[1]->y_rank_min); tree->n_root->y_rank_max = MAX(tree->n_root->v[2]->y_rank_max,tree->n_root->v[1]->y_rank_max); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Get_All_Y_Rank_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) { d->y_rank_min = d->y_rank; d->y_rank_max = d->y_rank; return; } else { int i; int dir1,dir2; phydbl v1,v2; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIPO_Get_All_Y_Rank_Pre(d,d->v[i],tree); } } dir1 = dir2 = -1; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(dir1 < 0) dir1 = i; else dir2 = i; } } v1 = d->v[dir1]->y_rank; v2 = d->v[dir2]->y_rank; d->y_rank = (v1+v2)/2.; tree->sum_y_dist_sq += POW(v1-v2,2); tree->sum_y_dist += FABS(v1-v2); d->y_rank_min = MIN(d->v[dir1]->y_rank_min,d->v[dir2]->y_rank_min); d->y_rank_max = MAX(d->v[dir1]->y_rank_max,d->v[dir2]->y_rank_max); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Swap_One_Node(t_node *d, t_tree *tree) { if(d->tax) return; else { int i; int dir1, dir2; t_node *tmp_n; t_edge *tmp_e; if(d != tree->n_root) { dir1 = dir2 = -1; For(i,3) { if((d->v[i] != d->anc) && (d->b[i] != tree->e_root)) { if(dir1 < 0) dir1 = i; else dir2 = i; } } } else { dir1 = 0; dir2 = 1; } tmp_n = d->v[dir2]; d->v[dir2] = d->v[dir1]; d->v[dir1] = tmp_n; tmp_e = d->b[dir2]; d->b[dir2] = d->b[dir1]; d->b[dir1] = tmp_e; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_tree) { int i,j; phydbl score,min_score,old_min_score; phydbl diff,eps; t_node **node_table; int swapped; t_node *tmp; eps = 1.E-3; old_min_score = min_score = score = INT_MAX; /* TIPO_Print_Tip_Ordered(ref_tree); */ do { for(i=ref_tree->n_otu;i<2*ref_tree->n_otu-1;i++) { TIPO_Swap_One_Node(ref_tree->a_nodes[i],ref_tree); TIPO_Get_Tips_Y_Rank(ref_tree); score = (phydbl)TIPO_Untangle_Tree_List(n_trees,list_tree,ref_tree); if(score == -1) { return; } if(score < min_score) { min_score = score; PhyML_Printf("\n- Score = %f",score); } else { TIPO_Swap_One_Node(ref_tree->a_nodes[i],ref_tree); TIPO_Get_Tips_Y_Rank(ref_tree); /* PhyML_Printf("\n+ Score = %f",score); */ } } diff = fabs(old_min_score - min_score); old_min_score = min_score; }while(diff > eps); PhyML_Printf("\n"); node_table = (t_node **)mCalloc(ref_tree->n_otu,sizeof(t_node *)); For(i,ref_tree->n_otu) { For(j,ref_tree->n_otu) { if(!strcmp(ref_tree->io->short_tax_names[i],ref_tree->a_nodes[j]->name)) { Free(ref_tree->a_nodes[j]->name); ref_tree->a_nodes[j]->name = (char *)mCalloc((int)strlen(ref_tree->io->long_tax_names[i])+1,sizeof(char)); strcpy(ref_tree->a_nodes[j]->name,ref_tree->io->long_tax_names[i]); break; } } } For(i,ref_tree->n_otu) node_table[i] = ref_tree->a_nodes[i]; /* bubble sort of conflict nodes according to their y_rank */ do { swapped = NO; For(i,ref_tree->n_otu-1) { if(node_table[i]->y_rank > node_table[i+1]->y_rank) { swapped = YES; tmp = node_table[i]; node_table[i] = node_table[i+1]; node_table[i+1] = tmp; } } }while(swapped == YES); For(i,ref_tree->n_otu) { PhyML_Printf("\n%s",node_table[i]->name,node_table[i]->y_rank); } Free(node_table); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Print_Tip_Ordered(t_tree *tree) { TIPO_Print_Tip_Ordered_Pre(tree->n_root,tree->n_root->v[2],tree); TIPO_Print_Tip_Ordered_Pre(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Print_Tip_Ordered_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) { PhyML_Printf("\n. %f \"%s\"",d->y_rank,d->name); } else { int i,dir1,dir2; dir1 = dir2 = -1; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root)) { if(dir1 < 0) dir1 = i; else dir2 = i; } } if(d->v[dir1]->y_rank < d->v[dir2]->y_rank) { TIPO_Print_Tip_Ordered_Pre(d,d->v[dir1],tree); TIPO_Print_Tip_Ordered_Pre(d,d->v[dir2],tree); } else { TIPO_Print_Tip_Ordered_Pre(d,d->v[dir2],tree); TIPO_Print_Tip_Ordered_Pre(d,d->v[dir1],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int TIPO_Untangle_Tree_List(int n_trees, t_tree **list_tree, t_tree *ref_tree) { int i,j; int tree_score,score; score = 0; For(i,n_trees) { /* PhyML_Printf("\n. Untangling tree %3d",i); */ For(j,ref_tree->n_otu) list_tree[i]->a_nodes[j]->y_rank = list_tree[i]->a_nodes[j]->ext_node->y_rank; tree_score = TIPO_Untangle_Tree(list_tree[i]); /* PhyML_Printf(" score = %3d",tree_score); */ score += tree_score; if(tree_score < 0) { return -1; } } return score; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIPO_Untangle_Tree(t_tree *tree) { int conflict; int n_trials; t_node **node_table; int i,swapped; t_node *tmp; node_table = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); For(i,tree->n_otu) node_table[i] = tree->a_nodes[i]; For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank; /* bubble sort of nodes according to their y_rank */ do { swapped = NO; For(i,tree->n_otu-1) { if(node_table[i]->y_rank > node_table[i+1]->y_rank) { swapped = YES; tmp = node_table[i]; node_table[i] = node_table[i+1]; node_table[i+1] = tmp; } } } while(swapped == YES); /* Work out the y_rank values for every internal node given the external node ranks */ TIPO_Get_All_Y_Rank(tree); tree->tip_order_score = .0; n_trials = 0; do { conflict= NO; /* Recusrssive untangling of the tree */ TIPO_Untangle_Node(tree->n_root,tree->n_root->v[2],node_table,&conflict,tree); TIPO_Untangle_Node(tree->n_root,tree->n_root->v[1],node_table,&conflict,tree); n_trials++; if(n_trials > 2) /* We should have been able to untangle the tree after just one tree traversal */ { int i; FILE *ps_tree; PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); ps_tree = (FILE *)fopen("failed_tree.ps","w"); Test_Node_Table_Consistency(tree); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,tree->io->rates,tree->n_otu); TIMES_Least_Square_Node_Times(tree->e_root,tree); TIMES_Adjust_Node_Times(tree); RATES_Update_Cur_Bl(tree); DR_Print_Postscript_Header(1,ps_tree); tree->ps_tree = DR_Make_Tdraw_Struct(tree); DR_Init_Tdraw_Struct(tree->ps_tree); DR_Get_Tree_Box_Width(tree->ps_tree,tree); Dist_To_Root(tree->n_root,tree); tree->ps_tree->max_dist_to_root = DR_Get_Max_Dist_To_Root(tree); For(i,tree->n_otu) tree->ps_tree->ycoord[i] = tree->a_nodes[i]->y_rank * (int)(tree->ps_tree->page_height / (tree->n_otu)); DR_Get_X_Coord(NO,tree->ps_tree,tree); DR_Get_Y_Coord(YES,tree->ps_tree,tree); DR_Print_Tree_Postscript(1,NO,ps_tree,tree); DR_Print_Postscript_EOF(ps_tree); fclose(ps_tree); Warn_And_Exit(""); } }while(conflict == YES); Free(node_table); return tree->tip_order_score; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict, t_tree *tree) { if(d->tax) return; else { int i,j; int d_a; int beg,end; phydbl min,max; t_node *lca; t_node **conflict_tips, **anc_conflict; int n_conflicts; phydbl eps,tmp_rank; t_node *tmp_node; int n_moved; int n_anc_conflicts; anc_conflict = NULL; d_a = -1; /* It is a post order traversal */ For(i,3) { if((d->v[i] != d->anc) && (d->b[i] != tree->e_root)) { TIPO_Untangle_Node(d,d->v[i],node_table,conflict,tree); } } lca = NULL; eps = 1.E-10; /* Find direction fron node d ((d)escendant) to a ((a)ncestor) */ For(i,3) { if((d->v[i] == d->anc) || (d->b[i] == tree->e_root)) { d_a = i; break; } } /* y_rank_min is the minimum rank among all the ranks of the tips that can be reached when going from a to d */ min = d->y_rank_min; max = d->y_rank_max; /* Get the list of tip nodes which ranks are between d->y_rank_min and d->y_rank_max */ n_conflicts = 0; For(i,tree->n_otu) { if((node_table[i]->y_rank > min - eps) && (node_table[i]->y_rank < max + eps)) { n_conflicts++; } } conflict_tips = NULL; For(i,tree->n_otu) { if(node_table[i]->y_rank > min - eps) { conflict_tips = node_table+i; break; } } beg = 0; end = n_conflicts; n_moved = 0; n_anc_conflicts = 0; do { for(i=beg;ibip_size[d_a]) if(conflict_tips[i] == d->bip_node[d_a][j]) break; if(j == d->bip_size[d_a]) /* conflict_tips[i] does not belong to the list of descendant of node d. It is therefore responsible for a conflict */ { *conflict = YES; /* printf("\n. Moving %d with rank %f",conflict_tips[i]->num,conflict_tips[i]->y_rank); */ n_moved++; /* Move from conflict_tips[i] towards the root as long as the rank of the node lca is between min and max */ lca = conflict_tips[i]; while(lca->y_rank_min > min && lca->y_rank_max < max) lca = lca->anc; if(lca->y_rank_min > max && lca->y_rank_max > max) { PhyML_Printf("\n. lca = %d (%d)",lca->num,lca==tree->n_root); PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } if(lca->y_rank_min < min && lca->y_rank_max < min) { PhyML_Printf("\n. lca = %d (root ? %d) (tip ? %d)",lca->num,lca==tree->n_root,lca->tax); PhyML_Printf("\n. lca->y_rank_min = %f lca->y_rank_max = %f",lca->y_rank_min,lca->y_rank_max); PhyML_Printf("\n. min=%f max=%f",min,max); PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } if(lca->tax) { PhyML_Printf("\n. lca (%d) cannot be a tip.",lca->num); PhyML_Printf("\n. lca->anc->y_rank=%f",lca->anc->y_rank); PhyML_Printf("\n. lca->y_rank=%f",lca->y_rank); PhyML_Printf("\n. lca->y_rank_min=%f lca=>y_rank_max=%f",lca->y_rank_min,lca->y_rank_max); PhyML_Printf("\n. min=%f max=%f",min,max); PhyML_Printf("\n. %p %p",lca,conflict_tips[i]); PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } /* Have you found lca previously ? */ For(j,n_anc_conflicts) if(anc_conflict[j] == lca) break; if(j == n_anc_conflicts) /* if no, then update the tree score and the list of ancestral nodes at the origin of conflicts */ { /* tree->tip_order_score+=1.; */ /* tree->tip_order_score+=(lca->y_rank_max-lca->y_rank_min); */ n_anc_conflicts++; anc_conflict = (t_node **)realloc(anc_conflict,n_anc_conflicts*sizeof(t_node *)); anc_conflict[n_anc_conflicts-1] = lca; } /* PhyML_Printf("\n. Detected conflict for ``%s'' (rank:%f min=%f max=%f lca=%f)", */ /* conflict_tips[i]->name, */ /* conflict_tips[i]->y_rank, */ /* min,max,lca->y_rank); */ /* Solve the conflict by shifting tip nodes to the left or to the right */ if(lca->y_rank > d->y_rank) { end--; /* max-=1.; */ max = conflict_tips[end-1]->y_rank; /* printf("\n. max=%f %f",max,conflict_tips[end-1]->y_rank); */ for(j=i;jnum,conflict_tips[j+1]->num, */ /* conflict_tips[j]->y_rank,conflict_tips[j+1]->y_rank); */ tmp_rank = conflict_tips[j]->y_rank; conflict_tips[j]->y_rank = conflict_tips[j+1]->y_rank; conflict_tips[j+1]->y_rank = tmp_rank; tmp_node = conflict_tips[j]; conflict_tips[j] = conflict_tips[j+1]; conflict_tips[j+1] = tmp_node; tree->tip_order_score += fabs(conflict_tips[j]->y_rank - conflict_tips[j+1]->y_rank)/n_conflicts; /* PhyML_Printf(" to (%d,%d) (%f,%f)", */ /* conflict_tips[j]->num,conflict_tips[j+1]->num, */ /* conflict_tips[j]->y_rank,conflict_tips[j+1]->y_rank); */ } } else { beg++; /* min+=1.; */ min = conflict_tips[beg]->y_rank; /* printf("\n. min=%f %f",min,conflict_tips[beg]->y_rank); */ for(j=i;j>0;j--) { /* PhyML_Printf("\n- Moved (%d,%d) from (%f,%f)", */ /* conflict_tips[j]->num,conflict_tips[j-1]->num, */ /* conflict_tips[j]->y_rank,conflict_tips[j-1]->y_rank); */ tmp_rank = conflict_tips[j]->y_rank; conflict_tips[j]->y_rank = conflict_tips[j-1]->y_rank; conflict_tips[j-1]->y_rank = tmp_rank; tmp_node = conflict_tips[j]; conflict_tips[j] = conflict_tips[j-1]; conflict_tips[j-1] = tmp_node; tree->tip_order_score += fabs(conflict_tips[j]->y_rank - conflict_tips[j+1]->y_rank)/n_conflicts; /* PhyML_Printf(" to (%d,%d) (%f,%f)", */ /* conflict_tips[j]->num,conflict_tips[j-1]->num, */ /* conflict_tips[j]->y_rank,conflict_tips[j-1]->y_rank); */ } } /* printf("\n"); */ /* For(j,n_conflicts) printf("%.0f ",conflict_tips[j]->y_rank); */ /* printf("\n. min=%f max=%f",min,max); */ /* printf("\n. Node %d has now rank %f",c_node->num,c_node->y_rank); */ /* Update internal nodes y ranks */ TIPO_Get_All_Y_Rank(tree); break; } } }while(n_moved + d->bip_size[d_a] != n_conflicts); For(i,tree->n_otu) { if((tree->a_nodes[i]->y_rank > min - eps) && (tree->a_nodes[i]->y_rank < max + eps)) { For(j,d->bip_size[d_a]) { if(tree->a_nodes[i] == d->bip_node[d_a][j]) break; } if(j == d->bip_size[d_a]) { printf("\n. Conflict remaining for node %d (%d)",d->num,a->num); PhyML_Printf("\n. Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } } } if(anc_conflict) Free(anc_conflict); return; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int TIPO_Check_Tip_Ranks(t_tree *tree) { int i,j; phydbl eps; eps = 1.E-6; For(i,tree->n_otu-1) { for(j=i+1;jn_otu;j++) { if(fabs(tree->a_nodes[i]->y_rank - tree->a_nodes[j]->y_rank) < eps) { return 0; } } } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Read_Taxa_Zscores(FILE *fp_coord, t_tree *tree) { char *name,*line; phydbl z; int i; name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); if(!fgets(line,T_MAX_LINE,fp_coord)) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } Free(line); do { if(fscanf(fp_coord,"%s\t%lf\n",name,&z) == EOF) break; PhyML_Printf("\n. Read %s. Z-score: %f",name,z); For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break; if(i == tree->n_otu) { PhyML_Printf("\n. Could not find taxon '%s' in coordinate file.",name); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } tree->io->z_scores[i] = z; }while(1); Free(name); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Read_Taxa_Coordinates(FILE *fp_coord, t_tree *tree) { char *name,*line; phydbl lon, lat; int i; name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); if(!fgets(line,T_MAX_LINE,fp_coord)) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } Free(line); tree->io->lat = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl)); tree->io->lon = (phydbl *)mCalloc(tree->n_otu,sizeof(phydbl)); do { if(fscanf(fp_coord,"%s\t%lf\t%lf\n",name,&lat,&lon) == EOF) break; PhyML_Printf("\n. Read %s %f %f",name,lat,lon); For(i,tree->n_otu) if(!strcmp(tree->io->long_tax_names[i],name)) break; if(i == tree->n_otu) { PhyML_Printf("\n. Could not find taxon '%s' in coordinate file.",name); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } tree->io->lat[i] = lat; tree->io->lon[i] = lon; }while(1); Free(name); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Get_Tips_Y_Rank_From_Zscores(t_tree *tree) { int i; For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0; /* Randomization in order to avoid ties */ For(i,tree->n_otu) tree->io->z_scores[i] += Rnorm(0.0,0.001); For(i,tree->n_otu) tree->a_nodes[i]->y_rank = tree->io->z_scores[i]; /* For(i,tree->n_otu) tree->a_nodes[i]->y_rank = .0; */ /* For(i,tree->n_otu-1) */ /* { */ /* for(j=i+1;jn_otu;j++) */ /* { */ /* if(tree->io->z_scores[i] > tree->io->z_scores[j]) */ /* { */ /* tree->a_nodes[i]->y_rank += 1.0; */ /* } */ /* else */ /* if(tree->io->z_scores[i] < tree->io->z_scores[j]) */ /* { */ /* tree->a_nodes[j]->y_rank += 1.0; */ /* } */ /* else */ /* { */ /* PhyML_Printf("\n. Ties not allowed.\n"); */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* } */ /* } */ /* For(i,tree->n_otu) printf("- %f\n",tree->a_nodes[i]->y_rank); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Sort translation table such that tree->a_nodes[i]->name == tree->io->short_tax_name[i] for all i */ void TIPO_Sort_Translation_Table(t_tree *tree) { int i,j; char *s; Test_Node_Table_Consistency(tree); For(i,tree->n_otu-1) { for(j=i+1;jn_otu;j++) { if(!strcmp(tree->a_nodes[i]->name,tree->io->short_tax_names[j])) { s = tree->io->short_tax_names[i]; tree->io->short_tax_names[i] = tree->io->short_tax_names[j]; tree->io->short_tax_names[j] = s; s = tree->io->long_tax_names[i]; tree->io->long_tax_names[i] = tree->io->long_tax_names[j]; tree->io->long_tax_names[j] = s; break; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Randomize_Tip_Y_Ranks(t_tree *tree) { int i; phydbl rk_tmp; int rnd_node_num; For(i,tree->n_otu) tree->a_nodes[i]->y_rank_ori = tree->a_nodes[i]->y_rank; For(i,tree->n_otu) { rnd_node_num = Rand_Int(0,tree->n_otu-1); rk_tmp = tree->a_nodes[rnd_node_num]->y_rank; tree->a_nodes[rnd_node_num]->y_rank = tree->a_nodes[i]->y_rank; tree->a_nodes[i]->y_rank = rk_tmp; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIPO_Read_One_Taxon_Zscore(FILE *fp_coord, char *seqname_qry, int col, t_tree *tree) { char *seqname, *place; phydbl lat; seqname = (char *)mCalloc(T_MAX_NAME,sizeof(char)); place = (char *)mCalloc(T_MAX_NAME,sizeof(char)); rewind(fp_coord); /* skip first line */ /* if(!fgets(line,T_MAX_LINE,fp_coord)) */ /* { */ /* PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); */ /* Warn_And_Exit(""); */ /* } */ /* Free(line); */ do { /* if(fscanf(fp_coord,"%s\t%s\t%lf\t%lf\t%d\n",seqname,place,&lat,&lon,&year) == EOF) */ /* if(fscanf(fp_coord,"%s\t%s\t%lf\t%lf\n",seqname,place,&lat,&lon) == EOF) */ /* if(fscanf(fp_coord,"%s\t%lf\t%lf\n",seqname,&lat,&lon) == EOF) */ if(fscanf(fp_coord,"%s %lf\n",seqname,&lat) == EOF) { PhyML_Printf("\n. Could not find sequence '%s' in coordinate file",seqname_qry); PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(!strcmp(seqname,seqname_qry)) break; }while(1); /* PhyML_Printf("\n. Found %20s %s @ %10.2f %10.2f. Recording %10.2f",seqname,place,lat,lon,(col==1)?lat:lon); */ Free(seqname); Free(place); /* if(col == 1) return lat; */ /* else if(col == 2) return lon; */ /* else return -1.; */ return lat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void TIPO_Normalize_Zscores(t_tree *tree) { int i; phydbl min_z,max_z; phydbl eps; eps = 1.E-10; min_z = FLT_MAX; For(i,tree->n_otu) { if(tree->io->z_scores[i] < min_z) { min_z = tree->io->z_scores[i]; } } max_z = -FLT_MAX; For(i,tree->n_otu) { if(tree->io->z_scores[i] > max_z) { max_z = tree->io->z_scores[i]; } } For(i,tree->n_otu) tree->io->z_scores[i] = (tree->io->z_scores[i] - min_z)/(max_z-min_z+eps); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIPO_Lk(t_tree *tree) { tree->geo_lnL = 0.0; TIPO_Lk_Post(tree->n_root,tree->n_root->v[2],tree); TIPO_Lk_Post(tree->n_root,tree->n_root->v[1],tree); TIPO_Lk_Core(NULL,tree->n_root,tree); return(tree->geo_lnL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIPO_Lk_Post(t_node *a, t_node *d, t_tree *tree) { if(!d->tax) { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { TIPO_Lk_Post(d,d->v[i],tree); } } TIPO_Lk_Core(a,d,tree); } return .0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree) { int i,j; int d_v1,d_v2,v1_d,v2_d; t_node *v1, *v2; phydbl dist,dens,min_dist; if(d->tax) { PhyML_Printf("\n. Err in file %s at line %d\n\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(d == tree->n_root) { d_v1 = 0; d_v2 = 1; } else { d_v1 = d_v2 = -1; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { if(d_v1 < 0) d_v1 = i; else d_v2 = i; } } } v1 = d->v[d_v1]; v2 = d->v[d_v2]; v1_d = v2_d = -1; if(d == tree->n_root) { For(i,3) { if(v1->b[i] == tree->e_root) v1_d = i; if(v2->b[i] == tree->e_root) v2_d = i; } } else { For(i,3) { if(v1->v[i] == d) v1_d = i; if(v2->v[i] == d) v2_d = i; } } dens = 0.0; min_dist = FLT_MAX; For(i,v1->bip_size[v1_d]) { For(j,v2->bip_size[v2_d]) { dist = fabs(v1->bip_node[v1_d][i]->y_rank - v2->bip_node[v2_d][j]->y_rank); if(dist < min_dist) min_dist = dist; dens += Dnorm(dist,0.0,tree->geo_mig_sd); /* printf("\n. dist=%f dens=%f %f %f", */ /* dist,Dnorm(dist,0.0,tree->geo_mig_sd), */ /* v1->bip_node[v1_d][i]->y_rank, */ /* v2->bip_node[v2_d][j]->y_rank); */ } } /* printf("\n. min_dist=%f dens=%f", */ /* min_dist,Dnorm(dist,0.0,tree->geo_mig_sd)); */ /* dens = Dnorm(min_dist,0.0,tree->geo_mig_sd); */ tree->geo_lnL += LOG(dens); return tree->geo_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/tiporder.h000066400000000000000000000040671263450375500154560ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include #ifndef TIPORDER_H #define TIPORDER_H #include "times.h" #include "spr.h" #include "utilities.h" #include "lk.h" #include "optimiz.h" #include "bionj.h" #include "models.h" #include "free.h" #include "help.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "m4.h" #include "draw.h" #include "rates.h" #include "mcmc.h" #include "io.h" #include "stats.h" void TIPO_Get_Tips_Y_Rank(t_tree *tree); void TIPO_Get_Tips_Y_Rank_Pre(t_node *a, t_node *d, phydbl *curr_rank, t_tree *tree); void TIPO_Get_All_Y_Rank(t_tree *tree); void TIPO_Get_All_Y_Rank_Pre(t_node *a, t_node *d, t_tree *tree); void TIPO_Swap_One_Node(t_node *d, t_tree *tree); void TIPO_Minimize_Tip_Order_Score(int n_trees, t_tree **list_tree, t_tree *ref_tree); void TIPO_Print_Tip_Ordered(t_tree *ref_tree); void TIPO_Print_Tip_Ordered_Pre(t_node *a, t_node *d, t_tree *ref_tree); phydbl TIPO_Untangle_Tree(t_tree *tree); void TIPO_Untangle_Node(t_node *a, t_node *d, t_node **node_table, int *conflict, t_tree *tree); int TIPO_Untangle_Tree_List(int n_trees, t_tree **list_tree, t_tree *ref_tree); int TIPO_Check_Tip_Ranks(t_tree *tree); void TIPO_Read_Taxa_Coordinates(FILE *fp_coord, t_tree *tree); void TIPO_Get_Tips_Y_Rank_From_Zscores(t_tree *tree); void TIPO_Init_Tip_Num(t_tree *tree); void TIPO_Read_Taxa_Zscores(FILE *fp_coord, t_tree *tree); void TIPO_Sort_Translation_Table(t_tree *tree); void TIPO_Randomize_Tip_Y_Ranks(t_tree *tree); phydbl TIPO_Read_One_Taxon_Zscore(FILE *fp, char *seqname_qry, int col, t_tree *tree); void TIPO_Normalize_Zscores(t_tree *tree); void TIPO_Get_Min_Number_Of_Tip_Permut(t_tree *tree); phydbl TIPO_Lk(t_tree *tree); phydbl TIPO_Lk_Post(t_node *a, t_node *d, t_tree *tree); phydbl TIPO_Lk_Core(t_node *a, t_node *d, t_tree *tree); #endif phyml-3.2.0/src/utilities.c000066400000000000000000011130331263450375500156270ustar00rootroot00000000000000/* PhyML: a program that computes maximum likelihood phylogenies from DNA or AA homologous sequences. Copyright (C) Stephane Guindon. Oct 2003 onward. All parts of the source except where indicated are distributed under the GNU public licence. See http://www.opensource.org for details. */ #include "utilities.h" #include "assert.h" #ifdef BEAGLE #include "beagle_utils.h" #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl String_To_Dbl(char *string) { phydbl buff; char *endptr; if(!string) { PhyML_Printf("\n== String object empty."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } buff = strtod(string,&endptr); if(string == endptr || errno == ERANGE) { PhyML_Printf("\n== Error in translating string '%s' to double.",string); Exit("\n"); } return buff; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Unroot_Tree(char **subtrees) { char **tmp_sub; int degree,i,j; PhyML_Printf("\n. Removing the root...\n"); tmp_sub = Sub_Trees(subtrees[0],°ree); if(degree >= 2) { strcpy(subtrees[2],subtrees[1]); Clean_Multifurcation(tmp_sub,degree,2); For(j,2) strcpy(subtrees[j],tmp_sub[j]); } else { tmp_sub = Sub_Trees(subtrees[1],°ree); strcpy(subtrees[2],subtrees[0]); Clean_Multifurcation(tmp_sub,degree,2); For(j,2) strcpy(subtrees[j],tmp_sub[j]); } For(i,degree) Free(tmp_sub[i]); Free(tmp_sub); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Edge_Dirs(t_edge *b, t_node *a, t_node *d, t_tree *tree) { int i; if(a == b->rght) { PhyML_Printf("\n== a->num = %3d ; d->num = %3d",a->num,d->num); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } if(d == b->left) { PhyML_Printf("\n== a->num = %3d ; d->num = %3d",a->num,d->num); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } b->l_r = b->r_l = -1; For(i,3) { /* if((a->v[i]) && ((a->v[i] == d) || (e_root && a->b[i] == e_root))) */ if((a->v[i]) && ((a->v[i] == d))) { b->l_r = i; /* we consider here that 'a' is on the left handside of 'b'*/ a->b[i] = b; } /* if((d->v[i]) && ((d->v[i] == a) || (e_root && d->b[i] == e_root))) */ if((d->v[i]) && ((d->v[i] == a))) { b->r_l = i; /* we consider here that 'd' is on the right handside of 'b'*/ d->b[i] = b; } } if(a->tax) {b->r_l = 0; For(i,3) if(d->v[i]==a) {b->l_r = i; break;}} b->l_v1 = b->l_v2 = b->r_v1 = b->r_v2 = -1; For(i,3) { if(b->left->v[i] != b->rght) { if(b->l_v1 < 0) b->l_v1 = i; else b->l_v2 = i; } if(b->rght->v[i] != b->left) { if(b->r_v1 < 0) b->r_v1 = i; else b->r_v2 = i; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Restrict_To_Coding_Position(align **data, option *io) { int i,j,curr_pos; if(io->codpos != -1) { For(i,io->n_otu) { curr_pos = 0; for(j=io->codpos-1;jlen;j+=3) { data[i]->state[curr_pos] = data[i]->state[j]; curr_pos++; } data[i]->len /= 3; } } } void Uppercase(char *ch) { /* convert ch to upper case -- either ASCII or EBCDIC */ *ch = isupper((int)*ch) ? *ch : toupper((int)*ch); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Lowercase(char *ch) { /* convert ch to upper case -- either ASCII or EBCDIC */ *ch = isupper((int)*ch) ? tolower((int)*ch) : *ch; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// calign *Compact_Data(align **data, option *io) { calign *cdata_tmp,*cdata; int i,j,k,site; int n_patt,which_patt,n_invar; char **sp_names; int n_otu, n_sites; pnode *proot; int compress; int n_ambigu,is_ambigu; n_otu = io->n_otu; n_patt = 0; which_patt = 0; sp_names = (char **)mCalloc(n_otu,sizeof(char *)); For(i,n_otu) { sp_names[i] = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(sp_names[i],data[i]->name); } cdata_tmp = Make_Cseq(n_otu,data[0]->len,io->state_len,data[0]->len,sp_names); proot = (pnode *)Create_Pnode(T_MAX_ALPHABET); For(i,n_otu) Free(sp_names[i]); Free(sp_names); if(data[0]->len%io->state_len) { PhyML_Printf("\n== Sequence length is not a multiple of %d\n",io->state_len); Exit("\n"); } compress = io->colalias; n_ambigu = 0; is_ambigu = 0; if(!io->quiet && !compress) { PhyML_Printf("\n== WARNING: sequences are not compressed !\n"); } Fors(site,data[0]->len,io->state_len) { if(io->rm_ambigu) { is_ambigu = 0; For(j,n_otu) if(Is_Ambigu(data[j]->state+site,io->datatype,io->state_len)) break; if(j != n_otu) { is_ambigu = 1; n_ambigu++; } } if(!is_ambigu) { if(compress) { which_patt = -1; Traverse_Prefix_Tree(site,-1,&which_patt,&n_patt,data,io,proot); if(which_patt == n_patt-1) /* New pattern found */ { n_patt--; k=n_patt; } else { k = n_patt-10; } } else { k = n_patt; } if(k == n_patt) /* add a new site pattern */ { For(j,n_otu) Copy_One_State(data[j]->state+site, cdata_tmp->c_seq[j]->state+n_patt*io->state_len, io->state_len); For(i,n_otu) { For(j,n_otu) { if(!(Are_Compatible(cdata_tmp->c_seq[i]->state+n_patt*io->state_len, cdata_tmp->c_seq[j]->state+n_patt*io->state_len, io->state_len, io->datatype))) break; } if(j != n_otu) break; } if((j == n_otu) && (i == n_otu)) /* all characters at that site are compatible with one another: the site may be invariant */ { For(j,n_otu) { cdata_tmp->invar[n_patt] = Assign_State(cdata_tmp->c_seq[j]->state+n_patt*io->state_len, io->datatype, io->state_len); if(cdata_tmp->invar[n_patt] > -1.) break; } } else cdata_tmp->invar[n_patt] = -1; cdata_tmp->sitepatt[site] = n_patt; cdata_tmp->wght[n_patt] += 1; n_patt += 1; } else { cdata_tmp->sitepatt[site] = which_patt; cdata_tmp->wght[which_patt] += 1; } } } data[0]->len -= n_ambigu; cdata_tmp->init_len = data[0]->len; cdata_tmp->crunch_len = n_patt; For(i,n_otu) cdata_tmp->c_seq[i]->len = n_patt; if(!io->quiet) PhyML_Printf("\n. %d patterns found (out of a total of %d sites). \n",n_patt,data[0]->len); if((io->rm_ambigu) && (n_ambigu)) PhyML_Printf("\n. Removed %d columns of the alignment as they contain ambiguous characters (e.g., gaps) \n",n_ambigu); /* For(i,n_otu) */ /* { */ /* For(j,cdata_tmp->crunch_len) */ /* { */ /* printf("%c",cdata_tmp->c_seq[i]->state[j*io->state_len+1]); */ /* } */ /* printf("\n"); */ /* } */ n_invar=0; For(i,cdata_tmp->crunch_len) { if(cdata_tmp->invar[i] > -1.) n_invar+=(int)cdata_tmp->wght[i]; } if(!io->quiet) PhyML_Printf("\n. %d sites without polymorphism (%.2f%c).\n",n_invar,100.*(phydbl)n_invar/data[0]->len,'%'); cdata_tmp->obs_pinvar = (phydbl)n_invar/data[0]->len; cdata_tmp->io = io; n_sites = 0; For(i,cdata_tmp->crunch_len) n_sites += cdata_tmp->wght[i]; if(n_sites != data[0]->len / io->state_len) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(io->datatype == NT) Get_Base_Freqs(cdata_tmp); else if(io->datatype == AA) Get_AA_Freqs(cdata_tmp); else {/* Uniform state frequency distribution.*/} cdata = Copy_Cseq(cdata_tmp,io); Free_Cseq(cdata_tmp); Free_Prefix_Tree(proot,T_MAX_ALPHABET); Check_Ambiguities(cdata,io->datatype,io->state_len); Set_D_States(cdata,io->datatype,io->state_len); return cdata; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// calign *Compact_Cdata(calign *data, option *io) { calign *cdata; int i,j,k,site; int n_patt,which_patt; int n_otu; n_otu = data->n_otu; cdata = (calign *)mCalloc(1,sizeof(calign)); cdata->n_otu = n_otu; cdata->c_seq = (align **)mCalloc(n_otu,sizeof(align *)); cdata->wght = (int *)mCalloc(data->crunch_len,sizeof(int)); cdata->b_frq = (phydbl *)mCalloc(io->mod->ns,sizeof(phydbl)); cdata->ambigu = (short int *)mCalloc(data->crunch_len,sizeof(short int)); cdata->invar = (short int *)mCalloc(data->crunch_len,sizeof(short int)); cdata->crunch_len = cdata->init_len = -1; For(j,n_otu) { cdata->c_seq[j] = (align *)mCalloc(1,sizeof(align)); cdata->c_seq[j]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(cdata->c_seq[j]->name,data->c_seq[j]->name); cdata->c_seq[j]->state = (char *)mCalloc(data->crunch_len,sizeof(char)); cdata->c_seq[j]->is_ambigu = (short int *)mCalloc(data->crunch_len,sizeof(short int)); cdata->c_seq[j]->state[0] = data->c_seq[j]->state[0]; } n_patt = which_patt = 0; For(site,data->crunch_len) { if(data->wght[site]) { For(k,n_patt) { For(j,n_otu) { if(strncmp(cdata->c_seq[j]->state+k*io->state_len, data->c_seq[j]->state+site*io->state_len, io->state_len)) break; } if(j == n_otu) { which_patt = k; break; } } /* /\* TO DO *\/ */ /* k = n_patt; */ if(k == n_patt) { For(j,n_otu) Copy_One_State(data->c_seq[j]->state+site*io->state_len, cdata->c_seq[j]->state+n_patt*io->state_len, io->state_len); For(i,n_otu) { For(j,n_otu) { if(!(Are_Compatible(cdata->c_seq[i]->state+n_patt*io->state_len, cdata->c_seq[j]->state+n_patt*io->state_len, io->state_len, io->datatype))) break; } if(j != n_otu) break; } if((j == n_otu) && (i == n_otu)) { For(j,n_otu) { cdata->invar[n_patt] = Assign_State(cdata->c_seq[j]->state+n_patt*io->state_len, io->datatype, io->state_len); if(cdata->invar[n_patt] > -1.) break; } } else cdata->invar[n_patt] = -1; cdata->wght[n_patt] += data->wght[site]; n_patt+=1; } else cdata->wght[which_patt] += data->wght[site]; /* Print_Site(cdata,k,n_otu,"\n",io->stepsize); */ } } cdata->init_len = data->crunch_len; cdata->crunch_len = n_patt; For(i,n_otu) cdata->c_seq[i]->len = n_patt; if(io->datatype == NT) Get_Base_Freqs(cdata); else if(io->datatype == AA) Get_AA_Freqs(cdata); else {/* Not implemented yet */} return cdata; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Traverse_Prefix_Tree(int site, int seqnum, int *patt_num, int *n_patt, align **data, option *io, pnode *n) { if(seqnum == io->n_otu-1) { n->weight++; if(n->weight == 1) { n->num = *n_patt; (*n_patt) += 1; } (*patt_num) = n->num; return; } else { int next_state; next_state = -1; next_state = Assign_State_With_Ambiguity(data[seqnum+1]->state+site, io->datatype, io->state_len); if(!n->next[next_state]) n->next[next_state] = Create_Pnode(T_MAX_ALPHABET); Traverse_Prefix_Tree(site,seqnum+1,patt_num,n_patt,data,io,n->next[next_state]); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// pnode *Create_Pnode(int size) { pnode *n; int i; n = (pnode *)mCalloc(1,sizeof(pnode )); n->next = (pnode **)mCalloc(size,sizeof(pnode *)); For(i,size) n->next[i] = NULL; n->weight = 0; n->num = -1; return n; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Base_Freqs(calign *data) { int i,j,k; phydbl A,C,G,T; phydbl fA,fC,fG,fT; int w; fA = fC = fG = fT = .25; For(k,8) { A = C = G = T = .0; For(i,data->n_otu) { For(j,data->crunch_len) { w = data->wght[j]; if(w) { switch(data->c_seq[i]->state[j]) { case 'A' : A+=w; break; case 'C' : C+=w; break; case 'G' : G+=w; break; case 'T' : T+=w; break; case 'U' : T+=w; break; case 'M' : C+=w*fC/(fC+fA); A+=w*fA/(fA+fC); break; case 'R' : G+=w*fG/(fA+fG); A+=w*fA/(fA+fG); break; case 'W' : T+=w*fT/(fA+fT); A+=w*fA/(fA+fT); break; case 'S' : C+=w*fC/(fC+fG); G+=w*fG/(fC+fG); break; case 'Y' : C+=w*fC/(fC+fT); T+=w*fT/(fT+fC); break; case 'K' : G+=w*fG/(fG+fT); T+=w*fT/(fT+fG); break; case 'B' : C+=w*fC/(fC+fG+fT); G+=w*fG/(fC+fG+fT); T+=w*fT/(fC+fG+fT); break; case 'D' : A+=w*fA/(fA+fG+fT); G+=w*fG/(fA+fG+fT); T+=w*fT/(fA+fG+fT); break; case 'H' : A+=w*fA/(fA+fC+fT); C+=w*fC/(fA+fC+fT); T+=w*fT/(fA+fC+fT); break; case 'V' : A+=w*fA/(fA+fC+fG); C+=w*fC/(fA+fC+fG); G+=w*fG/(fA+fC+fG); break; case 'N' : case 'X' : case '?' : case 'O' : case '-' : A+=w*fA; C+=w*fC; G+=w*fG; T+=w*fT; break; default : break; } } } } fA = A/(A+C+G+T); fC = C/(A+C+G+T); fG = G/(A+C+G+T); fT = T/(A+C+G+T); } data->b_frq[0] = fA; data->b_frq[1] = fC; data->b_frq[2] = fG; data->b_frq[3] = fT; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_AA_Freqs(calign *data) { int i,j,k; phydbl A,C,D,E,F,G,H,I,K,L,M,N,P,Q,R,S,T,V,W,Y; phydbl fA,fC,fD,fE,fF,fG,fH,fI,fK,fL,fM,fN,fP,fQ,fR,fS,fT,fV,fW,fY; int w; phydbl sum; fA = fC = fD = fE = fF = fG = fH = fI = fK = fL = fM = fN = fP = fQ = fR = fS = fT = fV = fW = fY = 1./20.; For(k,8) { A = C = D = E = F = G = H = I = K = L = M = N = P = Q = R = S = T = V = W = Y = .0; For(i,data->n_otu) { For(j,data->crunch_len) { w = data->wght[j]; if(w) { switch(data->c_seq[i]->state[j]) { case 'A' : A+=w; break; case 'C' : C+=w; break; case 'D' : D+=w; break; case 'E' : E+=w; break; case 'F' : F+=w; break; case 'G' : G+=w; break; case 'H' : H+=w; break; case 'I' : I+=w; break; case 'K' : K+=w; break; case 'L' : L+=w; break; case 'M' : M+=w; break; case 'N' : N+=w; break; case 'P' : P+=w; break; case 'Q' : Q+=w; break; case 'R' : R+=w; break; case 'S' : S+=w; break; case 'T' : T+=w; break; case 'V' : V+=w; break; case 'W' : W+=w; break; case 'Y' : Y+=w; break; case 'Z' : Q+=w; break; case 'X' : case '?' : case 'O' : case '-' : A+=w*fA; C+=w*fC; D+=w*fD; E+=w*fE; F+=w*fF; G+=w*fG; H+=w*fH; I+=w*fI; K+=w*fK; L+=w*fL; M+=w*fM; N+=w*fN; P+=w*fP; Q+=w*fQ; R+=w*fR; S+=w*fS; T+=w*fT; V+=w*fV; W+=w*fW; Y+=w*fY; break; default : break; } } } } sum = (A+C+D+E+F+G+H+I+K+L+M+N+P+Q+R+S+T+V+W+Y); fA = A/sum; fC = C/sum; fD = D/sum; fE = E/sum; fF = F/sum; fG = G/sum; fH = H/sum; fI = I/sum; fK = K/sum; fL = L/sum; fM = M/sum; fN = N/sum; fP = P/sum; fQ = Q/sum; fR = R/sum; fS = S/sum; fT = T/sum; fV = V/sum; fW = W/sum; fY = Y/sum; } data->b_frq[0] = fA; data->b_frq[1] = fR; data->b_frq[2] = fN; data->b_frq[3] = fD; data->b_frq[4] = fC; data->b_frq[5] = fQ; data->b_frq[6] = fE; data->b_frq[7] = fG; data->b_frq[8] = fH; data->b_frq[9] = fI; data->b_frq[10] = fL; data->b_frq[11] = fK; data->b_frq[12] = fM; data->b_frq[13] = fF; data->b_frq[14] = fP; data->b_frq[15] = fS; data->b_frq[16] = fT; data->b_frq[17] = fW; data->b_frq[18] = fY; data->b_frq[19] = fV; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Swap the nodes on the left and right of e1 with the nodes // on the left and right of e2 respectively, or on the // right and left of e2 if swap == YES void Swap_Nodes_On_Edges(t_edge *e1, t_edge *e2, int swap, t_tree *tree) { t_node *buff; e1->left->l[e1->l_r] = e1->l->v; e1->rght->l[e1->r_l] = e1->l->v; e2->left->l[e2->l_r] = e2->l->v; e2->rght->l[e2->r_l] = e2->l->v; printf("\n. Swap edge %d (%d %d) with %d (%d %d)",e1->num,e1->left->num,e1->rght->num,e2->num,e2->left->num,e2->rght->num); if(swap == NO) { buff = e1->left; e1->left = e2->left; e2->left = buff; buff = e1->rght; e1->rght = e2->rght; e2->rght = buff; } else { buff = e1->left; e1->left = e2->rght; e2->rght = buff; buff = e1->rght; e1->rght = e2->left; e2->left = buff; } Connect_One_Edge_To_Two_Nodes(e1->left,e1->rght,e1,tree); Connect_One_Edge_To_Two_Nodes(e2->left,e2->rght,e2,tree); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* As opposed to Connect_Edges_To_Nodes_Recur, the ordering of edges connected to tips changes does not depend on the topology */ void Connect_Edges_To_Nodes_Serial(t_tree *tree) { int i,j; /* Reset */ For(i,2*tree->n_otu-1) For(j,3) tree->a_nodes[i]->b[j] = NULL; tree->num_curr_branch_available = 0; For(i,tree->n_otu) { if(!tree->a_nodes[i]->tax) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); Connect_One_Edge_To_Two_Nodes(tree->a_nodes[i], tree->a_nodes[i]->v[0], tree->a_edges[tree->num_curr_branch_available], tree); if(tree->n_otu == 2) break; } for(i=tree->n_otu;i<2*tree->n_otu-2;i++) { if(tree->a_nodes[i] == tree->n_root) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); For(j,3) if(!tree->a_nodes[i]->b[j]) Connect_One_Edge_To_Two_Nodes(tree->a_nodes[i], tree->a_nodes[i]->v[j], tree->a_edges[tree->num_curr_branch_available], tree); } } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ void Connect_Edges_To_Nodes_Recur(t_node *a, t_node *d, t_tree *tree) { int i; Connect_One_Edge_To_Two_Nodes(a,d,tree->a_edges[tree->num_curr_branch_available],tree); if(d->tax) return; else For(i,3) if(d->v[i] != a) /* Don't add d->b[i] != tree->e_root condition here since tree is not wired yet... */ Connect_Edges_To_Nodes_Recur(d,d->v[i],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Connect_One_Edge_To_Two_Nodes(t_node *a, t_node *d, t_edge *b, t_tree *tree) { int i,dir_a_d,dir_d_a; dir_a_d = -1; For(i,3) if(a->v[i] == d) {dir_a_d = i; break;} dir_d_a = -1; For(i,3) if(d->v[i] == a) {dir_d_a = i; break;} if(dir_a_d == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(dir_d_a == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); a->b[dir_a_d] = b; d->b[dir_d_a] = b; b->num = tree->num_curr_branch_available; b->left = a; b->rght = d; if(a->tax) {b->rght = a; b->left = d;} /* root */ /* a tip is necessary on the right hand side of the t_edge */ tree->num_curr_branch_available += 1; (b->left == a)? (Set_Edge_Dirs(b,a,d,tree)): (Set_Edge_Dirs(b,d,a,tree)); b->l->v = a->l[b->l_r]; if(a->tax) b->l->v = a->l[b->r_l]; b->l_old->v = b->l->v; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Dirs(t_tree *tree) { int i; int buff; t_edge *b; b = NULL; buff = -1; For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; if((!b->left->tax) && (b->left->v[b->l_v1]->num < b->left->v[b->l_v2]->num)) { buff = b->l_v1; b->l_v1 = b->l_v2; b->l_v2 = buff; } if((!b->rght->tax) && (b->rght->v[b->r_v1]->num < b->rght->v[b->r_v2]->num)) { buff = b->r_v1; b->r_v1 = b->r_v2; b->r_v2 = buff; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Exit(char *message) { fflush(NULL); PhyML_Fprintf(stderr,"%s",message); exit(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void *mCalloc(int nb, size_t size) { void *allocated; if((allocated = calloc((size_t)nb,size)) != NULL) /* if((allocated = malloc((size_t)nb*(size_t)size)) != NULL) */ return allocated; else Generic_Exit(__FILE__,__LINE__,__FUNCTION__); return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void *mRealloc(void *p,int nb, size_t size) { if((p = realloc(p,(size_t)nb*size)) != NULL) return p; else Exit("\n== Err: low memory\n"); return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* t_tree *Make_Light_Tree_Struct(int n_otu) */ /* { */ /* t_tree *tree; */ /* int i; */ /* tree = (t_tree *)mCalloc(1,sizeof(t_tree )); */ /* tree->a_edges = (t_edge **)mCalloc(2*n_otu-3,sizeof(t_edge *)); */ /* tree->a_nodes = (t_node **)mCalloc(2*n_otu-2,sizeof(t_node *)); */ /* tree->n_otu = n_otu; */ /* For(i,2*n_otu-3) */ /* tree->a_edges[i] = Make_Edge_Light(NULL,NULL,i); */ /* For(i,2*n_otu-2) */ /* tree->a_nodes[i] = Make_Node_Light(i); */ /* return tree; */ /* } */ ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sort_Phydbl_Decrease(const void *a, const void *b) { if((*(phydbl *)(a)) >= (*(phydbl *)(b))) return -1; else return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Qksort_Int(int *A, int *B, int ilo, int ihi) { phydbl pivot; // pivot value for partitioning array int ulo, uhi; // indices at ends of unpartitioned region int ieq; // least index of array entry with value equal to pivot int tempEntry; // temporary entry used for swapping if (ilo >= ihi) { return; } // Select a pivot value. pivot = A[(ilo + ihi)/2]; // Initialize ends of unpartitioned region and least index of entry // with value equal to pivot. ieq = ulo = ilo; uhi = ihi; // While the unpartitioned region is not empty, try to reduce its size. while (ulo <= uhi) { if (A[uhi] > pivot) { // Here, we can reduce the size of the unpartitioned region and // try again. uhi--; } else { // Here, A[uhi] <= pivot, so swap entries at indices ulo and // uhi. tempEntry = A[ulo]; A[ulo] = A[uhi]; A[uhi] = tempEntry; if(B) { tempEntry = B[ulo]; B[ulo] = B[uhi]; B[uhi] = tempEntry; } // After the swap, A[ulo] <= pivot. if (A[ulo] < pivot) { // Swap entries at indices ieq and ulo. tempEntry = A[ieq]; A[ieq] = A[ulo]; A[ulo] = tempEntry; if(B) { tempEntry = B[ieq]; B[ieq] = B[ulo]; B[ulo] = tempEntry; } // After the swap, A[ieq] < pivot, so we need to change // ieq. ieq++; // We also need to change ulo, but we also need to do // that when A[ulo] = pivot, so we do it after this if // statement. } // Once again, we can reduce the size of the unpartitioned // region and try again. ulo++; } } // Now, all entries from index ilo to ieq - 1 are less than the pivot // and all entries from index uhi to ihi + 1 are greater than the // pivot. So we have two regions of the array that can be sorted // recursively to put all of the entries in order. Qksort_Int(A, B, ilo, ieq - 1); Qksort_Int(A, B, uhi + 1, ihi); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Sort in ascending order. Elements in B (if provided) are also re-ordered according to the ordering of A */ void Qksort(phydbl *A, phydbl *B, int ilo, int ihi) { phydbl pivot; // pivot value for partitioning array int ulo, uhi; // indices at ends of unpartitioned region int ieq; // least index of array entry with value equal to pivot phydbl tempEntry; // temporary entry used for swapping if (ilo >= ihi) { return; } // Select a pivot value. pivot = A[(ilo + ihi)/2]; // Initialize ends of unpartitioned region and least index of entry // with value equal to pivot. ieq = ulo = ilo; uhi = ihi; // While the unpartitioned region is not empty, try to reduce its size. while (ulo <= uhi) { if (A[uhi] > pivot) { // Here, we can reduce the size of the unpartitioned region and // try again. uhi--; } else { // Here, A[uhi] <= pivot, so swap entries at indices ulo and // uhi. tempEntry = A[ulo]; A[ulo] = A[uhi]; A[uhi] = tempEntry; if(B) { tempEntry = B[ulo]; B[ulo] = B[uhi]; B[uhi] = tempEntry; } // After the swap, A[ulo] <= pivot. if (A[ulo] < pivot) { // Swap entries at indices ieq and ulo. tempEntry = A[ieq]; A[ieq] = A[ulo]; A[ulo] = tempEntry; if(B) { tempEntry = B[ieq]; B[ieq] = B[ulo]; B[ulo] = tempEntry; } // After the swap, A[ieq] < pivot, so we need to change // ieq. ieq++; // We also need to change ulo, but we also need to do // that when A[ulo] = pivot, so we do it after this if // statement. } // Once again, we can reduce the size of the unpartitioned // region and try again. ulo++; } } // Now, all entries from index ilo to ieq - 1 are less than the pivot // and all entries from index uhi to ihi + 1 are greater than the // pivot. So we have two regions of the array that can be sorted // recursively to put all of the entries in order. Qksort(A, B, ilo, ieq - 1); Qksort(A, B, uhi + 1, ihi); } /********************************************************/ void Qksort_Matrix(phydbl **A, int col, int ilo, int ihi) { phydbl pivot; // pivot value for partitioning array int ulo, uhi; // indices at ends of unpartitioned region int ieq; // least index of array entry with value equal to pivot phydbl *tempEntry; // temporary entry used for swapping tempEntry = NULL; if (ilo >= ihi) { return; } // Select a pivot value. pivot = A[(ilo + ihi)/2][col]; // Initialize ends of unpartitioned region and least index of entry // with value equal to pivot. ieq = ulo = ilo; uhi = ihi; // While the unpartitioned region is not empty, try to reduce its size. while (ulo <= uhi) { if (A[uhi][col] > pivot) { // Here, we can reduce the size of the unpartitioned region and // try again. uhi--; } else { // Here, A[uhi] <= pivot, so swap entries at indices ulo and // uhi. tempEntry = A[ulo]; A[ulo] = A[uhi]; A[uhi] = tempEntry; // After the swap, A[ulo] <= pivot. if (A[ulo][col] < pivot) { // Swap entries at indices ieq and ulo. tempEntry = A[ieq]; A[ieq] = A[ulo]; A[ulo] = tempEntry; // After the swap, A[ieq] < pivot, so we need to change // ieq. ieq++; // We also need to change ulo, but we also need to do // that when A[ulo] = pivot, so we do it after this if // statement. } // Once again, we can reduce the size of the unpartitioned // region and try again. ulo++; } } // Now, all entries from index ilo to ieq - 1 are less than the pivot // and all entries from index uhi to ihi + 1 are greater than the // pivot. So we have two regions of the array that can be sorted // recursively to put all of the entries in order. Qksort_Matrix(A, col, ilo, ieq - 1); Qksort_Matrix(A, col, uhi + 1, ihi); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *Add_Taxa_To_Constraint_Tree(FILE *fp, calign *cdata) { char *line,*long_line; t_tree *tree; int i,j; rewind(fp); line = Return_Tree_String_Phylip(fp); tree = Read_Tree(&line); long_line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); strcpy(long_line,line); long_line[strlen(line)-1] = '\0'; For(i,cdata->n_otu) { For(j,tree->n_otu) { if(!strcmp(tree->a_nodes[j]->name,cdata->c_seq[i]->name)) break; } if(j == tree->n_otu) { strcat(long_line,","); strcat(long_line,cdata->c_seq[i]->name); } } strcat(long_line,");"); Free_Tree(tree); Free(line); return long_line; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Constraint_Tree_Taxa_Names(t_tree *tree, calign *cdata) { int i,j,n_otu_tree,n_otu_cdata; n_otu_tree = tree->n_otu; n_otu_cdata = cdata->n_otu; For(i,n_otu_tree) { For(j,n_otu_cdata) { if(!strcmp(tree->a_nodes[i]->name,cdata->c_seq[j]->name)) break; } if(j==n_otu_cdata) { PhyML_Printf("\n. '%s' was not found in sequence data set\n",tree->a_nodes[i]->name); Warn_And_Exit(""); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Tax_Names_To_Tip_Labels(t_tree *tree, calign *data) { int i; For(i,tree->n_otu) { tree->a_nodes[i]->name = (char *)mCalloc((int)strlen(data->c_seq[i]->name)+1,sizeof(char)); tree->a_nodes[i]->ori_name = tree->a_nodes[i]->name; strcpy(tree->a_nodes[i]->name,data->c_seq[i]->name); tree->a_nodes[i]->tax = 1; tree->a_nodes[i]->num = i; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Share_Lk_Struct(t_tree *t_full, t_tree *t_empt) { int i,j,n_otu; t_edge *b_e,*b_f; t_node *n_e, *n_f; n_otu = t_full->n_otu; t_empt->c_lnL_sorted = t_full->c_lnL_sorted; t_empt->unscaled_site_lk_cat = t_full->unscaled_site_lk_cat; t_empt->cur_site_lk = t_full->cur_site_lk; t_empt->old_site_lk = t_full->old_site_lk; t_empt->triplet_struct = t_full->triplet_struct; t_empt->log_lks_aLRT = t_full->log_lks_aLRT; t_empt->site_lk_cat = t_full->site_lk_cat; t_empt->fact_sum_scale = t_full->fact_sum_scale; For(i,2*n_otu-3) { b_f = t_full->a_edges[i]; b_e = t_empt->a_edges[i]; b_e->Pij_rr = b_f->Pij_rr; b_e->nni = b_f->nni; } for(i=n_otu;i<2*n_otu-2;i++) { n_f = t_full->a_nodes[i]; n_e = t_empt->a_nodes[i]; For(j,3) { if(n_f->b[j]->left == n_f) { if(n_e->b[j]->left == n_e) { n_e->b[j]->p_lk_left = n_f->b[j]->p_lk_left; n_e->b[j]->p_lk_loc_left = n_f->b[j]->p_lk_loc_left; n_e->b[j]->patt_id_left = n_f->b[j]->patt_id_left; n_e->b[j]->sum_scale_left = n_f->b[j]->sum_scale_left; n_e->b[j]->sum_scale_left_cat = n_f->b[j]->sum_scale_left_cat; n_e->b[j]->p_lk_tip_l = n_f->b[j]->p_lk_tip_l; } else { n_e->b[j]->p_lk_rght = n_f->b[j]->p_lk_left; n_e->b[j]->p_lk_loc_rght = n_f->b[j]->p_lk_loc_left; n_e->b[j]->patt_id_rght = n_f->b[j]->patt_id_left; n_e->b[j]->sum_scale_rght = n_f->b[j]->sum_scale_left; n_e->b[j]->sum_scale_rght_cat = n_f->b[j]->sum_scale_left_cat; n_e->b[j]->p_lk_tip_r = n_f->b[j]->p_lk_tip_l; } } else { if(n_e->b[j]->rght == n_e) { n_e->b[j]->p_lk_rght = n_f->b[j]->p_lk_rght; n_e->b[j]->p_lk_loc_rght = n_f->b[j]->p_lk_loc_rght; n_e->b[j]->patt_id_rght = n_f->b[j]->patt_id_rght; n_e->b[j]->sum_scale_rght = n_f->b[j]->sum_scale_rght; n_e->b[j]->sum_scale_rght_cat = n_f->b[j]->sum_scale_rght_cat; n_e->b[j]->p_lk_tip_r = n_f->b[j]->p_lk_tip_r; } else { n_e->b[j]->p_lk_left = n_f->b[j]->p_lk_rght; n_e->b[j]->p_lk_loc_left = n_f->b[j]->p_lk_loc_rght; n_e->b[j]->patt_id_left = n_f->b[j]->patt_id_rght; n_e->b[j]->sum_scale_left = n_f->b[j]->sum_scale_rght; n_e->b[j]->sum_scale_left_cat = n_f->b[j]->sum_scale_rght_cat; n_e->b[j]->p_lk_tip_l = n_f->b[j]->p_lk_tip_r; } } } } For(i,n_otu) { n_f = t_full->a_nodes[i]; n_e = t_empt->a_nodes[i]; if(n_f->b[0]->rght == n_f) { n_e->b[0]->p_lk_rght = n_f->b[0]->p_lk_rght; n_e->b[0]->p_lk_loc_rght = n_f->b[0]->p_lk_loc_rght; n_e->b[0]->patt_id_rght = n_f->b[0]->patt_id_rght; n_e->b[0]->sum_scale_rght = n_f->b[0]->sum_scale_rght; n_e->b[0]->sum_scale_rght_cat = n_f->b[0]->sum_scale_rght_cat; n_e->b[0]->p_lk_tip_r = n_f->b[0]->p_lk_tip_r; } else { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Share_Spr_Struct(t_tree *t_full, t_tree *t_empt) { t_empt->size_spr_list = t_full->size_spr_list; t_empt->spr_list = t_full->spr_list; t_empt->best_spr = t_full->best_spr; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Share_Pars_Struct(t_tree *t_full, t_tree *t_empt) { int i; t_empt->site_pars = t_full->site_pars; t_empt->step_mat = t_full->step_mat; For(i,2*t_full->n_otu-3) { t_empt->a_edges[i]->ui_l = t_full->a_edges[i]->ui_l; t_empt->a_edges[i]->ui_r = t_full->a_edges[i]->ui_r; t_empt->a_edges[i]->pars_l = t_full->a_edges[i]->pars_l; t_empt->a_edges[i]->pars_r = t_full->a_edges[i]->pars_r; t_empt->a_edges[i]->p_pars_l = t_full->a_edges[i]->p_pars_l; t_empt->a_edges[i]->p_pars_r = t_full->a_edges[i]->p_pars_r; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sort_Edges_NNI_Score(t_tree *tree, t_edge **sorted_edges, int n_elem) { int i,j; t_edge *buff; For(i,n_elem-1) { for(j=i+1;jnni->score < sorted_edges[i]->nni->score) { buff = sorted_edges[j]; sorted_edges[j] = sorted_edges[i]; sorted_edges[i] = buff; } } } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sort_Edges_Depth(t_tree *tree, t_edge **sorted_edges, int n_elem) { int i,j; t_edge *buff; phydbl *depth,buff_depth; depth = (phydbl *)mCalloc(n_elem,sizeof(phydbl)); For(i,n_elem) depth[i] = sorted_edges[i]->left->bip_size[sorted_edges[i]->l_r] * sorted_edges[i]->rght->bip_size[sorted_edges[i]->r_l] ; For(i,n_elem-1) { for(j=i+1;j depth[j]) { buff = sorted_edges[i]; sorted_edges[i] = sorted_edges[j]; sorted_edges[j] = buff; buff_depth = depth[i]; depth[i] = depth[j]; depth[j] = buff_depth; } } } Free(depth); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void NNI(t_tree *tree, t_edge *b_fcus, int do_swap) { t_node *v1,*v2,*v3,*v4; phydbl lk0, lk1, lk2; phydbl lk0_init, lk1_init, lk2_init; phydbl *l0,*l1,*l2; phydbl l_infa, l_infb; phydbl lk_init; t_edge *b; int i; if(tree->prev) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); lk_init = tree->c_lnL; b_fcus->nni->init_l = b_fcus->l->v; b_fcus->nni->init_lk = tree->c_lnL;; b_fcus->nni->best_conf = 0; b_fcus->nni->score = +1.0; lk0 = lk1 = lk2 = UNLIKELY; v1 = v2 = v3 = v4 = NULL; v1 = b_fcus->left->v[b_fcus->l_v1]; v2 = b_fcus->left->v[b_fcus->l_v2]; v3 = b_fcus->rght->v[b_fcus->r_v1]; v4 = b_fcus->rght->v[b_fcus->r_v2]; Record_Br_Len(tree); if(v1->num < v2->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(v3->num < v4->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /***********/ Swap(v2,b_fcus->left,b_fcus->rght,v3,tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); lk1_init = Update_Lk_At_Given_Edge(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->l->v; if(tree->mod->s_opt->fast_nni) { Fast_Br_Len(b_fcus,tree,1); lk1 = Lk(b_fcus,tree); } else { lk1 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); } if(lk1 < lk1_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f %f %G",l_infa,l_infb,b_fcus->l->v); PhyML_Printf("\n== %f -- %f",lk1_init,lk1); PhyML_Printf("\n== Err. in NNI (1)"); } /* l1 = b_fcus->l->v; */ l1 = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree); Swap(v3,b_fcus->left,b_fcus->rght,v2,tree); /***********/ /***********/ Swap(v2,b_fcus->left,b_fcus->rght,v4,tree); Restore_Br_Len(tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); lk2_init = Update_Lk_At_Given_Edge(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->l->v; if(tree->mod->s_opt->fast_nni) { Fast_Br_Len(b_fcus,tree,1); lk2 = Lk(b_fcus,tree); } else { lk2 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); } if(lk2 < lk2_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f %f %G",l_infa,l_infb,b_fcus->l->v); PhyML_Printf("\n== %f -- %f",lk2_init,lk2); PhyML_Printf("\n== Err. in NNI (2)"); } /* l2 = b_fcus->l->v; */ l2 = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree); Swap(v4,b_fcus->left,b_fcus->rght,v2,tree); /***********/ /***********/ Restore_Br_Len(tree); Set_Both_Sides(YES,tree); MIXT_Set_Alias_Subpatt(YES,tree); lk0_init = Update_Lk_At_Given_Edge(b_fcus,tree); MIXT_Set_Alias_Subpatt(NO,tree); if(FABS(lk0_init - lk_init) > tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== lk_init = %f; lk = %f diff = %f l = %G", lk_init, lk0_init, lk_init-lk0_init, b_fcus->l->v); PhyML_Printf("\n== Curr_lnL = %f",Lk(NULL,tree)); Exit("\n== Err. in NNI (3)"); } l_infa = 10.; l_infb = tree->mod->l_min/b_fcus->l->v; if(tree->mod->s_opt->fast_nni) { Fast_Br_Len(b_fcus,tree,1); lk0 = Lk(b_fcus,tree); } else { lk0 = Br_Len_Brent(l_infb,l_infa,b_fcus,tree); } if(lk0 < lk_init - tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== %f %f %f",l_infa,l_infb,b_fcus->l->v); PhyML_Printf("\n== %f -- %f",lk0_init,lk0); PhyML_Printf("\n== Err. in NNI (3)\n"); Exit("\n"); } /* l0 = b_fcus->l->v; */ l0 = MIXT_Get_Lengths_Of_This_Edge(b_fcus,tree); /***********/ b_fcus->nni->lk0 = lk0; b_fcus->nni->lk1 = lk1; b_fcus->nni->lk2 = lk2; b = b_fcus; i = 0; do { b->nni->l0 = l0[i]; b->nni->l1 = l1[i]; b->nni->l2 = l2[i]; b = b->next; i++; } while(b); b_fcus->nni->score = lk0 - MAX(lk1,lk2); if((b_fcus->nni->score < tree->mod->s_opt->min_diff_lk_local) && (b_fcus->nni->score > -tree->mod->s_opt->min_diff_lk_local)) { b_fcus->nni->score = .0; b_fcus->nni->lk1 = b_fcus->nni->lk0; b_fcus->nni->lk2 = b_fcus->nni->lk0; } if(lk0 > MAX(lk1,lk2)) { b_fcus->nni->best_conf = 0; b_fcus->nni->swap_node_v1 = NULL; b_fcus->nni->swap_node_v2 = NULL; b_fcus->nni->swap_node_v3 = NULL; b_fcus->nni->swap_node_v4 = NULL; b = b_fcus; i = 0; do { b->nni->best_l = l0[i]; b = b->next; i++; } while(b); } else if(lk1 > MAX(lk0,lk2)) { b_fcus->nni->best_conf = 1; b_fcus->nni->swap_node_v1 = v2; b_fcus->nni->swap_node_v2 = b_fcus->left; b_fcus->nni->swap_node_v3 = b_fcus->rght; b_fcus->nni->swap_node_v4 = v3; b = b_fcus; i = 0; do { b->nni->best_l = l1[i]; b = b->next; i++; } while(b); } else if(lk2 > MAX(lk0,lk1)) { b_fcus->nni->best_conf = 2; b_fcus->nni->swap_node_v1 = v2; b_fcus->nni->swap_node_v2 = b_fcus->left; b_fcus->nni->swap_node_v3 = b_fcus->rght; b_fcus->nni->swap_node_v4 = v4; b = b_fcus; i = 0; do { b->nni->best_l = l2[i]; b = b->next; i++; } while(b); } else { b_fcus->nni->score = +1.0; b_fcus->nni->best_conf = 0; b_fcus->nni->swap_node_v1 = NULL; b_fcus->nni->swap_node_v2 = NULL; b_fcus->nni->swap_node_v3 = NULL; b_fcus->nni->swap_node_v4 = NULL; b = b_fcus; i = 0; do { b->nni->best_l = l0[i]; b = b->next; i++; } while(b); } if((do_swap) && ((lk1 > lk0) || (lk2 > lk0))) { tree->n_swap++; PhyML_Printf("\n. Swap t_edge %d -> %f",b_fcus->num,MAX(lk1,lk2)); if(lk1 > lk2) { tree->best_lnL = lk1; Swap(v2,b_fcus->left,b_fcus->rght,v3,tree); b = b_fcus; i = 0; do { b->l->v = l1[i]; b = b->next; i++; } while(b); Set_Both_Sides(YES,tree); Lk(NULL,tree); } else { tree->best_lnL = lk2; Swap(v2,b_fcus->left,b_fcus->rght,v4,tree); b = b_fcus; i = 0; do { b->l->v = l2[i]; b = b->next; i++; } while(b); Set_Both_Sides(YES,tree); Lk(NULL,tree); } } else { Restore_Br_Len(tree); Update_PMat_At_Given_Edge(b_fcus,tree); tree->c_lnL = lk_init; } Free(l0); Free(l1); Free(l2); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void NNI_Pars(t_tree *tree, t_edge *b_fcus, int do_swap) { t_node *v1,*v2,*v3,*v4; int pars0, pars1, pars2; int pars_init; pars_init = tree->c_pars; b_fcus->nni->best_conf = 0; b_fcus->nni->score = +1.0; pars0 = pars1 = pars2 = 0; v1 = v2 = v3 = v4 = NULL; v1 = b_fcus->left->v[b_fcus->l_v1]; v2 = b_fcus->left->v[b_fcus->l_v2]; v3 = b_fcus->rght->v[b_fcus->r_v1]; v4 = b_fcus->rght->v[b_fcus->r_v2]; if(v1->num < v2->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(v3->num < v4->num) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /***********/ Swap(v2,b_fcus->left,b_fcus->rght,v3,tree); Set_Both_Sides(YES,tree); pars1 = Update_Pars_At_Given_Edge(b_fcus,tree); Swap(v3,b_fcus->left,b_fcus->rght,v2,tree); /***********/ /***********/ Swap(v2,b_fcus->left,b_fcus->rght,v4,tree); Set_Both_Sides(YES,tree); pars2 = Update_Pars_At_Given_Edge(b_fcus,tree); Swap(v4,b_fcus->left,b_fcus->rght,v2,tree); /***********/ /***********/ Set_Both_Sides(YES,tree); pars0 = Update_Pars_At_Given_Edge(b_fcus,tree); if(pars0 != pars_init) { PhyML_Printf("\n. pars_init = %d; pars0 = %d\n", pars_init, pars0); Warn_And_Exit("\n. Err. in NNI (3)\n"); } /***********/ tree->c_pars = pars0; b_fcus->nni->score = MIN(pars1,pars2) - pars0; if(pars0 < MIN(pars1,pars2)) { b_fcus->nni->best_conf = 0; b_fcus->nni->swap_node_v1 = NULL; b_fcus->nni->swap_node_v2 = NULL; b_fcus->nni->swap_node_v3 = NULL; b_fcus->nni->swap_node_v4 = NULL; } else if(pars1 < MIN(pars0,pars2)) { b_fcus->nni->best_conf = 1; b_fcus->nni->swap_node_v1 = v2; b_fcus->nni->swap_node_v2 = b_fcus->left; b_fcus->nni->swap_node_v3 = b_fcus->rght; b_fcus->nni->swap_node_v4 = v3; } else if(pars2 > MIN(pars0,pars1)) { b_fcus->nni->best_conf = 2; b_fcus->nni->swap_node_v1 = v2; b_fcus->nni->swap_node_v2 = b_fcus->left; b_fcus->nni->swap_node_v3 = b_fcus->rght; b_fcus->nni->swap_node_v4 = v4; } else { b_fcus->nni->score = +1.0; b_fcus->nni->swap_node_v1 = NULL; b_fcus->nni->swap_node_v2 = NULL; b_fcus->nni->swap_node_v3 = NULL; b_fcus->nni->swap_node_v4 = NULL; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Swap(t_node *a, t_node *b, t_node *c, t_node *d, t_tree *tree) { int ab, ba, cd, dc, bc; int i; /* \ /d \ /a * \ / \ / * \b__...__c/ -> \b__...__c/ * / \ / \ * / \ / \ * /a \ /d \ * * nodes b and c are not necessarily on the same branch */ if(!tree) return; #ifdef DEBUG if(!a || !b || !c || !d) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); #endif ab = ba = cd = dc = bc = -1; For(i,3) if(a->v[i] == b) { ab = i; break; } For(i,3) if(b->v[i] == a) { ba = i; break; } For(i,3) if(c->v[i] == d) { cd = i; break; } For(i,3) if(d->v[i] == c) { dc = i; break; } For(i,3) if(b->v[i] == c) { bc = i; break; } #ifdef DEBUG if(ab < 0 || ba < 0 || cd < 0 || dc < 0) { PhyML_Printf("\n== Nodes %d %d %d %d\n",a->num,b->num,c->num,d->num); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } #endif a->v[ab] = c; d->v[dc] = b; b->v[ba] = d; c->v[cd] = a; b->b[ba] = d->b[dc]; c->b[cd] = a->b[ab]; (a->b[ab]->left == b)? (a->b[ab]->left = c): (a->b[ab]->rght = c); (d->b[dc]->left == c)? (d->b[dc]->left = b): (d->b[dc]->rght = b); For(i,3) { if(a->b[ab]->left->v[i] == a->b[ab]->rght) a->b[ab]->l_r = i; if(a->b[ab]->rght->v[i] == a->b[ab]->left) a->b[ab]->r_l = i; if(d->b[dc]->left->v[i] == d->b[dc]->rght) d->b[dc]->l_r = i; if(d->b[dc]->rght->v[i] == d->b[dc]->left) d->b[dc]->r_l = i; } a->b[ab]->l_v1 = a->b[ab]->l_v2 = a->b[ab]->r_v1 = a->b[ab]->r_v2 = d->b[dc]->l_v1 = d->b[dc]->l_v2 = d->b[dc]->r_v1 = d->b[dc]->r_v2 = -1; For(i,3) { if(i != a->b[ab]->l_r) { if(a->b[ab]->l_v1 < 0) a->b[ab]->l_v1 = i; else a->b[ab]->l_v2 = i; } if(i != a->b[ab]->r_l) { if(a->b[ab]->r_v1 < 0) a->b[ab]->r_v1 = i; else a->b[ab]->r_v2 = i; } if(i != d->b[dc]->l_r) { if(d->b[dc]->l_v1 < 0) d->b[dc]->l_v1 = i; else d->b[dc]->l_v2 = i; } if(i != d->b[dc]->r_l) { if(d->b[dc]->r_v1 < 0) d->b[dc]->r_v1 = i; else d->b[dc]->r_v2 = i; } } Update_Dirs(tree); if(tree->next) Swap(a->next,b->next,c->next,d->next,tree->next); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_All_Partial_Lk(t_edge *b_fcus, t_tree *tree) { Update_SubTree_Partial_Lk(b_fcus->left->b[b_fcus->l_v1], b_fcus->left, b_fcus->left->v[b_fcus->l_v1], tree); Update_SubTree_Partial_Lk(b_fcus->left->b[b_fcus->l_v2], b_fcus->left, b_fcus->left->v[b_fcus->l_v2], tree); Update_SubTree_Partial_Lk(b_fcus->rght->b[b_fcus->r_v1], b_fcus->rght, b_fcus->rght->v[b_fcus->r_v1], tree); Update_SubTree_Partial_Lk(b_fcus->rght->b[b_fcus->r_v2], b_fcus->rght, b_fcus->rght->v[b_fcus->r_v2], tree); tree->c_lnL = Lk(b_fcus,tree); if(tree->next) Update_All_Partial_Lk(tree->next->a_edges[b_fcus->num], tree->next); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_SubTree_Partial_Lk(t_edge *b_fcus, t_node *a, t_node *d, t_tree *tree) { int i; Update_P_Lk(tree,b_fcus,a); if(d->tax) return; else For(i,3) if(d->v[i] != a) Update_SubTree_Partial_Lk(d->b[i],d,d->v[i],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Seq_Names_To_Tip_Labels(t_tree *tree, calign *data) { int i; For(i,tree->n_otu) { strcpy(tree->a_nodes[i]->name,data->c_seq[i]->name); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// calign *Copy_Cseq(calign *ori, option *io) { calign *new; int i,j,k,n_otu,c_len; char **sp_names; n_otu = ori->n_otu; c_len = ori->crunch_len; sp_names = (char **)mCalloc(n_otu,sizeof(char *)); For(i,n_otu) { sp_names[i] = (char *)mCalloc(strlen(ori->c_seq[i]->name)+1,sizeof(char)); strcpy(sp_names[i],ori->c_seq[i]->name); } new = Make_Cseq(n_otu,c_len+1,io->state_len,ori->init_len,sp_names); new->obs_pinvar = ori->obs_pinvar; For(i,ori->init_len) new->sitepatt[i] = ori->sitepatt[i]; For(j,ori->crunch_len) { For(i,ori->n_otu) { For(k,io->state_len) { new->c_seq[i]->state[j*io->state_len+k] = ori->c_seq[i]->state[j*io->state_len+k]; } new->c_seq[i]->is_ambigu[j] = ori->c_seq[i]->is_ambigu[j]; } new->wght[j] = ori->wght[j]; new->ambigu[j] = ori->ambigu[j]; new->invar[j] = ori->invar[j]; } For(i,ori->n_otu) { new->c_seq[i]->len = ori->c_seq[i]->len; strcpy(new->c_seq[i]->name,ori->c_seq[i]->name); } For(i,ori->n_otu) new->c_seq[i]->state[c_len*io->state_len] = '\0'; For(i,T_MAX_ALPHABET) new->b_frq[i] = ori->b_frq[i]; new->init_len = ori->init_len; new->clean_len = ori->clean_len; new->crunch_len = ori->crunch_len; new->n_otu = ori->n_otu; new->io = ori->io; For(i,n_otu) Free(sp_names[i]); Free(sp_names); return new; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Filexists(char *filename) { FILE *fp; fp =fopen(filename,"r"); if (fp) { fclose(fp); return 1; } else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// matrix *K80_dist(calign *data, phydbl g_shape) { int i,j,k; int diff; matrix *mat; phydbl **len; len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *)); For(i,data->n_otu) len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl)); mat = Make_Mat(data->n_otu); Init_Mat(mat,data); diff = 0; For(i,data->c_seq[0]->len) { For(j,data->n_otu-1) { for(k=j+1;kn_otu;k++) { if(((data->c_seq[j]->state[i] == 'A' || data->c_seq[j]->state[i] == 'G') && (data->c_seq[k]->state[i] == 'C' || data->c_seq[k]->state[i] == 'T'))|| ((data->c_seq[j]->state[i] == 'C' || data->c_seq[j]->state[i] == 'T') && (data->c_seq[k]->state[i] == 'A' || data->c_seq[k]->state[i] == 'G'))) { diff++; mat->Q[j][k]+=data->wght[i]; len[j][k]+=data->wght[i]; len[k][j]=len[j][k]; } else if(((data->c_seq[j]->state[i] == 'A' && data->c_seq[k]->state[i] == 'G') || (data->c_seq[j]->state[i] == 'G' && data->c_seq[k]->state[i] == 'A'))|| ((data->c_seq[j]->state[i] == 'C' && data->c_seq[k]->state[i] == 'T') || (data->c_seq[j]->state[i] == 'T' && data->c_seq[k]->state[i] == 'C'))) { diff++; mat->P[j][k]+=data->wght[i]; len[j][k]+=data->wght[i]; len[k][j]=len[j][k]; } else if((data->c_seq[j]->state[i] == 'A' || data->c_seq[j]->state[i] == 'C' || data->c_seq[j]->state[i] == 'G' || data->c_seq[j]->state[i] == 'T')&& (data->c_seq[k]->state[i] == 'A' || data->c_seq[k]->state[i] == 'C' || data->c_seq[k]->state[i] == 'G' || data->c_seq[k]->state[i] == 'T')) { len[j][k]+=data->wght[i]; len[k][j]=len[j][k]; } } } } For(i,data->n_otu-1) for(j=i+1;jn_otu;j++) { if(len[i][j] > .0) { mat->P[i][j] /= len[i][j]; mat->Q[i][j] /= len[i][j]; } else { mat->P[i][j] = .5; mat->Q[i][j] = .5; } mat->P[j][i] = mat->P[i][j]; mat->Q[j][i] = mat->Q[i][j]; if((1-2*mat->P[i][j]-mat->Q[i][j] <= .0) || (1-2*mat->Q[i][j] <= .0)) { mat->dist[i][j] = -1.; mat->dist[j][i] = -1.; continue; } mat->dist[i][j] = (g_shape/2)* (POW(1-2*mat->P[i][j]-mat->Q[i][j],-1./g_shape) + 0.5*POW(1-2*mat->Q[i][j],-1./g_shape) - 1.5); if(mat->dist[i][j] > DIST_MAX) mat->dist[i][j] = DIST_MAX; mat->dist[j][i] = mat->dist[i][j]; } For(i,data->n_otu) free(len[i]); free(len); return mat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// matrix *JC69_Dist(calign *data, t_mod *mod) { int site,i,j,k; matrix *mat; phydbl **len; int datatype; len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *)); For(i,data->n_otu) len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl)); mat = Make_Mat(data->n_otu); Init_Mat(mat,data); datatype = mod->io->datatype; For(site,data->c_seq[0]->len) { For(j,data->n_otu-1) { for(k=j+1;kn_otu;k++) { if((!Is_Ambigu(data->c_seq[j]->state+site*mod->io->state_len,datatype,mod->io->state_len)) && (!Is_Ambigu(data->c_seq[k]->state+site*mod->io->state_len,datatype,mod->io->state_len))) { len[j][k]+=data->wght[site]; len[k][j]=len[j][k]; if(strncmp(data->c_seq[j]->state+site*mod->io->state_len, data->c_seq[k]->state+site*mod->io->state_len,mod->io->state_len)) /* if(!Are_Compatible(data->c_seq[j]->state+site*mod->io->state_len, */ /* data->c_seq[k]->state+site*mod->io->state_len, */ /* mod->io->state_len, */ /* mod->io->datatype)) */ mat->P[j][k]+=data->wght[site]; } } } } For(i,data->n_otu-1) for(j=i+1;jn_otu;j++) { if(len[i][j] > .0) mat->P[i][j] /= len[i][j]; else mat->P[i][j] = 1.; mat->P[j][i] = mat->P[i][j]; if((1.-(mod->ns)/(mod->ns-1.)*mat->P[i][j]) < .0) mat->dist[i][j] = -1.; else mat->dist[i][j] = -(mod->ns-1.)/(mod->ns)*(phydbl)LOG(1.-(mod->ns)/(mod->ns-1.)*mat->P[i][j]); /* PhyML_Printf("\n. Incorrect JC distances"); */ /* mat->dist[i][j] = len[i][j]; */ if(mat->dist[i][j] > DIST_MAX) mat->dist[i][j] = DIST_MAX; mat->dist[j][i] = mat->dist[i][j]; } For(i,data->n_otu) free(len[i]); free(len); return mat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// matrix *Hamming_Dist(calign *data, t_mod *mod) { int i,j,k; matrix *mat; phydbl **len; int datatype; len = (phydbl **)mCalloc(data->n_otu,sizeof(phydbl *)); For(i,data->n_otu) len[i] = (phydbl *)mCalloc(data->n_otu,sizeof(phydbl)); mat = Make_Mat(data->n_otu); Init_Mat(mat,data); datatype = mod->io->datatype; For(i,data->crunch_len) { For(j,data->n_otu-1) { for(k=j+1;kn_otu;k++) { if((!Is_Ambigu(data->c_seq[j]->state+i*mod->io->state_len,datatype,mod->io->state_len)) && (!Is_Ambigu(data->c_seq[k]->state+i*mod->io->state_len,datatype,mod->io->state_len))) { len[j][k]+=data->wght[i]; len[k][j]=len[j][k]; /* if(data->c_seq[j]->state[i] != data->c_seq[k]->state[i]) */ if(!Are_Compatible(data->c_seq[j]->state+i*mod->io->state_len, data->c_seq[k]->state+i*mod->io->state_len, mod->io->state_len, mod->io->datatype)) { mat->P[j][k]+=data->wght[i]; } } } } } For(i,data->n_otu-1) for(j=i+1;jn_otu;j++) { if(len[i][j] > .0) { mat->P[i][j] /= len[i][j]; } else { mat->P[i][j] = 1.; } mat->P[j][i] = mat->P[i][j]; mat->dist[i][j] = mat->P[i][j]; if(mat->dist[i][j] > DIST_MAX) { mat->dist[i][j] = DIST_MAX; } mat->dist[j][i] = mat->dist[i][j]; } For(i,data->n_otu) free(len[i]); free(len); return mat; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Test if the given site pattern is invariant. Does not handle ambiguities */ int Is_Invar(int patt_num, int stepsize, int datatype, calign *data) { int i, j; For(i,data->n_otu) { For(j,data->n_otu) { if(!(Are_Compatible(data->c_seq[i]->state+patt_num, data->c_seq[j]->state+patt_num, stepsize, datatype))) { break; } } if(j != data->n_otu) break; } if(i == data->n_otu) return 1; else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Is_Ambigu(char *state, int datatype, int stepsize) { int val,i; val = -1; if(datatype == NT) { For(i,stepsize) { switch(state[i]) { case 'A' : case 'C' : case 'G' : case 'T' : case 'U' : { val=NO; break; } default : { val=YES; break; } } if(val == YES) break; } } else if(datatype == AA) { switch(state[0]) { case 'X' : case '?' : case '-' : case '.' : {val=YES; break; } default : { val=NO; break; } } } else if(datatype == GENERIC) { int i; For(i,stepsize) if(!isdigit(state[i])) break; if(i == stepsize) val = NO; else val = YES; } return val; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Ambiguities(calign *data, int datatype, int stepsize) { int i,j; For(j,data->crunch_len) { data->ambigu[j] = NO; For(i,data->n_otu) { data->c_seq[i]->is_ambigu[j] = NO; } For(i,data->n_otu) { if(Is_Ambigu(data->c_seq[i]->state+j*stepsize, datatype, stepsize)) { data->ambigu[j] = YES; data->c_seq[i]->is_ambigu[j] = YES; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_D_States(calign *data, int datatype, int stepsize) { int i,j; For(j,data->crunch_len) { For(i,data->n_otu) { if(data->c_seq[i]->is_ambigu[j] == NO) { data->c_seq[i]->d_state[j] = Assign_State(data->c_seq[i]->state+j, datatype, stepsize); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_State_From_Ui(int ui, int datatype) { if(datatype == NT) { switch(ui) { case 1 : {return 0; break;} case 2 : {return 1; break;} case 4 : {return 2; break;} case 8 : {return 3; break;} default : { PhyML_Printf("\n. ui=%d",ui); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } } else if(datatype == AA) { switch(ui) { case 1 : {return 0; break;} case 2 : {return 1; break;} case 4 : {return 2; break;} case 8 : {return 3; break;} case 16 : {return 4; break;} case 32 : {return 5; break;} case 64 : {return 6; break;} case 128 : {return 7; break;} case 256 : {return 8; break;} case 512 : {return 9; break;} case 1024 : {return 10; break;} case 2048 : {return 11; break;} case 4096 : {return 12; break;} case 8192 : {return 13; break;} case 16384 : {return 14; break;} case 32768 : {return 15; break;} case 65536 : {return 16; break;} case 131072 : {return 17; break;} case 262144 : {return 18; break;} case 524288 : {return 19; break;} default : { PhyML_Printf("\n. ui=%d",ui); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } else Generic_Exit(__FILE__,__LINE__,__FUNCTION__); return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Assign_State(char *c, int datatype, int stepsize) { int state[3]; int i; state[0] = state[1] = state[2] = -1; if(datatype == NT) { For(i,stepsize) { switch(c[i]) { case 'A' : {state[i]=0; break;} case 'C' : {state[i]=1; break;} case 'G' : {state[i]=2; break;} case 'T' : {state[i]=3; break;} case 'U' : {state[i]=3; break;} default : {state[i]=-1; break;} } } return (stepsize>1)?(state[0]*16+state[1]*4+state[2]):(state[0]); } else if(datatype == AA) { switch(c[0]) { case 'A' : {state[0]=0 ; break;} case 'R' : {state[0]=1 ; break;} case 'N' : {state[0]=2 ; break;} case 'D' : {state[0]=3 ; break;} case 'C' : {state[0]=4 ; break;} case 'Q' : {state[0]=5 ; break;} case 'E' : {state[0]=6 ; break;} case 'G' : {state[0]=7 ; break;} case 'H' : {state[0]=8 ; break;} case 'I' : {state[0]=9 ; break;} case 'L' : {state[0]=10; break;} case 'K' : {state[0]=11; break;} case 'M' : {state[0]=12; break;} case 'F' : {state[0]=13; break;} case 'P' : {state[0]=14; break;} case 'S' : {state[0]=15; break;} case 'T' : {state[0]=16; break;} case 'W' : {state[0]=17; break;} case 'Y' : {state[0]=18; break;} case 'V' : {state[0]=19; break;} case 'B' : {state[0] = 2; break;} case 'Z' : {state[0] = 5; break;} default : {state[0]=-1; break;} } return state[0]; } else if(datatype == GENERIC) { char format[6]; int ret; sprintf(format,"%%%dd",stepsize); ret = sscanf(c,format,state); if(!ret) state[0] = -1; return state[0]; } else { PhyML_Printf("\n== Not implemented yet.\n"); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char Reciproc_Assign_State(int i_state, int datatype) { if(datatype == NT) { i_state = i_state%4; switch(i_state) { case 0 : {return 'A'; break;} case 1 : {return 'C'; break;} case 2 : {return 'G'; break;} case 3 : {return 'T'; break;} default : { PhyML_Printf("\n. i_state = %d",i_state); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } } else if(datatype == AA) { i_state = i_state%20; switch(i_state) { case 0 : {return 'A' ; break;} case 1 : {return 'R' ; break;} case 2 : {return 'N' ; break;} case 3 : {return 'D' ; break;} case 4 : {return 'C' ; break;} case 5 : {return 'Q' ; break;} case 6 : {return 'E' ; break;} case 7 : {return 'G' ; break;} case 8 : {return 'H' ; break;} case 9 : {return 'I' ; break;} case 10 : {return 'L'; break;} case 11 : {return 'K'; break;} case 12 : {return 'M'; break;} case 13 : {return 'F'; break;} case 14 : {return 'P'; break;} case 15 : {return 'S'; break;} case 16 : {return 'T'; break;} case 17 : {return 'W'; break;} case 18 : {return 'Y'; break;} case 19 : {return 'V'; break;} default : { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } } else if(datatype == GENERIC) { return (char)i_state; } return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Assign_State_With_Ambiguity(char *c, int datatype, int stepsize) { int state[3]; int i; state[0] = state[1] = state[2] = -1; if(datatype == NT) { For(i,stepsize) { switch(c[i]) { case 'A' : {state[i]= 0; break;} case 'C' : {state[i]= 1; break;} case 'G' : {state[i]= 2; break;} case 'T' : {state[i]= 3; break;} case 'U' : {state[i]= 3; break;} case 'M' : {state[i]= 4; break;} case 'R' : {state[i]= 5; break;} case 'W' : {state[i]= 6; break;} case 'S' : {state[i]= 7; break;} case 'Y' : {state[i]= 8; break;} case 'K' : {state[i]= 9; break;} case 'B' : {state[i]=10; break;} case 'D' : {state[i]=11; break;} case 'H' : {state[i]=12; break;} case 'V' : {state[i]=13; break;} case 'N' : case 'X' : case '?' : case 'O' : case '-' : {state[i]=T_MAX_ALPHABET-1; break;} default : { PhyML_Printf("\n== Unknown character state : '%c'\n",c[i]); Warn_And_Exit("\n== Init failed (data type supposed to be DNA)\n"); break; } } return (stepsize>1)?(state[0]*16+state[1]*4+state[2]):(state[0]); } } else if(datatype == AA) { switch(c[0]) { case 'A' : {state[0]= 0; break;} case 'R' : {state[0]= 1; break;} case 'N' : {state[0]= 2; break;} case 'D' : {state[0]= 3; break;} case 'C' : {state[0]= 4; break;} case 'Q' : {state[0]= 5; break;} case 'E' : {state[0]= 6; break;} case 'G' : {state[0]= 7; break;} case 'H' : {state[0]= 8; break;} case 'I' : {state[0]= 9; break;} case 'L' : {state[0]=10; break;} case 'K' : {state[0]=11; break;} case 'M' : {state[0]=12; break;} case 'F' : {state[0]=13; break;} case 'P' : {state[0]=14; break;} case 'S' : {state[0]=15; break;} case 'T' : {state[0]=16; break;} case 'W' : {state[0]=17; break;} case 'Y' : {state[0]=18; break;} case 'V' : {state[0]=19; break;} case 'B' : {state[0]= 2; break;} case 'Z' : {state[0]= 5; break;} case 'X' : case '?' : case '-' : {state[0]=T_MAX_ALPHABET-1; break;} default : { PhyML_Printf("\n== Unknown character state : %c\n",state[0]); Warn_And_Exit("\n== Init failed (data type supposed to be amino-acids)\n"); break; } } return state[0]; } else if(datatype == GENERIC) { if(Is_Ambigu(c,GENERIC,stepsize)) state[0] = T_MAX_ALPHABET-1; else { char format[6]; sprintf(format,"%%%dd",stepsize); if(!sscanf(c,format,state)) { PhyML_Printf("\n== Error reading character. Was expecting an integer, got '%c' instead.\n",c[0]); PhyML_Printf("\n== Err. in file %s at line %d (function '%s')\n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } } return state[0]; } return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Clean_Tree_Connections(t_tree *tree) { int i; For(i,2*tree->n_otu-2) { tree->a_nodes[i]->v[0] = NULL; tree->a_nodes[i]->v[1] = NULL; tree->a_nodes[i]->v[2] = NULL; tree->a_nodes[i]->b[0] = NULL; tree->a_nodes[i]->b[1] = NULL; tree->a_nodes[i]->b[2] = NULL; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Bootstrap(t_tree *tree) { int *site_num, n_site; int replicate,j,k; int position,init_len; calign *boot_data; t_tree *boot_tree; t_mod *boot_mod; matrix *boot_mat; char *s; /* phydbl rf; */ tree->print_boot_val = 1; tree->print_alrt_val = 0; boot_tree = NULL; site_num = (int *)mCalloc(tree->data->init_len,sizeof(int)); Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); n_site = 0; For(j,tree->data->crunch_len) For(k,tree->data->wght[j]) { site_num[n_site] = j; n_site++; } boot_data = Copy_Cseq(tree->data,tree->io); PhyML_Printf("\n\n. Non parametric bootstrap analysis \n\n"); PhyML_Printf(" ["); For(replicate,tree->mod->bootstrap) { For(j,boot_data->crunch_len) boot_data->wght[j] = 0; init_len = 0; For(j,boot_data->init_len) { position = Rand_Int(0,(int)(tree->data->init_len-1.0)); boot_data->wght[site_num[position]] += 1; init_len++; } if(init_len != tree->data->init_len) Exit("\n== Pb. when copying sequences\n"); init_len = 0; For(j,boot_data->crunch_len) init_len += boot_data->wght[j]; if(init_len != tree->data->init_len) Exit("\n== Pb. when copying sequences\n"); if(tree->io->datatype == NT) Get_Base_Freqs(boot_data); else if(tree->io->datatype == AA) Get_AA_Freqs(boot_data); if(tree->io->random_boot_seq_order) Randomize_Sequence_Order(boot_data); Set_D_States(boot_data,tree->io->datatype,tree->io->state_len); boot_mod = Copy_Model(tree->mod); boot_mod->s_opt = tree->mod->s_opt; /* WARNING: re-using the same address here instead of creating a copying requires to leave the value of s_opt unchanged during the boostrap. */ boot_mod->io = tree->io; /* WARNING: re-using the same address here instead of creating a copying requires to leave the value of io unchanged during the boostrap. */ Init_Model(boot_data,boot_mod,tree->io); if(tree->io->mod->use_m4mod) M4_Init_Model(boot_mod->m4mod,boot_data,boot_mod); if(tree->io->in_tree == 2) { rewind(tree->io->fp_in_tree); boot_tree = Read_Tree_File_Phylip(tree->io->fp_in_tree); } else { boot_mat = ML_Dist(boot_data,boot_mod); boot_mat->tree = Make_Tree_From_Scratch(boot_data->n_otu,boot_data); Fill_Missing_Dist(boot_mat); Bionj(boot_mat); boot_tree = boot_mat->tree; boot_tree->mat = boot_mat; } boot_tree->mod = boot_mod; boot_tree->io = tree->io; boot_tree->data = boot_data; boot_tree->mod->s_opt->print = NO; boot_tree->n_pattern = boot_tree->data->crunch_len; boot_tree->io->print_site_lnl = 0; boot_tree->io->print_trace = 0; boot_tree->n_root = NULL; boot_tree->e_root = NULL; Set_Both_Sides(YES,boot_tree); if((boot_tree->mod->s_opt->random_input_tree) && (boot_tree->mod->s_opt->topo_search == SPR_MOVE)) Random_Tree(boot_tree); Connect_CSeqs_To_Nodes(boot_data,tree->io,boot_tree); Check_Br_Lens(boot_tree); Share_Lk_Struct(tree,boot_tree); Share_Spr_Struct(tree,boot_tree); Share_Pars_Struct(tree,boot_tree); Fill_Dir_Table(boot_tree); Update_Dirs(boot_tree); if(tree->mod->s_opt->greedy) Init_P_Lk_Tips_Double(boot_tree); else Init_P_Lk_Tips_Int(boot_tree); Init_Ui_Tips(boot_tree); Init_P_Pars_Tips(boot_tree); Br_Len_Not_Involving_Invar(boot_tree); if(boot_tree->io->do_alias_subpatt) { MIXT_Set_Alias_Subpatt(YES,boot_tree); Lk(NULL,boot_tree); MIXT_Set_Alias_Subpatt(NO,boot_tree); } if(boot_tree->mod->s_opt->opt_topo) { if(boot_tree->mod->s_opt->topo_search == NNI_MOVE) { Simu_Loop(boot_tree); } else if((boot_tree->mod->s_opt->topo_search == SPR_MOVE) || (boot_tree->mod->s_opt->topo_search == BEST_OF_NNI_AND_SPR)) { Speed_Spr_Loop(boot_tree); } } else { if(boot_tree->mod->s_opt->opt_subst_param || boot_tree->mod->s_opt->opt_bl) Round_Optimize(boot_tree,boot_tree->data,ROUND_MAX); else Lk(NULL,boot_tree); } Free_Bip(boot_tree); Alloc_Bip(boot_tree); Match_Tip_Numbers(tree,boot_tree); Get_Bip(boot_tree->a_nodes[0], boot_tree->a_nodes[0]->v[0], boot_tree); Compare_Bip(tree,boot_tree,NO); Check_Br_Lens(boot_tree); Br_Len_Involving_Invar(boot_tree); if(tree->io->print_boot_trees) { s = Write_Tree(boot_tree,NO); PhyML_Fprintf(tree->io->fp_out_boot_tree,"%s\n",s); Free(s); Print_Fp_Out_Lines(tree->io->fp_out_boot_stats,0,0,boot_tree,tree->io,replicate+1); } /* rf = .0; */ /* For(j,2*tree->n_otu-3) */ /* rf += tree->a_edges[j]->bip_score; */ PhyML_Printf("."); #ifndef QUIET fflush(stdout); #endif if(!((replicate+1)%tree->io->boot_prog_every)) { PhyML_Printf("] %4d/%4d\n ",replicate+1,tree->mod->bootstrap); if(replicate != tree->mod->bootstrap-1) PhyML_Printf("["); } Free_Tree(boot_tree); Free_Model(boot_mod); } if(((replicate)%tree->io->boot_prog_every)) PhyML_Printf("] %4d/%4d\n ",replicate,tree->mod->bootstrap); tree->lock_topo = YES; /* Topology should not be modified afterwards */ if(tree->io->print_boot_trees) { fclose(tree->io->fp_out_boot_tree); fclose(tree->io->fp_out_boot_stats); } Free_Cseq(boot_data); Free(site_num); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Br_Len_Involving_Invar(t_tree *tree) { int i; if(tree->is_mixt_tree) { MIXT_Br_Len_Involving_Invar(tree); return; } For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v *= (1.0-tree->mod->ras->pinvar->v); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Br_Len_Not_Involving_Invar(t_tree *tree) { int i; if(tree->is_mixt_tree) { MIXT_Br_Len_Not_Involving_Invar(tree); return; } For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v /= (1.0-tree->mod->ras->pinvar->v); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Getstring_Stdin(char *s) { if(!fgets(s,T_MAX_LINE,stdin)) Exit(""); if (strchr(s, '\n') != NULL) *strchr(s, '\n') = '\0'; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree, phydbl f0, phydbl *param, int which, int n_param, phydbl stepsize, int logt, phydbl *err, int precise, int is_positive) { int i,j; phydbl errt,fac,hh,**a,ans,*sign; int n_iter; sign = (phydbl *)mCalloc(n_param,sizeof(phydbl)); a = (phydbl **)mCalloc(11,sizeof(phydbl *)); For(i,11) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl)); n_iter = 10; /* */ ans = .0; if(stepsize < SMALL) Warn_And_Exit("\n== h must be nonzero in Dfridr."); hh=stepsize; if(!precise) { param[which] = param[which]+hh; if(logt == YES) For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i])); For(i,n_param) sign[i] = param[i] > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]); a[0][0] = (*func)(tree); if(is_positive == YES) For(i,n_param) param[i] *= sign[i]; if(logt == YES) For(i,n_param) param[i] = LOG(param[i]); /* printf("\n. f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,param[which]); */ a[0][0] -= f0; a[0][0] /= hh; param[which] = param[which]-hh; ans = a[0][0]; } else { param[which] = param[which]+hh; if(logt == YES) For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i])); For(i,n_param) sign[i] = param[i] > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]); a[0][0] = (*func)(tree); if(is_positive == YES) For(i,n_param) param[i] *= sign[i]; if(logt == YES) For(i,n_param) param[i] = LOG(param[i]); /* param[which] = param[which]-2*hh; */ /* a[0][0] -= (*func)(tree); */ /* a[0][0] /= (2.0*hh); */ /* param[which] = param[which]+hh; */ a[0][0] -= f0; a[0][0] /= hh; param[which] = param[which]-hh; *err=1e30; for(i=1;i .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]); a[0][i] = (*func)(tree); if(is_positive == YES) For(i,n_param) param[i] *= sign[i]; if(logt == YES) For(j,n_param) param[j] = LOG(param[j]); /* param[which] = param[which]-2*hh; */ /* a[0][i] -= (*func)(tree); */ /* a[0][i] /= (2.0*hh); */ /* param[which] = param[which]+hh; */ a[0][i] -= f0; a[0][i] /= hh; param[which] = param[which]-hh; fac=1.4*1.4; for (j=1;j<=i;j++) { a[j][i]=(a[j-1][i]*fac-a[j-1][i-1])/(fac-1.0); fac=1.4*1.4*fac; errt=MAX(FABS(a[j][i]-a[j-1][i]),FABS(a[j][i]-a[j-1][i-1])); if (errt <= *err) { *err=errt; ans=a[j][i]; } } if(FABS(a[i][i]-a[i-1][i-1]) >= 2.0*(*err)) break; } } For(i,11) Free(a[i]); Free(a); Free(sign); return ans; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree *tree, phydbl f0, phydbl **param, int which, int n_param, phydbl stepsize, int logt, phydbl *err, int precise, int is_positive) { int i,j; phydbl errt,fac,hh,**a,ans,*sign; int n_iter; sign = (phydbl *)mCalloc(n_param,sizeof(phydbl)); a = (phydbl **)mCalloc(11,sizeof(phydbl *)); For(i,11) a[i] = (phydbl *)mCalloc(11,sizeof(phydbl)); n_iter = 10; /* */ ans = .0; if(stepsize < SMALL) Warn_And_Exit("\n== h must be nonzero in Dfridr."); hh=stepsize; if(!precise) { *(param[which]) = *(param[which])+hh; if(logt == YES) For(i,n_param) *(param[i]) = EXP(MIN(1.E+2,*(param[i]))); For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i])); a[0][0] = (*func)(tree); if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i]; if(logt == YES) For(i,n_param) *(param[i]) = LOG(*(param[i])); /* printf("\n. f0=%f f1=%f hh=%G %f",f0,a[0][0],hh,*(param[which])); */ a[0][0] -= f0; a[0][0] /= hh; *(param[which]) = *(param[which])-hh; ans = a[0][0]; } else { *(param[which]) = *(param[which])+hh; if(logt == YES) For(i,n_param) *(param[i]) = EXP(MIN(1.E+2,*(param[i]))); For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i])); a[0][0] = (*func)(tree); if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i]; if(logt == YES) For(i,n_param) *(param[i]) = LOG(*(param[i])); /* *(param[which] = *(param[which]-2*hh; */ /* a[0][0] -= (*func)(tree); */ /* a[0][0] /= (2.0*hh); */ /* *(param[which] = *(param[which]+hh; */ a[0][0] -= f0; a[0][0] /= hh; *(param[which]) = *(param[which])-hh; *err=1e30; for(i=1;i .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) (*(param[i])) = FABS(*(param[i])); a[0][i] = (*func)(tree); if(is_positive == YES) For(i,n_param) (*(param[i])) *= sign[i]; if(logt == YES) For(j,n_param) *(param[j]) = LOG(*(param[j])); /* *(param[which] = *(param[which]-2*hh; */ /* a[0][i] -= (*func)(tree); */ /* a[0][i] /= (2.0*hh); */ /* *(param[which] = *(param[which]+hh; */ a[0][i] -= f0; a[0][i] /= hh; *(param[which]) = *(param[which])-hh; fac=1.4*1.4; for (j=1;j<=i;j++) { a[j][i]=(a[j-1][i]*fac-a[j-1][i-1])/(fac-1.0); fac=1.4*1.4*fac; errt=MAX(FABS(a[j][i]-a[j-1][i]),FABS(a[j][i]-a[j-1][i-1])); if (errt <= *err) { *err=errt; ans=a[j][i]; } } if(FABS(a[i][i]-a[i-1][i-1]) >= 2.0*(*err)) break; } } For(i,11) Free(a[i]); Free(a); Free(sign); return ans; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Num_Derivative_Several_Param(t_tree *tree, phydbl *param, int n_param, phydbl stepsize, int logt, phydbl (*func)(t_tree *tree), phydbl *derivatives, int is_positive) { int i; phydbl err,f0,*sign; sign = (phydbl *)mCalloc(n_param,sizeof(phydbl)); if(logt == YES) For(i,n_param) param[i] = EXP(MIN(1.E+2,param[i])); For(i,n_param) sign[i] = (param[i]) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) param[i] = FABS(param[i]); f0 = (*func)(tree); if(is_positive == YES) For(i,n_param) param[i] *= sign[i]; if(logt == YES) For(i,n_param) param[i] = LOG(param[i]); For(i,n_param) { /* For(j,tree->mod->r_mat->n_diff_rr) PhyML_Printf("\n. 00%d %f",i,tree->mod->r_mat->rr_val->v[j]); */ derivatives[i] = Num_Derivatives_One_Param(func, tree, f0, param, i, n_param, stepsize, logt, &err, 0, is_positive ); } Free(sign); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Num_Derivative_Several_Param_Nonaligned(t_tree *tree, phydbl **param, int n_param, phydbl stepsize, int logt, phydbl (*func)(t_tree *tree), phydbl *derivatives, int is_positive) { int i; phydbl err,f0,*sign; sign = (phydbl *)mCalloc(n_param,sizeof(phydbl)); if(logt == YES) For(i,n_param) (*(param[i])) = EXP(MIN(1.E+2,*(param[i]))); For(i,n_param) sign[i] = (*(param[i])) > .0 ? 1. : -1.; if(is_positive == YES) For(i,n_param) *(param[i]) = FABS(*(param[i])); f0 = (*func)(tree); if(is_positive == YES) For(i,n_param) *(param[i]) *= sign[i]; if(logt == YES) For(i,n_param) (*(param[i])) = LOG(*(param[i])); For(i,n_param) { derivatives[i] = Num_Derivatives_One_Param_Nonaligned(func, tree, f0, param, i, n_param, stepsize, logt, &err, 0, is_positive ); } Free(sign); return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Compare_Two_States(char *state1, char *state2, int state_size) { /* 1 the two states are identical */ /* 0 the two states are different */ int i; For(i,state_size) if(state1[i] != state2[i]) break; return (i==state_size)?(1):(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_One_State(char *from, char *to, int state_size) { int i; For(i,state_size) to[i] = from[i]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Dist(phydbl **cpy, phydbl **orig, int n) { int i,j; For(i,n) For(j,n) cpy[i][j] = orig[i][j]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_mod *Copy_Model(t_mod *ori) { t_mod *cpy; cpy = Make_Model_Basic(); cpy->ns = ori->ns; cpy->ras->n_catg = ori->ras->n_catg; cpy->whichmodel = ori->whichmodel; Make_Model_Complete(cpy); Record_Model(ori,cpy); cpy->m4mod = M4_Copy_M4_Model(ori, ori->m4mod); #ifdef BEAGLE cpy->b_inst = ori->b_inst; cpy->optimizing_topology = ori->optimizing_topology; #endif return cpy; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Record_Model(t_mod *ori, t_mod *cpy) { int i; cpy->ns = ori->ns; cpy->ras->n_catg = ori->ras->n_catg; cpy->ras->normalise_rr = ori->ras->normalise_rr; cpy->l_var_sigma = ori->l_var_sigma; cpy->kappa->v = ori->kappa->v; cpy->ras->alpha->v = ori->ras->alpha->v; cpy->lambda->v = ori->lambda->v; cpy->ras->pinvar->v = ori->ras->pinvar->v; cpy->br_len_mult->v = ori->br_len_mult->v; strcpy(cpy->modelname->s,ori->modelname->s); strcpy(cpy->custom_mod_string->s,ori->custom_mod_string->s); cpy->mod_num = ori->mod_num; cpy->whichmodel = ori->whichmodel; cpy->update_eigen = ori->update_eigen; cpy->bootstrap = ori->bootstrap; cpy->ras->invar = ori->ras->invar; cpy->r_mat->n_diff_rr = ori->r_mat->n_diff_rr; cpy->l_min = ori->l_min; cpy->l_max = ori->l_max; cpy->log_l = ori->log_l; cpy->ras->free_mixt_rates = ori->ras->free_mixt_rates; cpy->ras->gamma_median = ori->ras->gamma_median; if((ori->whichmodel == CUSTOM) || (ori->whichmodel == GTR)) { For(i,ori->ns*(ori->ns-1)/2) { cpy->r_mat->rr_num->v[i] = ori->r_mat->rr_num->v[i]; cpy->r_mat->rr_val->v[i] = ori->r_mat->rr_val->v[i]; cpy->r_mat->rr->v[i] = ori->r_mat->rr->v[i]; cpy->r_mat->n_rr_per_cat->v[i] = ori->r_mat->n_rr_per_cat->v[i]; } } For(i,cpy->ns) { cpy->e_frq->pi->v[i] = ori->e_frq->pi->v[i]; cpy->e_frq->pi_unscaled->v[i] = ori->e_frq->pi_unscaled->v[i]; cpy->user_b_freq->v[i] = ori->user_b_freq->v[i]; } For(i,cpy->ns*cpy->ns) cpy->r_mat->qmat->v[i] = ori->r_mat->qmat->v[i]; For(i,cpy->ras->n_catg) { cpy->ras->gamma_r_proba->v[i] = ori->ras->gamma_r_proba->v[i]; cpy->ras->gamma_rr->v[i] = ori->ras->gamma_rr->v[i]; cpy->ras->gamma_r_proba_unscaled->v[i] = ori->ras->gamma_r_proba_unscaled->v[i]; cpy->ras->gamma_rr_unscaled->v[i] = ori->ras->gamma_rr_unscaled->v[i]; } cpy->use_m4mod = ori->use_m4mod; cpy->eigen->size = ori->eigen->size; For(i,2*ori->ns) cpy->eigen->space[i] = ori->eigen->space[i]; For(i,2*ori->ns) cpy->eigen->space_int[i] = ori->eigen->space_int[i]; For(i,ori->ns) cpy->eigen->e_val[i] = ori->eigen->e_val[i]; For(i,ori->ns) cpy->eigen->e_val_im[i] = ori->eigen->e_val_im[i]; For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect[i] = ori->eigen->r_e_vect[i]; For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect[i] = ori->eigen->r_e_vect[i]; For(i,ori->ns*ori->ns) cpy->eigen->r_e_vect_im[i] = ori->eigen->r_e_vect_im[i]; For(i,ori->ns*ori->ns) cpy->eigen->l_e_vect[i] = ori->eigen->l_e_vect[i]; For(i,ori->ns*ori->ns) cpy->eigen->q[i] = ori->eigen->q[i]; #ifdef BEAGLE cpy->b_inst = ori->b_inst; cpy->optimizing_topology = ori->optimizing_topology; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Test_Node_Table_Consistency(t_tree *tree) { int i; For(i,2*tree->n_otu-2) { if(tree->a_nodes[i]->num != i) { PhyML_Printf("\n== Node table is not consistent with node numbers."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Bip(t_node *a, t_node *d, t_tree *tree) { int i,j; t_node *tmp; int swapped; if(!d || !a || !tree) { PhyML_Printf("\n== d: %p a: %p tree: %p",d,a,tree); PhyML_Printf("\n== Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } if(d->tax) { if(d->common) { d->bip_node[0] = (t_node **)mCalloc(1,sizeof(t_node *)); d->bip_node[0][0] = d; d->bip_size[0] = 1; d->bip_size[1] = -1; d->bip_size[2] = -1; For(i,3) { if(a->v[i] == d) { a->bip_size[i] = 0; For(j,tree->n_otu) { if(strcmp(tree->a_nodes[j]->name,d->name)) { a->bip_node[i] = (t_node **)realloc(a->bip_node[i],(a->bip_size[i]+1)*sizeof(t_node *)); a->bip_node[i][a->bip_size[i]] = tree->a_nodes[j]; a->bip_size[i]++; } } /* Sort bipartition */ do { swapped = NO; For(j,a->bip_size[i]-1) { if(a->bip_node[i][j]->num > a->bip_node[i][j+1]->num) { swapped = YES; tmp = a->bip_node[i][j]; a->bip_node[i][j] = a->bip_node[i][j+1]; a->bip_node[i][j+1] = tmp; } } }while(swapped == YES); break; } } } return; } else { int k; int d_a; d_a = -1; For(i,3) { if(d->v[i] != a) Get_Bip(d,d->v[i],tree); else if(d->v[i] == a) d_a = i; } d->bip_size[d_a] = 0; For(i,3) if(d->v[i] != a) { For(j,3) { if(d->v[i]->v[j] == d) { For(k,d->v[i]->bip_size[j]) { d->bip_node[d_a] = (t_node **)realloc(d->bip_node[d_a],(d->bip_size[d_a]+1)*sizeof(t_node *)); d->bip_node[d_a][d->bip_size[d_a]] = d->v[i]->bip_node[j][k]; d->bip_size[d_a]++; } break; } } } do { swapped = NO; For(j,d->bip_size[d_a]-1) { if(d->bip_node[d_a][j]->num > d->bip_node[d_a][j+1]->num) { swapped = YES; tmp = d->bip_node[d_a][j]; d->bip_node[d_a][j] = d->bip_node[d_a][j+1]; d->bip_node[d_a][j+1] = tmp; } } }while(swapped == YES); For(i,3) if(a->v[i] == d) { a->bip_size[i] = 0; For(j,tree->n_otu) { For(k,d->bip_size[d_a]) { if(d->bip_node[d_a][k] == tree->a_nodes[j]) break; } if((k == d->bip_size[d_a]) && (tree->a_nodes[j]->common)) { a->bip_node[i] = (t_node **)realloc(a->bip_node[i],(a->bip_size[i]+1)*sizeof(t_node *)); a->bip_node[i][a->bip_size[i]] = tree->a_nodes[j]; a->bip_size[i]++; } } do { swapped = NO; For(j,a->bip_size[i]-1) { if(a->bip_node[i][j]->num > a->bip_node[i][j+1]->num) { swapped = YES; tmp = a->bip_node[i][j]; a->bip_node[i][j] = a->bip_node[i][j+1]; a->bip_node[i][j+1] = tmp; } } }while(swapped == YES); if(a->bip_size[i] != tree->n_otu - d->bip_size[d_a]) { PhyML_Printf("%d %d \n",a->bip_size[i],tree->n_otu - d->bip_size[d_a]); Warn_And_Exit("\n. Problem in counting bipartitions \n"); } break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Alloc_Bip(t_tree *tree) { int i; if(tree->has_bip) return; tree->has_bip = YES; For(i,2*tree->n_otu-2) { tree->a_nodes[i]->bip_size = (int *)mCalloc(3,sizeof(int)); tree->a_nodes[i]->bip_node = (t_node ***)mCalloc(3,sizeof(t_node **)); /* For(j,3) */ /* { */ /* tree->a_nodes[i]->bip_node[j] = (t_node **)mCalloc(tree->n_otu,sizeof(t_node *)); */ /* } */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sort_Phydbl_Increase(const void *a, const void *b) { if((*(phydbl *)(a)) <= (*(phydbl *)(b))) return -1; else return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Sort_String(const void *a, const void *b) { return(strcmp((*(const char **)(a)), (*(const char **)(b)))); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Compare_Bip(t_tree *tree1, t_tree *tree2, int on_existing_edges_only) { int i,j,k; t_edge *b1,*b2; /* char **bip1,**bip2; */ /* int *bip1,*bip2; */ t_node **bip1, **bip2; int bip_size1, bip_size2, bip_size; int different,identical; int n_edges; /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ /* WARNING: call Match_Tip_Numbers and Get_Bip before using this function. */ /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ if(on_existing_edges_only == YES) { n_edges = 0; For(i,2*tree1->n_otu-3) if(tree1->a_edges[i]->does_exist && tree2->a_edges[i]->does_exist) n_edges++; n_edges -= tree1->n_otu; } else { n_edges = tree1->n_otu-3; } identical = 0; different = 0; For(i,2*tree1->n_otu-3) { b1 = tree1->a_edges[i]; bip_size1 = MIN(b1->left->bip_size[b1->l_r],b1->rght->bip_size[b1->r_l]); if(bip_size1 > 1 && ((on_existing_edges_only == YES && b1->does_exist) || (on_existing_edges_only == NO))) { For(j,2*tree2->n_otu-3) { b2 = tree2->a_edges[j]; bip_size2 = MIN(b2->left->bip_size[b2->l_r],b2->rght->bip_size[b2->r_l]); if(bip_size2 > 1 && ((on_existing_edges_only == YES && b2->does_exist) || (on_existing_edges_only == NO))) { if(bip_size1 == bip_size2) { bip_size = bip_size1; if(b1->left->bip_size[b1->l_r] == b1->rght->bip_size[b1->r_l]) { /* if(b1->left->bip_name[b1->l_r][0][0] < b1->rght->bip_name[b1->r_l][0][0]) */ if(b1->left->bip_node[b1->l_r][0]->num < b1->rght->bip_node[b1->r_l][0]->num) { /* bip1 = b1->left->bip_name[b1->l_r]; */ bip1 = b1->left->bip_node[b1->l_r]; } else { /* bip1 = b1->rght->bip_name[b1->r_l]; */ bip1 = b1->rght->bip_node[b1->r_l]; } } else if(b1->left->bip_size[b1->l_r] < b1->rght->bip_size[b1->r_l]) { /* bip1 = b1->left->bip_name[b1->l_r]; */ bip1 = b1->left->bip_node[b1->l_r]; } else { /* bip1 = b1->rght->bip_name[b1->r_l]; */ bip1 = b1->rght->bip_node[b1->r_l]; } if(b2->left->bip_size[b2->l_r] == b2->rght->bip_size[b2->r_l]) { /* if(b2->left->bip_name[b2->l_r][0][0] < b2->rght->bip_name[b2->r_l][0][0]) */ if(b2->left->bip_node[b2->l_r][0]->num < b2->rght->bip_node[b2->r_l][0]->num) { /* bip2 = b2->left->bip_name[b2->l_r]; */ bip2 = b2->left->bip_node[b2->l_r]; } else { /* bip2 = b2->rght->bip_name[b2->r_l]; */ bip2 = b2->rght->bip_node[b2->r_l]; } } else if(b2->left->bip_size[b2->l_r] < b2->rght->bip_size[b2->r_l]) { /* bip2 = b2->left->bip_name[b2->l_r]; */ bip2 = b2->left->bip_node[b2->l_r]; } else { /* bip2 = b2->rght->bip_name[b2->r_l]; */ bip2 = b2->rght->bip_node[b2->r_l]; } if(bip_size == 1) Warn_And_Exit("\n. Problem in Compare_Bip\n"); For(k,bip_size) { /* if(strcmp(bip1[k],bip2[k])) break; */ if(bip1[k]->num != bip2[k]->num) break; } if(k == bip_size) /* Branches b1 and b2 define the same bipartition */ { b1->bip_score++; b2->bip_score++; identical++; goto out; } else { different++; // Bipartitions have identical sizes but distinct elements } } else different++; // Biparition have different sizes } } } out: ; } return n_edges - identical; /* return different; */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Modifiy the tip numbering in tree2 so that tips in tree1 and tree2 corresponding to the same taxon name also have the same tip numbering */ void Match_Tip_Numbers(t_tree *tree1, t_tree *tree2) { int i,j; if(tree1->n_otu != tree2->n_otu) { PhyML_Printf("\n== tree1 and tree2 must have the same number of tips."); /* Otherwise, if tree2->n_otu < tree->n_otu, then some tips in tree2 will have a number (->num) that is the same as the number of an internal node in this tree */ Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } For(i,tree1->n_otu) { For(j,tree2->n_otu) { if(!strcmp(tree1->a_nodes[i]->name,tree2->a_nodes[j]->name)) { tree2->a_nodes[j]->num = tree1->a_nodes[i]->num; break; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Test_Multiple_Data_Set_Format(option *io) { char *line; line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); io->n_trees = 0; while(fgets(line,T_MAX_LINE,io->fp_in_tree)) if(strstr(line,";")) io->n_trees++; Free(line); if((io->mod->bootstrap > 1) && (io->n_trees > 1)) Warn_And_Exit("\n. Bootstrap option is not allowed with multiple input trees !\n"); rewind(io->fp_in_tree); return; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Are_Compatible(char *statea, char *stateb, int stepsize, int datatype) { int i,j; char a,b; if(datatype == NT) { For(i,stepsize) { a = statea[i]; For(j,stepsize) { b = stateb[j]; switch(a) { case 'A': { switch(b) { case 'A' : case 'M' : case 'R' : case 'W' : case 'D' : case 'H' : case 'V' : case 'X' : {break;} default : return 0; } break; } case 'G': { switch(b) { case 'G' : case 'R' : case 'S' : case 'K' : case 'B' : case 'D' : case 'V' : case 'X' : {break;} default : return 0; } break; } case 'C': { switch(b) { case 'C' : case 'M' : case 'S' : case 'Y' : case 'B' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'T': { switch(b) { case 'T' : case 'W' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'H' : case 'X' : { break;} default : return 0; } break; } case 'M' : { switch(b) { case 'M' : case 'A' : case 'C' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'R' : { switch(b) { case 'R' : case 'A' : case 'G' : case 'M' : case 'W' : case 'S' : case 'K' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'W' : { switch(b) { case 'W' : case 'A' : case 'T' : case 'M' : case 'R' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'S' : { switch(b) { case 'S' : case 'C' : case 'G' : case 'M' : case 'R' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'Y' : { switch(b) { case 'Y' : case 'C' : case 'T' : case 'M' : case 'W' : case 'S' : case 'K' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'K' : { switch(b) { case 'K' : case 'G' : case 'T' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'B' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'B' : { switch(b) { case 'B' : case 'C' : case 'G' : case 'T' : case 'M' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'K' : case 'D' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'D' : { switch(b) { case 'D' : case 'A' : case 'G' : case 'T' : case 'M' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'K' : case 'B' : case 'H' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'H' : { switch(b) { case 'H' : case 'A' : case 'C' : case 'T' : case 'M' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'V' : case 'X' : { break;} default : return 0; } break; } case 'V' : { switch(b) { case 'V' : case 'A' : case 'C' : case 'G' : case 'M' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'H' : case 'X' : { break;} default : return 0; } break; } case 'X' : { switch(b) { case 'X' : case 'A' : case 'C' : case 'G' : case 'T' : case 'M' : case 'R' : case 'W' : case 'S' : case 'Y' : case 'K' : case 'B' : case 'D' : case 'H' : case 'V' : { break;} default : return 0; } break; } default : { PhyML_Printf("\n== Err. in Are_Compatible."); PhyML_Printf("\n== Please check that characters `%c` and `%c`",a,b); PhyML_Printf("\n== correspond to existing nucleotides.\n"); Warn_And_Exit("\n"); return 0; } } } } } else if(datatype == AA) { a = statea[0]; b = stateb[0]; switch(a) { case 'A' : { switch(b) { case 'A' : case 'X' : { break;} default : return 0; } break; } case 'R' : { switch(b) { case 'R' : case 'X' : { break;} default : return 0; } break; } case 'N' : { switch(b) { case 'N' : case 'B' : case 'X' : { break;} default : return 0; } break; } case 'B' : { switch(b) { case 'N' : case 'B' : case 'X' : { break;} default : return 0; } break; } case 'D' : { switch(b) { case 'D' : case 'X' : { break;} default : return 0; } break; } case 'C' : { switch(b) { case 'C' : case 'X' : { break;} default : return 0; } break; } case 'Q' : { switch(b) { case 'Q' : case 'Z' : case 'X' : { break;} default : return 0; } break; } case 'Z' : { switch(b) { case 'Q' : case 'Z' : case 'X' : { break;} default : return 0; } break; } case 'E' : { switch(b) { case 'E' : case 'X' : { break;} default : return 0; } break; } case 'G' : { switch(b) { case 'G' : case 'X' : { break;} default : return 0; } break; } case 'H' : { switch(b) { case 'H' : case 'X' : { break;} default : return 0; } break; } case 'I' : { switch(b) { case 'I' : case 'X' : { break;} default : return 0; } break; } case 'L' : { switch(b) { case 'L' : case 'X' : { break;} default : return 0; } break; } case 'K' : { switch(b) { case 'K' : case 'X' : { break;} default : return 0; } break; } case 'M' : { switch(b) { case 'M' : case 'X' : { break;} default : return 0; } break; } case 'F' : { switch(b) { case 'F' : case 'X' : { break;} default : return 0; } break; } case 'P' : { switch(b) { case 'P' : case 'X' : { break;} default : return 0; } break; } case 'S' : { switch(b) { case 'S' : case 'X' : { break;} default : return 0; } break; } case 'T' : { switch(b) { case 'T' : case 'X' : { break;} default : return 0; } break; } case 'W' : { switch(b) { case 'W' : case 'X' : { break;} default : return 0; } break; } case 'Y' : { switch(b) { case 'Y' : case 'X' : { break;} default : return 0; } break; } case 'V' : { switch(b) { case 'V' : case 'X' : { break;} default : return 0; } break; } case 'X' : { switch(b) { case 'A':case 'R':case 'N' :case 'B' :case 'D' : case 'C':case 'Q':case 'Z' :case 'E' :case 'G' : case 'H':case 'I':case 'L' :case 'K' :case 'M' : case 'F':case 'P':case 'S' :case 'T' :case 'W' : case 'Y':case 'V': case 'X' : { break;} default : return 0; } break; } default : { PhyML_Printf("\n== Err. in Are_Compatible."); PhyML_Printf("\n== Please check that characters `%c` and `%c`",a,b); PhyML_Printf("\n== correspond to existing amino-acids.\n"); Warn_And_Exit("\n"); return 0; } } } else if(datatype == GENERIC) { if(Is_Ambigu(statea,GENERIC,stepsize) || Is_Ambigu(stateb,GENERIC,stepsize)) return 1; else { int a,b; char format[6]; sprintf(format,"%%%dd",stepsize); if(!sscanf(statea,format,&a)) { PhyML_Printf("\n== statea = %s",statea); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(!sscanf(stateb,format,&b)) { PhyML_Printf("\n== statea = %s",stateb); PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } /* PhyML_Printf("\n. %s %d a=%d b=%d ",__FILE__,__LINE__,a,b); */ if(a == b) return 1; } return 0; } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Hide_Ambiguities(calign *data) { int i; For(i,data->crunch_len) if(data->ambigu[i]) data->wght[i] = 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Tree(t_tree *ori, t_tree *cpy) { int i,j; For(i,2*ori->n_otu-2) { For(j,3) { if(ori->a_nodes[i]->v[j]) { cpy->a_nodes[i]->v[j] = cpy->a_nodes[ori->a_nodes[i]->v[j]->num]; cpy->a_nodes[i]->l[j] = ori->a_nodes[i]->l[j]; cpy->a_nodes[i]->b[j] = cpy->a_edges[ori->a_nodes[i]->b[j]->num]; } else { cpy->a_nodes[i]->v[j] = NULL; cpy->a_nodes[i]->b[j] = NULL; } } } For(i,2*ori->n_otu-3) { cpy->a_edges[i]->l->v = ori->a_edges[i]->l->v; cpy->a_edges[i]->l_old->v = ori->a_edges[i]->l_old->v; cpy->a_edges[i]->l_var->v = ori->a_edges[i]->l_var->v; cpy->a_edges[i]->l_var_old->v = ori->a_edges[i]->l_var_old->v; cpy->a_edges[i]->left = cpy->a_nodes[ori->a_edges[i]->left->num]; cpy->a_edges[i]->rght = cpy->a_nodes[ori->a_edges[i]->rght->num]; cpy->a_edges[i]->l_v1 = ori->a_edges[i]->l_v1; cpy->a_edges[i]->l_v2 = ori->a_edges[i]->l_v2; cpy->a_edges[i]->r_v1 = ori->a_edges[i]->r_v1; cpy->a_edges[i]->r_v2 = ori->a_edges[i]->r_v2; cpy->a_edges[i]->l_r = ori->a_edges[i]->l_r; cpy->a_edges[i]->r_l = ori->a_edges[i]->r_l; cpy->a_edges[i]->does_exist = ori->a_edges[i]->does_exist; #ifdef BEAGLE cpy->a_edges[i]->p_lk_left_idx = ori->a_edges[i]->p_lk_left_idx; cpy->a_edges[i]->p_lk_rght_idx = ori->a_edges[i]->p_lk_rght_idx; cpy->a_edges[i]->p_lk_tip_idx = ori->a_edges[i]->p_lk_tip_idx; #endif } For(i,ori->n_otu) { cpy->a_nodes[i]->tax = YES; Free(cpy->a_nodes[i]->name); cpy->a_nodes[i]->name = (char *)mCalloc(strlen(ori->a_nodes[i]->name)+1,sizeof(char)); cpy->a_nodes[i]->ori_name = cpy->a_nodes[i]->name ; strcpy(cpy->a_nodes[i]->name,ori->a_nodes[i]->name); } if(ori->n_root) { cpy->e_root = cpy->a_edges[ori->e_root->num]; cpy->n_root = cpy->a_nodes[ori->n_root->num]; Add_Root(cpy->e_root,cpy); } else { cpy->a_edges[2*cpy->n_otu-3]->l->v = ori->a_edges[2*cpy->n_otu-3]->l->v; cpy->a_edges[2*cpy->n_otu-3]->l_old->v = ori->a_edges[2*cpy->n_otu-3]->l_old->v; cpy->a_edges[2*cpy->n_otu-3]->l_var->v = ori->a_edges[2*cpy->n_otu-3]->l_var->v; cpy->a_edges[2*cpy->n_otu-3]->l_var_old->v = ori->a_edges[2*cpy->n_otu-3]->l_var_old->v; cpy->a_edges[2*cpy->n_otu-2]->l->v = ori->a_edges[2*cpy->n_otu-2]->l->v; cpy->a_edges[2*cpy->n_otu-2]->l_old->v = ori->a_edges[2*cpy->n_otu-2]->l_old->v; cpy->a_edges[2*cpy->n_otu-2]->l_var->v = ori->a_edges[2*cpy->n_otu-2]->l_var->v; cpy->a_edges[2*cpy->n_otu-2]->l_var_old->v = ori->a_edges[2*cpy->n_otu-2]->l_var_old->v; } cpy->num_curr_branch_available = 0; cpy->t_beg = ori->t_beg; /* Connect_Edges_To_Nodes_Recur(cpy->a_nodes[0],cpy->a_nodes[0]->v[0],cpy); */ /* Update_Dirs(cpy); */ #ifdef BEAGLE cpy->b_inst = ori->b_inst; #endif } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Prune_Subtree(t_node *a, t_node *d, t_edge **target, t_edge **residual, t_tree *tree) { t_node *v1, *v2; t_edge *b1, *b2; int dir_v1, dir_v2; int i; /* phydbl ***buff_p_lk; */ phydbl *buff_p_lk; int *buff_scale; int *buff_p_pars, *buff_pars, *buff_p_lk_loc, *buff_patt_id; unsigned int *buff_ui; short int *buff_p_lk_tip; if(a->tax) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); dir_v1 = dir_v2 = -1; For(i,3) { if(a->v[i] != d) { if(dir_v1 < 0) dir_v1 = i; else dir_v2 = i; } } if(a->v[dir_v1]->num < a->v[dir_v2]->num) { v1 = a->v[dir_v1]; v2 = a->v[dir_v2]; b1 = a->b[dir_v1]; b2 = a->b[dir_v2]; } else { v1 = a->v[dir_v2]; v2 = a->v[dir_v1]; b1 = a->b[dir_v2]; b2 = a->b[dir_v1]; } assert(NULL != b1 && NULL != b2); /* if(v1->tax && v2->tax) PhyML_Printf("\n. Pruning is meaningless here.\n"); */ a->v[dir_v1] = NULL; a->v[dir_v2] = NULL; a->b[dir_v1] = NULL; a->b[dir_v2] = NULL; #ifdef BEAGLE int temp; #endif if(v1 == b1->left) { b1->rght = v2; if(v2 == b2->left) { buff_p_lk = b1->p_lk_rght; b1->p_lk_rght = b2->p_lk_left; b2->p_lk_left = buff_p_lk; buff_p_lk_tip = b1->p_lk_tip_r; b1->p_lk_tip_r = b2->p_lk_tip_l; b2->p_lk_tip_l = buff_p_lk_tip; #ifdef BEAGLE temp = b1->p_lk_rght_idx; b1->p_lk_rght_idx = b2->p_lk_left_idx; b2->p_lk_left_idx = temp; #endif buff_scale = b1->sum_scale_rght; b1->sum_scale_rght = b2->sum_scale_left; b2->sum_scale_left = buff_scale; buff_scale = b1->sum_scale_rght_cat; b1->sum_scale_rght_cat = b2->sum_scale_left_cat; b2->sum_scale_left_cat = buff_scale; buff_pars = b1->pars_r; b1->pars_r = b2->pars_l; b2->pars_l = buff_pars; buff_ui = b1->ui_r; b1->ui_r = b2->ui_l; b2->ui_l = buff_ui; buff_p_pars = b1->p_pars_r; b1->p_pars_r = b2->p_pars_l; b2->p_pars_l = buff_p_pars; buff_p_lk_loc = b1->p_lk_loc_rght; b1->p_lk_loc_rght = b2->p_lk_loc_left; b2->p_lk_loc_left = buff_p_lk_loc; buff_patt_id = b1->patt_id_rght; b1->patt_id_rght = b2->patt_id_left; b2->patt_id_left = buff_patt_id; } else { buff_p_lk = b1->p_lk_rght; /* b1->p_lk_rght = NULL if b1->rght->tax */ b1->p_lk_rght = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */ b2->p_lk_rght = buff_p_lk; buff_p_lk_tip = b1->p_lk_tip_r; b1->p_lk_tip_r = b2->p_lk_tip_r; b2->p_lk_tip_r = buff_p_lk_tip; #ifdef BEAGLE temp = b1->p_lk_rght_idx; b1->p_lk_rght_idx = b2->p_lk_rght_idx; b2->p_lk_rght_idx = temp; b2->p_lk_tip_idx = b1->p_lk_tip_idx; #endif buff_scale = b1->sum_scale_rght; b1->sum_scale_rght = b2->sum_scale_rght; b2->sum_scale_rght = buff_scale; buff_pars = b1->pars_r; b1->pars_r = b2->pars_r; b2->pars_r = buff_pars; buff_ui = b1->ui_r; b1->ui_r = b2->ui_r; b2->ui_r = buff_ui; buff_p_pars = b1->p_pars_r; b1->p_pars_r = b2->p_pars_r; b2->p_pars_r = buff_p_pars; buff_p_lk_loc = b1->p_lk_loc_rght; b1->p_lk_loc_rght = b2->p_lk_loc_rght; b2->p_lk_loc_rght = buff_p_lk_loc; buff_patt_id = b1->patt_id_rght; b1->patt_id_rght = b2->patt_id_rght; b2->patt_id_rght = buff_patt_id; } } else { b1->left = v2; if(v2 == b2->left) { buff_p_lk = b1->p_lk_left; b1->p_lk_left = b2->p_lk_left; b2->p_lk_left = buff_p_lk; buff_p_lk_tip = b1->p_lk_tip_l; b1->p_lk_tip_l = b2->p_lk_tip_l; b2->p_lk_tip_l = buff_p_lk_tip; #ifdef BEAGLE temp = b1->p_lk_left_idx; b1->p_lk_left_idx = b2->p_lk_left_idx; b2->p_lk_left_idx = temp; #endif buff_scale = b1->sum_scale_left; b1->sum_scale_left = b2->sum_scale_left; b2->sum_scale_left = buff_scale; buff_scale = b1->sum_scale_left_cat; b1->sum_scale_left_cat = b2->sum_scale_left_cat; b2->sum_scale_left_cat = buff_scale; buff_pars = b1->pars_l; b1->pars_l = b2->pars_l; b2->pars_l = buff_pars; buff_ui = b1->ui_l; b1->ui_l = b2->ui_l; b2->ui_l = buff_ui; buff_p_pars = b1->p_pars_l; b1->p_pars_l = b2->p_pars_l; b2->p_pars_l = buff_p_pars; buff_p_lk_loc = b1->p_lk_loc_left; b1->p_lk_loc_left = b2->p_lk_loc_left; b2->p_lk_loc_left = buff_p_lk_loc; buff_patt_id = b1->patt_id_left; b1->patt_id_left = b2->patt_id_left; b2->patt_id_left = buff_patt_id; } else { buff_p_lk = b1->p_lk_left; b1->p_lk_left = b2->p_lk_rght; /* b2->p_lk_rght = NULL if b2->rght->tax */ b2->p_lk_rght = buff_p_lk; buff_p_lk_tip = b1->p_lk_tip_l; b1->p_lk_tip_l = b2->p_lk_tip_r; b2->p_lk_tip_r = buff_p_lk_tip; #ifdef BEAGLE temp = b1->p_lk_left_idx; b1->p_lk_left_idx = b2->p_lk_rght_idx; b2->p_lk_rght_idx = temp; b2->p_lk_tip_idx = b1->p_lk_tip_idx; #endif buff_scale = b1->sum_scale_left; b1->sum_scale_left = b2->sum_scale_rght; b2->sum_scale_rght = buff_scale; buff_scale = b1->sum_scale_left_cat; b1->sum_scale_left_cat = b2->sum_scale_rght_cat; b2->sum_scale_rght_cat = buff_scale; buff_pars = b1->pars_l; b1->pars_l = b2->pars_r; b2->pars_r = buff_pars; buff_ui = b1->ui_l; b1->ui_l = b2->ui_r; b2->ui_r = buff_ui; buff_p_pars = b1->p_pars_l; b1->p_pars_l = b2->p_pars_r; b2->p_pars_r = buff_p_pars; buff_p_lk_loc = b1->p_lk_loc_left; b1->p_lk_loc_left = b2->p_lk_loc_rght; b2->p_lk_loc_rght = buff_p_lk_loc; buff_patt_id = b1->patt_id_left; b1->patt_id_left = b2->patt_id_rght; b2->patt_id_rght = buff_patt_id; } } For(i,3) if(v2->v[i] == a) { v2->v[i] = v1; v2->b[i] = b1; break; } #ifdef DEBUG if(i == 3) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif For(i,3) if(v1->v[i] == a) { v1->v[i] = v2; break; } #ifdef DEBUG if(i == 3) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif if(b1->l->onoff == ON) { b1->l->v += b2->l->v; } (v1 == b1->left)? (Set_Edge_Dirs(b1,v1,v2,tree)): (Set_Edge_Dirs(b1,v2,v1,tree)); if(target) (*target) = b1; if(residual) (*residual) = b2; if(tree->n_root) { if(tree->n_root->v[1] == a) tree->n_root->v[1] = NULL; if(tree->n_root->v[2] == a) tree->n_root->v[2] = NULL; } /* if(tree->n_root) */ /* { */ /* tree->n_root->v[1] = tree->e_root->left; */ /* tree->n_root->v[2] = tree->e_root->rght; */ /* tree->n_root->b[1]->rght = tree->e_root->left; */ /* tree->n_root->b[2]->rght = tree->e_root->rght; */ /* } */ #ifdef DEBUG if(b1->left->tax == YES && b1->rght->tax == NO) { PhyML_Printf("\n== b1->left->num = %d",b1->left->num); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } #endif if(tree->is_mixt_tree == YES) MIXT_Prune_Subtree(a,d,target,residual,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Graft_Subtree(t_edge *target, t_node *link, t_edge *residual, t_tree *tree) { t_node *v1, *v2; int i, dir_v1, dir_v2; phydbl *buff_p_lk; int *buff_scale; int *buff_p_pars, *buff_pars, *buff_p_lk_loc, *buff_patt_id; short int *buff_p_lk_tip; unsigned int *buff_ui; t_edge *b_up; dir_v1 = dir_v2 = -1; b_up = NULL; For(i,3) { if(!link->v[i]) { if(dir_v1 < 0) dir_v1 = i; else dir_v2 = i; } else b_up = link->b[i]; } #ifdef BEAGLE int temp; #endif if(target->left->num < target->rght->num) { v1 = target->left; v2 = target->rght; buff_p_lk = residual->p_lk_rght; residual->p_lk_rght = target->p_lk_rght; target->p_lk_rght = buff_p_lk; buff_p_lk_tip = residual->p_lk_tip_r; residual->p_lk_tip_r = target->p_lk_tip_r; target->p_lk_tip_r = buff_p_lk_tip; #ifdef BEAGLE temp = residual->p_lk_rght_idx; residual->p_lk_rght_idx = target->p_lk_rght_idx; target->p_lk_rght_idx = temp; temp = residual->p_lk_tip_idx; residual->p_lk_tip_idx = target->p_lk_tip_idx; target->p_lk_tip_idx = temp; #endif buff_scale = residual->sum_scale_rght; residual->sum_scale_rght = target->sum_scale_rght; target->sum_scale_rght = buff_scale; buff_pars = residual->pars_r; residual->pars_r = target->pars_r; target->pars_r = buff_pars; buff_ui = residual->ui_r; residual->ui_r = target->ui_r; target->ui_r = buff_ui; buff_p_pars = residual->p_pars_r; residual->p_pars_r = target->p_pars_r; target->p_pars_r = buff_p_pars; buff_p_lk_loc = residual->p_lk_loc_rght; residual->p_lk_loc_rght = target->p_lk_loc_rght; target->p_lk_loc_rght = buff_p_lk_loc; buff_patt_id = residual->patt_id_rght; residual->patt_id_rght = target->patt_id_rght; target->patt_id_rght = buff_patt_id; } else { v1 = target->rght; v2 = target->left; buff_p_lk = residual->p_lk_rght; residual->p_lk_rght = target->p_lk_left; target->p_lk_left = buff_p_lk; buff_p_lk_tip = residual->p_lk_tip_r; residual->p_lk_tip_r = target->p_lk_tip_l; target->p_lk_tip_l = buff_p_lk_tip; #ifdef BEAGLE temp = residual->p_lk_rght_idx; residual->p_lk_rght_idx = target->p_lk_left_idx; target->p_lk_left_idx = temp; #endif buff_scale = residual->sum_scale_rght; residual->sum_scale_rght = target->sum_scale_left; target->sum_scale_left = buff_scale; buff_scale = residual->sum_scale_rght_cat; residual->sum_scale_rght_cat = target->sum_scale_left_cat; target->sum_scale_left_cat = buff_scale; buff_pars = residual->pars_r; residual->pars_r = target->pars_l; target->pars_l = buff_pars; buff_ui = residual->ui_r; residual->ui_r = target->ui_l; target->ui_l = buff_ui; buff_p_pars = residual->p_pars_r; residual->p_pars_r = target->p_pars_l; target->p_pars_l = buff_p_pars; buff_p_lk_loc = residual->p_lk_loc_rght; residual->p_lk_loc_rght = target->p_lk_loc_left; target->p_lk_loc_left = buff_p_lk_loc; buff_patt_id = residual->patt_id_rght; residual->patt_id_rght = target->patt_id_left; target->patt_id_left = buff_patt_id; } For(i,3) if(v2->b[i] == target) { v2->v[i] = link; v2->b[i] = residual; break; } link->v[dir_v2] = v2; link->b[dir_v2] = residual; residual->left = link; residual->rght = v2; if(v1 == target->left) target->rght = link; else target->left = link; link->v[dir_v1] = v1; link->b[dir_v1] = target; For(i,3) if(v1->v[i] == v2) { v1->v[i] = link; break; } if(target->l->onoff == ON) target->l->v /= 2.; if(residual->l->onoff == ON) residual->l->v = target->l->v; Set_Edge_Dirs(target,target->left,target->rght,tree); Set_Edge_Dirs(residual,residual->left,residual->rght,tree); Set_Edge_Dirs(b_up,b_up->left,b_up->rght,tree); /* if(tree->n_root) */ /* { */ /* tree->n_root->v[1] = tree->e_root->left; */ /* tree->n_root->v[2] = tree->e_root->rght; */ /* tree->n_root->b[1]->rght = tree->e_root->left; */ /* tree->n_root->b[2]->rght = tree->e_root->rght; */ /* } */ if(tree->is_mixt_tree == YES) MIXT_Graft_Subtree(target,link,residual,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Reassign_Node_Nums(t_node *a, t_node *d, int *curr_ext_node, int *curr_int_node, t_tree *tree) { t_node *buff; int i; if(a->tax) { buff = tree->a_nodes[*curr_ext_node]; tree->a_nodes[*curr_ext_node] = a; tree->a_nodes[a->num] = buff; buff->num = a->num; a->num = *curr_ext_node; (*curr_ext_node)++; } if(d->tax) { buff = tree->a_nodes[*curr_ext_node]; tree->a_nodes[*curr_ext_node] = d; tree->a_nodes[d->num] = buff; buff->num = d->num; d->num = *curr_ext_node; (*curr_ext_node)++; return; } else { buff = tree->a_nodes[*curr_int_node]; tree->a_nodes[*curr_int_node] = d; tree->a_nodes[d->num] = buff; buff->num = d->num; d->num = *curr_int_node; (*curr_int_node)++; } For(i,3) { if(d->v[i] != a) Reassign_Node_Nums(d,d->v[i],curr_ext_node,curr_int_node,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Reassign_Edge_Nums(t_node *a, t_node *d, int *curr_br, t_tree *tree) { t_edge *buff; int i,j; For(i,3) if(a->v[i] == d) { buff = tree->a_edges[*curr_br]; For(j,2*N_MAX_OTU-3) if(tree->a_edges[j] == a->b[i]) break; if(j == 2*N_MAX_OTU-3) { PhyML_Printf("\n. Err. in file %s at line %d (function '%s').\n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } tree->a_edges[*curr_br] = a->b[i]; tree->a_edges[j] = buff; a->b[i]->num = *curr_br; (*curr_br)++; break; } if(d->tax) return; else { For(i,3) if(d->v[i] != a) Reassign_Edge_Nums(d,d->v[i],curr_br,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Mutual_Direction(t_node *n1, t_node *n2, short int *dir_n1_to_n2, short int *dir_n2_to_n1) { int scores[3][3]; int i,j,k,l; if(n1 == n2) return; For(i,3) { For(j,3) { scores[i][j] = 0; For(k,n1->bip_size[i]) { For(l,n2->bip_size[j]) { if(n1->bip_node[i][k] == n2->bip_node[j][l]) { scores[i][j]++; break; } } } } } For(i,3) { For(j,3) { if(!scores[i][j]) { *dir_n1_to_n2 = i; *dir_n2_to_n1 = j; return; } } } PhyML_Printf("\n. n1=%d n2=%d",n1->num,n2->num); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); /* For(i,3) */ /* { */ /* n_zero_line = 0; */ /* For(j,3) */ /* { */ /* if(!scores[i][j]) n_zero_line++; */ /* } */ /* if(n_zero_line != 2) {*dir_n1_to_n2 = i; break;} */ /* } */ /* For(i,3) */ /* { */ /* n_zero_col = 0; */ /* For(j,3) */ /* { */ /* if(!scores[j][i]) n_zero_col++; */ /* } */ /* if(n_zero_col != 2) {*dir_n2_to_n1 = i; break;} */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Dir_To_Tips(t_node *a, t_node *d, t_tree *tree) { int i,j,k; short int *inout; int d_a; int dim; dim = 2*tree->n_otu-2; inout = (short int *)mCalloc(tree->n_otu,sizeof(short int)); For(i,3) { if(a->v[i] == d) { For(j,tree->n_otu) inout[j] = 1; For(k,a->bip_size[i]) inout[a->bip_node[i][k]->num] = 0; For(j,tree->n_otu) if(inout[tree->a_nodes[j]->num]) tree->t_dir[a->num*dim+tree->a_nodes[j]->num] = i; break; } } if(!d->tax) { d_a = -1; For(i,3) { if(d->v[i] != a) Update_Dir_To_Tips(d,d->v[i],tree); else if(d->v[i] == a) d_a = i; } For(j,tree->n_otu) inout[j] = 1; For(k,d->bip_size[d_a]) inout[d->bip_node[d_a][k]->num] = 0; For(j,tree->n_otu) if(inout[tree->a_nodes[j]->num]) tree->t_dir[d->num*dim+tree->a_nodes[j]->num] = d_a; } Free(inout); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Fill_Dir_Table(t_tree *tree) { int i,j; int dim; dim = 2*tree->n_otu-2; For(i,dim*dim) tree->t_dir[i] = 0; Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); Update_Dir_To_Tips(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); for(i=tree->n_otu;i<2*tree->n_otu-2;i++) for(j=i;j<2*tree->n_otu-2;j++) { Find_Mutual_Direction(tree->a_nodes[i],tree->a_nodes[j], &(tree->t_dir[i*dim+j]), &(tree->t_dir[j*dim+i])); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_Subtree_Size(t_node *a, t_node *d) { int size,i; if(d->tax) return 1; else { size = 0; For(i,3) if(d->v[i] != a) size += Get_Subtree_Size(d,d->v[i]); } return size; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Fast_Br_Len(t_edge *b, t_tree *tree, int approx) { /* phydbl sum; */ /* phydbl *prob, *F; */ /* int i, j, k, site; */ /* phydbl *v_rght; */ /* int dim1,dim2,dim3; */ /* int n_iter; */ /* phydbl scale_rght; */ if(tree->is_mixt_tree) { if(approx == NO) MIXT_Br_Len_Brent(0.001,100.,b,tree); else { tree->mod->s_opt->brent_it_max = 10; MIXT_Br_Len_Brent(0.0001,1000.,b,tree); tree->mod->s_opt->brent_it_max = BRENT_IT_MAX; } return; } /* n_iter = 0; */ /* dim1 = tree->mod->ns * tree->mod->ras->n_catg; */ /* dim2 = tree->mod->ns ; */ /* dim3 = tree->mod->ns * tree->mod->ns; */ /* F = tree->triplet_struct->F_bc; */ /* prob = tree->triplet_struct->F_cd; */ /* Update_PMat_At_Given_Edge(b,tree); */ /* For(i,dim1*dim2) F[i] = .0; */ /* v_rght = (phydbl *)mCalloc(tree->mod->ns,sizeof(phydbl)); */ /* For(site,tree->n_pattern) */ /* { */ /* /\* Joint probabilities of the states at the two ends of the t_edge *\/ */ /* For(k,tree->mod->ras->n_catg) */ /* { */ /* if(b->rght->tax == YES) */ /* For(i,tree->mod->ns) v_rght[i] = (phydbl)(b->p_lk_tip_r[site*dim2+i]); */ /* else */ /* For(i,tree->mod->ns) v_rght[i] = (phydbl)(b->p_lk_rght[site*dim1+k*dim2+i]); */ /* scale_rght = (b->rght->tax)?(0.0):(b->sum_scale_rght[k*tree->n_pattern+site]); */ /* Joint_Proba_States_Left_Right(b->Pij_rr + k*dim3, */ /* b->p_lk_left + site*dim1+k*dim2, */ /* v_rght, */ /* tree->mod->e_frq->pi, */ /* b->sum_scale_left[k*tree->n_pattern+site], */ /* scale_rght, */ /* prob + dim3*k, */ /* tree->mod->ns,site,tree); */ /* /\* Scaling *\/ */ /* sum = .0; */ /* For(i,tree->mod->ns) For(j,tree->mod->ns) sum += prob[dim3*k+dim2*i+j]; */ /* For(i,tree->mod->ns) For(j,tree->mod->ns) prob[dim3*k+dim2*i+j] /= sum; */ /* For(i,tree->mod->ns) For(j,tree->mod->ns) prob[dim3*k+dim2*i+j] *= tree->mod->ras->gamma_r_proba->v[k]; */ /* } */ /* /\* Expected number of each pair of states *\/ */ /* For(i,tree->mod->ns) For(j,tree->mod->ns) For(k,tree->mod->ras->n_catg) */ /* F[dim3*k+dim2*i+j] += tree->data->wght[site] * prob[dim3*k+dim2*i+j]; */ /* } */ /* Free(v_rght); */ /* Opt_Dist_F(&(b->l->v),F,tree->mod); */ /* n_iter++; */ if(approx == NO) Br_Len_Brent(0.001,100.,b,tree); else { tree->mod->s_opt->brent_it_max = 10; Br_Len_Brent(0.001,1000.,b,tree); tree->mod->s_opt->brent_it_max = BRENT_IT_MAX; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Calculate the joint probability of states (nt or aa) at the two extremities of a given edge given the matrix of transition probabilities, the vector of conditional likelihoods on each side of the branch and the vector of equilibrium frequencies. */ void Joint_Proba_States_Left_Right(phydbl *Pij, phydbl *p_lk_left, phydbl *p_lk_rght, vect_dbl *pi, int scale_left, int scale_rght, phydbl *F, int n, int site, t_tree *tree) { int i,j; phydbl sum = 0.0; For(i,n) F[i] = .0; For(i,n) { For(j,n) { F[i*n+j] = pi->v[i] * Pij[i*n+j] * p_lk_left[i] * p_lk_rght[j] * POW(2.,-(scale_left + scale_rght)); sum += F[i*n+j]; } } For(i,n*n) { F[i] /= sum; if(isnan(F[i]) || isinf(F[i])) { For(i,n) For(j,n) PhyML_Printf("\n== %15G %15G %15G %15G %15G", pi->v[i] , Pij[i*n+j] , p_lk_left[i] , p_lk_rght[j] , POW(2.,-(scale_left + scale_rght))); PhyML_Printf("\n== sum = %G",sum); Print_Site(tree->data,site,tree->n_otu,"\n",1,stderr); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Triple_Dist(t_node *a, t_tree *tree, int approx) { if(a->tax) return UNLIKELY; else { Update_PMat_At_Given_Edge(a->b[1],tree); Update_PMat_At_Given_Edge(a->b[2],tree); Update_P_Lk(tree,a->b[0],a); Fast_Br_Len(a->b[0],tree,approx); Update_P_Lk(tree,a->b[1],a); Fast_Br_Len(a->b[1],tree,approx); Update_P_Lk(tree,a->b[2],a); Fast_Br_Len(a->b[2],tree,approx); Update_P_Lk(tree,a->b[1],a); Update_P_Lk(tree,a->b[0],a); } return tree->c_lnL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_Symmetric(phydbl **F, int size) { int i,j; For(i,size) { for(j=i+1;jmod->ns) { For(j,tree->mod->ns) { (*F)[tree->mod->ns*i+j] = RINT((*F)[tree->mod->ns*i+j]); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Get_Sum_Of_Cells(phydbl *F, t_tree *tree) { int i,j; phydbl sum = .0; For(i,tree->mod->ns) For(j,tree->mod->ns) sum += F[tree->mod->ns*i+j]; return sum; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Divide_Cells(phydbl **F, phydbl div, t_tree *tree) { int i,j; For(i,tree->mod->ns) For(j,tree->mod->ns) (*F)[tree->mod->ns*i+j] /= div; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Divide_Mat_By_Vect(phydbl **F, phydbl *vect, int size) { int i,j; For(i,size) For(j,size) (*F)[size*i+j] = (*F)[size*i+j] / vect[j]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Multiply_Mat_By_Vect(phydbl **F, phydbl *vect, int size) { int i,j; For(i,size) For(j,size) (*F)[size*i+j] = (*F)[size*i+j] * vect[j]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Found_In_Subtree(t_node *a, t_node *d, t_node *target, int *match, t_tree *tree) { if(d->tax) return; else { int i; if(d == target) *match = 1; For(i,3) { if(d->v[i] != a) Found_In_Subtree(d,d->v[i],target,match,tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_List_Of_Target_Edges(t_node *a, t_node *d, t_edge **list, int *list_size, t_tree *tree) { int i; For(i,3) { if(a->v[i] && a->v[i] == d) { list[*list_size] = a->b[i]; (*list_size)++; } } if(d->tax) return; else { For(i,3) { if(d->v[i] != a) Get_List_Of_Target_Edges(d,d->v[i],list,list_size,tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Fix_All(t_tree *tree) { int i; for(i=tree->n_otu;i<2*tree->n_otu-2;i++) { tree->a_nodes[i]->b[0]->l_old->v = tree->a_nodes[i]->b[0]->l->v; tree->a_nodes[i]->b[1]->l_old->v = tree->a_nodes[i]->b[1]->l->v; tree->a_nodes[i]->b[2]->l_old->v = tree->a_nodes[i]->b[2]->l->v; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Record_Br_Len(t_tree *mixt_tree) { int i; t_tree *tree; if(mixt_tree->br_len_recorded == YES) { PhyML_Printf("\n== Overwriting recorded edge lengths.\n"); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } tree = mixt_tree; do { For(i,2*tree->n_otu-1) tree->a_edges[i]->l_old->v = tree->a_edges[i]->l->v; For(i,2*tree->n_otu-1) tree->a_edges[i]->l_var_old->v = tree->a_edges[i]->l_var->v; tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Restore_Br_Len(t_tree *mixt_tree) { int i; t_tree *tree; mixt_tree->br_len_recorded = NO; tree = mixt_tree; do { For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v = tree->a_edges[i]->l_old->v; For(i,2*tree->n_otu-1) tree->a_edges[i]->l_var->v = tree->a_edges[i]->l_var_old->v; tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Dist_Btw_Edges(t_node *a, t_node *d, t_tree *tree) { int i; t_edge *b_fcus; b_fcus = NULL; For(i,3) if(a->v[i] == d) {b_fcus = a->b[i]; break;} if(d->tax) return; else { For(i,3) if(d->v[i] != a) { d->b[i]->topo_dist_btw_edges = b_fcus->topo_dist_btw_edges + 1; d->b[i]->dist_btw_edges = b_fcus->dist_btw_edges + d->b[i]->l->v / 2.; Get_Dist_Btw_Edges(d,d->v[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Detect_Polytomies(t_edge *b, phydbl l_thresh, t_tree *tree) { if((b->l->v < l_thresh) && (!b->left->tax) && (!b->rght->tax)) { b->l->v = 0.0; b->has_zero_br_len = YES; } else b->has_zero_br_len = NO; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_List_Of_Nodes_In_Polytomy(t_node *a, t_node *d, t_node ***list, int *size_list) { if(d->tax) return; else { int i; For(i,3) { if(d->v[i] != a) { if(!d->b[i]->has_zero_br_len) { (*list)[*size_list] = d->v[i]; (*size_list)++; } if(d->b[i]->has_zero_br_len) Get_List_Of_Nodes_In_Polytomy(d,d->v[i],list,size_list); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Path_Length(t_node *dep, t_node *arr, phydbl *len, t_tree *tree) { if(dep==arr) return; else { t_edge *next; next = dep->b[tree->t_dir[dep->num*(2*tree->n_otu-2)+arr->num]]; if(next == tree->e_root) { (*len) += (tree->n_root->l[1] + tree->n_root->l[2]); } else { (*len) += next->l->v; } Path_Length(dep->v[tree->t_dir[dep->num*(2*tree->n_otu-2)+arr->num]],arr,len,tree); return; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Path(t_node *a, t_node *d, t_node *target, t_tree *tree) { PhyML_Printf("path---------\n"); if(d==target) return; else Check_Path(d,d->v[tree->t_dir[d->num*(2*tree->n_otu-2)+target->num]],target,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Connect_Two_Nodes(t_node *a, t_node *d) { a->v[0] = d; d->v[0] = a; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_List_Of_Adjacent_Targets(t_node *a, t_node *d, t_node ***node_list, t_edge ***edge_list, int *list_size) { int i; For(i,3) if(a->v[i] == d) { (*node_list)[*list_size] = a; (*edge_list)[*list_size] = a->b[i]; (*list_size)++; } if(d->tax) return; else For(i,3) if(d->v[i] != a) Get_List_Of_Adjacent_Targets(d,d->v[i],node_list,edge_list,list_size); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Sort_List_Of_Adjacent_Targets(t_edge ***list, int list_size) { t_edge *buff_edge; int i,j; buff_edge = NULL; For(i,list_size-1) { for(j=i+1;jtopo_dist_btw_edges < (*list)[i]->topo_dist_btw_edges) { buff_edge = (*list)[j]; (*list)[j] = (*list)[i]; (*list)[i] = buff_edge; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_node *Common_Nodes_Btw_Two_Edges(t_edge *a, t_edge *b) { if(a->left == b->left) return b->left; else if(a->left == b->rght) return b->rght; else if(a->rght == b->left) return b->left; else if(a->rght == b->rght) return b->rght; PhyML_Printf("\n. First t_edge = %d (%d %d); Second t_edge = %d (%d %d)\n", a->num,a->left->num,a->rght->num, b->num,b->left->num,b->rght->num); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int KH_Test(phydbl *site_lk_M1, phydbl *site_lk_M2, t_tree *tree) { phydbl *delta,mean,sd,obs_stat,threshold; int i; delta = (phydbl *)mCalloc(tree->data->init_len,sizeof(phydbl)); threshold = .0; mean = .0; obs_stat = .0; For(i,tree->n_pattern) { delta[i] = site_lk_M1[i] - site_lk_M2[i]; mean += ((int)tree->data->wght[i])*delta[i]; } obs_stat = mean; mean /= tree->data->init_len; For(i,tree->data->init_len) delta[i] -= mean; sd = .0; For(i,tree->data->init_len) sd += POW(delta[i],2); sd /= (phydbl)(tree->data->init_len-1.); /* threshold = tree->dnorm_thresh*SQRT(sd*tree->data->init_len); */ /* PhyML_Printf("\nObs stat = %f Threshold = %f\n",obs_stat,threshold); */ Free(delta); if(obs_stat > threshold) return 1; else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Random_Tree(t_tree *tree) { int *is_available,*list_of_nodes; int i,node_num,step,n_available; phydbl min_edge_len; min_edge_len = 1.E-3; if(tree->mod->s_opt && tree->mod->s_opt->print == YES) PhyML_Printf("\n\n. Randomising the tree...\n"); is_available = (int *)mCalloc(2*tree->n_otu-2,sizeof(int)); list_of_nodes = (int *)mCalloc(tree->n_otu, sizeof(int)); For(i,tree->n_otu) is_available[i] = 1; For(i,tree->n_otu) list_of_nodes[i] = i; step = 0; do { /* node_num = (int)RINT(rand()/(phydbl)(RAND_MAX+1.0)*(tree->n_otu-1-step)); */ node_num = Rand_Int(0,tree->n_otu-1-step); node_num = list_of_nodes[node_num]; is_available[node_num] = 0; For(i,tree->n_otu) list_of_nodes[i] = -1; n_available = 0; For(i,2*tree->n_otu-2) if(is_available[i]) {list_of_nodes[n_available++] = i;} tree->a_nodes[node_num]->v[0] = tree->a_nodes[tree->n_otu+step]; tree->a_nodes[tree->n_otu+step]->v[1] = tree->a_nodes[node_num]; /* node_num = (int)RINT(rand()/(phydbl)(RAND_MAX+1.0)*(tree->n_otu-2-step)); */ node_num = Rand_Int(0,tree->n_otu-2-step); node_num = list_of_nodes[node_num]; is_available[node_num] = 0; For(i,tree->n_otu) list_of_nodes[i] = -1; n_available = 0; For(i,2*tree->n_otu-2) if(is_available[i]) {list_of_nodes[n_available++] = i;} tree->a_nodes[node_num]->v[0] = tree->a_nodes[tree->n_otu+step]; tree->a_nodes[tree->n_otu+step]->v[2] = tree->a_nodes[node_num]; is_available[tree->n_otu+step] = 1; For(i,tree->n_otu) list_of_nodes[i] = -1; n_available = 0; For(i,2*tree->n_otu-2) if(is_available[i]) list_of_nodes[n_available++] = i; step++; }while(step < tree->n_otu-2); tree->a_nodes[list_of_nodes[0]]->v[0] = tree->a_nodes[list_of_nodes[1]]; tree->a_nodes[list_of_nodes[1]]->v[0] = tree->a_nodes[list_of_nodes[0]]; tree->num_curr_branch_available = 0; Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); For(i,2*tree->n_otu-3) if(tree->a_edges[i]->l->v < min_edge_len) tree->a_edges[i]->l->v = min_edge_len; Fill_Dir_Table(tree); Update_Dirs(tree); Free(is_available); Free(list_of_nodes); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Make sure internal edges have likelihood vectors on both // sides and external edges have one likelihood vector on the // lefthand side only void Reorganize_Edges_Given_Lk_Struct(t_tree *tree) { int j,i; For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->p_lk_left && tree->a_edges[i]->left->tax == YES) { For(j,2*tree->n_otu-3) { if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO) { Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],NO,tree); break; } if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO) { Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],YES,tree); break; } } } if(tree->a_edges[i]->p_lk_rght && tree->a_edges[i]->rght->tax == YES) { For(j,2*tree->n_otu-3) { if(!tree->a_edges[j]->p_lk_left && tree->a_edges[j]->left->tax == NO) { Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],YES,tree); break; } if(!tree->a_edges[j]->p_lk_rght && tree->a_edges[j]->rght->tax == NO) { Swap_Nodes_On_Edges(tree->a_edges[i],tree->a_edges[j],NO,tree); break; } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Random_NNI(int n_moves, t_tree *tree) { int i,j; t_edge *b; t_node *n1,*n2,*n_target; n1 = n2 = NULL; b = NULL; For(i,n_moves) { n_target = tree->a_nodes[tree->n_otu + (int)((phydbl)rand()/RAND_MAX * (2*tree->n_otu-3-tree->n_otu))]; For(j,3) if(!n_target->v[j]->tax) {b = n_target->b[j]; break;} For(j,3) if(b->left->v[j] != b->rght) {n1 = b->left->v[j]; break;} For(j,3) if(b->rght->v[j] != b->left) {n2 = b->rght->v[j]; break;} Swap(n1,b->left,b->rght,n2,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Fill_Missing_Dist(matrix *mat) { int i,j; For(i,mat->n_otu) { for(j=i+1;jn_otu;j++) { if(i != j) { if(mat->dist[i][j] < .0) { Fill_Missing_Dist_XY(i,j,mat); mat->dist[j][i] = mat->dist[i][j]; } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Fill_Missing_Dist_XY(int x, int y, matrix *mat) { int i,j; phydbl *local_mins,**S1S2; int cpt; int pos_best_estimate; phydbl min_crit, curr_crit; local_mins = (phydbl *)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl )); S1S2 = (phydbl **)mCalloc(mat->n_otu*mat->n_otu,sizeof(phydbl *)); For(i,mat->n_otu*mat->n_otu) S1S2[i] = (phydbl *)mCalloc(2,sizeof(phydbl)); cpt = 0; For(i,mat->n_otu) { if((mat->dist[i][x] > .0) && (mat->dist[i][y] > .0)) { For(j,mat->n_otu) { if((mat->dist[j][x] > .0) && (mat->dist[j][y] > .0)) { if((i != j) && (i != x) && (i != y) && (j != x) && (j != y)) { S1S2[cpt][0] = MIN(mat->dist[i][x] + mat->dist[j][y] - mat->dist[i][j] , mat->dist[i][y] + mat->dist[j][x] - mat->dist[i][j]); S1S2[cpt][1] = MAX(mat->dist[i][x] + mat->dist[j][y] - mat->dist[i][j] , mat->dist[i][y] + mat->dist[j][x] - mat->dist[i][j]); cpt++; } } } } } Qksort_Matrix(S1S2,0,0,cpt-1); local_mins[0] = S1S2[0][1]; for(i=1;i S1S2[i][0])) { curr_crit = Least_Square_Missing_Dist_XY(x,y,local_mins[i],mat); if(curr_crit < min_crit) { min_crit = curr_crit; pos_best_estimate = i; } } } mat->dist[x][y] = local_mins[pos_best_estimate]; mat->dist[y][x] = mat->dist[x][y]; For(i,mat->n_otu*mat->n_otu) Free(S1S2[i]); Free(S1S2); Free(local_mins); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Least_Square_Missing_Dist_XY(int x, int y, phydbl dxy, matrix *mat) { int i,j; phydbl fit; fit = .0; For(i,mat->n_otu) { if((mat->dist[i][x] > .0) && (mat->dist[i][y] > .0)) { For(j,mat->n_otu) { if((mat->dist[j][x] > .0) && (mat->dist[j][y] > .0)) { if((i != j) && (i != x) && (i != y) && (j != x) && (j != y)) { if(dxy < MIN(mat->dist[i][x] + mat->dist[j][y] - mat->dist[i][j] , mat->dist[i][y] + mat->dist[j][x] - mat->dist[i][j])) { fit += POW((mat->dist[i][x] + mat->dist[j][y]) - (mat->dist[i][y] + mat->dist[j][x]),2); } else if((mat->dist[i][x] + mat->dist[j][y]) < (mat->dist[i][y] + mat->dist[j][x])) { fit += POW(dxy - (mat->dist[i][y] + mat->dist[j][x] - mat->dist[i][j]),2); } else { fit += POW(dxy - (mat->dist[i][x] + mat->dist[j][y] - mat->dist[i][j]),2); } } } } } } return fit; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Memory_Amount(t_tree *tree) { /* Rough estimate of the amount of memory that has to be used */ long int nbytes; int n_otu; t_mod *mod; mod = tree->mod; n_otu = tree->io->n_otu; nbytes = 0; /* Partial Pars */ nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * sizeof(int); nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * sizeof(unsigned int); nbytes += (2*n_otu-3) * 2 * tree->data->crunch_len * mod->ns * sizeof(int); /* Pmat */ nbytes += (2*n_otu-3) * mod->ras->n_catg * mod->ns * mod->ns * sizeof(phydbl); /* Partial Lk */ nbytes += ((2*n_otu-3) * 2 - tree->n_otu) * tree->data->crunch_len * mod->ras->n_catg * mod->ns * sizeof(phydbl); /* Scaling factors */ nbytes += ((2*n_otu-3) * 2 - tree->n_otu) * tree->data->crunch_len * sizeof(int); if(((phydbl)nbytes/(1.E+06)) > 256.) /* if(((phydbl)nbytes/(1.E+06)) > 0.) */ { PhyML_Printf("\n\n. WARNING: this analysis requires at least %.0f MB of memory space.\n",(phydbl)nbytes/(1.E+06)); #ifndef BATCH char answer; if((!tree->io->quiet) && (tree->io->mem_question == YES)) { PhyML_Printf("\n. Do you really want to proceed? [Y/n] "); if(scanf("%c", &answer)) { if(answer == '\n') answer = 'Y'; else if(answer == 'n' || answer == 'N') Warn_And_Exit("\n"); else getchar(); } else { Warn_And_Exit("\n\n"); } } #endif } else if(((phydbl)nbytes/(1.E+06)) > 100.) { if(!tree->io->quiet) PhyML_Printf("\n\n. WARNING: this analysis will use at least %.0f Mo of memory space...\n",(phydbl)nbytes/(1.E+06)); } else if(((phydbl)nbytes/(1.E+06)) > 1.) { if(!tree->io->quiet) PhyML_Printf("\n\n. This analysis requires at least %.0f Mo of memory space.\n",(phydbl)nbytes/(1.E+06)); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_State_From_P_Lk(phydbl *p_lk, int pos, t_tree *tree) { int i; For(i,tree->mod->ns) if(p_lk[pos+i] > .0) return i; return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_State_From_P_Pars(short int *p_pars, int pos, t_tree *tree) { int i; For(i,tree->mod->ns) if(p_pars[pos+i] > .0) return i; return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Dirs(t_tree *tree) { int i; For(i,2*tree->n_otu-3) { if(!tree->a_edges[i]->left->tax) { if(tree->a_edges[i]->left->v[tree->a_edges[i]->l_v1]->num < tree->a_edges[i]->left->v[tree->a_edges[i]->l_v2]->num) { PhyML_Printf("\n. Edge %d ; v1=%d v2=%d", tree->a_edges[i]->num, tree->a_edges[i]->left->v[tree->a_edges[i]->l_v1]->num, tree->a_edges[i]->left->v[tree->a_edges[i]->l_v2]->num); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } if(!tree->a_edges[i]->rght->tax) { if(tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v1]->num < tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v2]->num) { PhyML_Printf("\n. Edge %d ; v3=%d v4=%d", tree->a_edges[i]->num, tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v1]->num, tree->a_edges[i]->rght->v[tree->a_edges[i]->r_v2]->num); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Warn_And_Exit(const char *s) { PhyML_Fprintf(stdout,"%s",s); fflush(NULL); #ifndef BATCH /* if (! tree->io->quiet) { */ /* char c; */ PhyML_Fprintf(stdout,"\n. Type enter to exit.\n"); /* if(!fscanf(stdin,"%c",&c)) */ Exit(""); /* } */ #endif Exit("\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Randomize_Sequence_Order(calign *cdata) { int i,exchange_with; phydbl buff_dbl; char *buff_name,*buff_state; short int *buff_ambigu; exchange_with = -1; For(i,cdata->n_otu) { buff_dbl = rand(); buff_dbl /= (RAND_MAX+1.); buff_dbl *= cdata->n_otu; exchange_with = (int)FLOOR(buff_dbl); buff_name = cdata->c_seq[i]->name; cdata->c_seq[i]->name = cdata->c_seq[exchange_with]->name; cdata->c_seq[exchange_with]->name = buff_name; buff_state = cdata->c_seq[i]->state; cdata->c_seq[i]->state = cdata->c_seq[exchange_with]->state; cdata->c_seq[exchange_with]->state = buff_state; buff_ambigu = cdata->c_seq[i]->is_ambigu; cdata->c_seq[i]->is_ambigu = cdata->c_seq[exchange_with]->is_ambigu; cdata->c_seq[exchange_with]->is_ambigu = buff_ambigu; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Root_Pos(t_tree *tree) { if(tree->n_root_pos > -1.0) { tree->n_root->l[2] = tree->e_root->l->v * tree->n_root_pos; tree->n_root->l[1] = tree->e_root->l->v * (1.-tree->n_root_pos); } else { /* tree->n_root->l[0] = tree->e_root->l->v / 2.; */ /* tree->n_root->l[1] = tree->e_root->l->v / 2.; */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Add_Root(t_edge *target, t_tree *tree) { t_edge *b1, *b2; #ifndef PHYML PhyML_Printf("\n. Adding root on t_edge %d left = %d right = %d\n.",target->num,target->left->num,target->rght->num); fflush(NULL); #endif tree->e_root = target; /* Create the root t_node if it does not exist yet */ if(!tree->a_nodes[2*tree->n_otu-2]) { tree->n_root = (t_node *)Make_Node_Light(2*tree->n_otu-2); } else { tree->n_root = tree->a_nodes[2*tree->n_otu-2]; } tree->a_nodes[2*tree->n_otu-2] = tree->n_root; tree->n_root->tax = 0; /* Set the position of the root */ tree->n_root->v[0] = NULL; tree->n_root->v[1] = tree->e_root->left; tree->n_root->v[2] = tree->e_root->rght; /* tree->n_root->b[2] = tree->e_root; */ /* tree->n_root->b[1] = tree->e_root; */ if(tree->n_root_pos > -1.0) { if(tree->n_root_pos < 1.E-6 && tree->n_root_pos > -1.E-6) printf("\n. WARNING: you put the root at a weird position..."); /* tree->n_root->l[0] = tree->e_root->l->v * (tree->n_root_pos/(1.+tree->n_root_pos)); */ /* tree->n_root->l[1] = tree->e_root->l->v - tree->n_root->l[0]; */ tree->n_root->l[2] = tree->e_root->l->v * tree->n_root_pos; tree->n_root->l[1] = tree->e_root->l->v * (1. - tree->n_root_pos); } else { tree->n_root->l[2] = tree->e_root->l->v / 2.; tree->n_root->l[1] = tree->e_root->l->v / 2.; tree->n_root_pos = 0.5; } b1 = tree->a_edges[2*tree->n_otu-3]; b2 = tree->a_edges[2*tree->n_otu-2]; tree->n_root->b[0] = NULL; tree->n_root->b[1] = b1; tree->n_root->b[2] = b2; b1->num = tree->num_curr_branch_available; b2->num = tree->num_curr_branch_available+1; b1->left = tree->n_root; b1->rght = tree->n_root->v[1]; b2->left = tree->n_root; b2->rght = tree->n_root->v[2]; b1->l->v = tree->n_root->l[1]; b2->l->v = tree->n_root->l[2]; b1->l_old->v = tree->n_root->l[1]; b2->l_old->v = tree->n_root->l[2]; b1->l_r = 1; b2->l_r = 2; b1->r_l = 0; b2->r_l = 0; b1->l_v1 = 0; b1->l_v2 = 2; b2->l_v1 = 0; b2->l_v2 = 1; b1->r_v1 = 1; b1->r_v2 = 2; b2->r_v1 = 1; b2->r_v2 = 2; /* WARNING: make sure you have freed the memory for p_lk_rght on b1 and b2 */ b1->p_lk_rght = tree->e_root->p_lk_left; b2->p_lk_rght = tree->e_root->p_lk_rght; b1->p_lk_tip_r = tree->e_root->p_lk_tip_l; b2->p_lk_tip_r = tree->e_root->p_lk_tip_r; b1->sum_scale_rght = tree->e_root->sum_scale_left; b2->sum_scale_rght = tree->e_root->sum_scale_rght; b1->sum_scale_rght_cat = tree->e_root->sum_scale_left_cat; b2->sum_scale_rght_cat = tree->e_root->sum_scale_rght_cat; b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left; b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght; b1->pars_r = tree->e_root->pars_l; b2->pars_r = tree->e_root->pars_r; b1->ui_r = tree->e_root->ui_l; b2->ui_r = tree->e_root->ui_r; b1->p_pars_r = tree->e_root->p_pars_l; b2->p_pars_r = tree->e_root->p_pars_r; b1->p_lk_loc_rght = tree->e_root->p_lk_loc_left; b2->p_lk_loc_rght = tree->e_root->p_lk_loc_rght; b1->patt_id_rght = tree->e_root->patt_id_left; b2->patt_id_rght = tree->e_root->patt_id_rght; Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); tree->n_root->anc = NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Update_Ancestors(t_node *a, t_node *d, t_tree *tree) { if(a == tree->n_root) a->anc = NULL; d->anc = a; if(d->tax) return; else { int i; For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) Update_Ancestors(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Generate a random unrooted tree with 'n_otu' OTUs */ #if (defined PHYTIME || defined INVITEE) t_tree *Generate_Random_Tree_From_Scratch(int n_otu, int rooted) { t_tree *tree; int *connected,*nonconnected,*available_nodes; int i,n_connected,n_nonconnected,n1,n2,new_n,n_internal,n_external,n_available; t_node *root,*curr_n,**internal_nodes, **external_nodes; phydbl *t,*tmp; tree = Make_Tree_From_Scratch(n_otu,NULL); tree->rates = RATES_Make_Rate_Struct(tree->n_otu); RATES_Init_Rate_Struct(tree->rates,tree->io->rates,tree->n_otu); For(i,2*tree->n_otu-2) { tree->a_nodes[i]->v[1] = NULL; tree->a_nodes[i]->v[2] = NULL; } root = (t_node *)Make_Node_Light(2*tree->n_otu-2); connected = (int *)mCalloc(2*tree->n_otu-2,sizeof(int)); nonconnected = (int *)mCalloc(2*tree->n_otu-2,sizeof(int)); available_nodes = (int *)mCalloc(2*tree->n_otu-2,sizeof(int)); internal_nodes = (t_node **)mCalloc(tree->n_otu-2,sizeof(t_node *)); external_nodes = (t_node **)mCalloc(tree->n_otu, sizeof(t_node *)); t = (phydbl *)mCalloc(tree->n_otu-1,sizeof(phydbl )); tmp = (phydbl *)mCalloc(2*tree->n_otu-2,sizeof(phydbl )); n_nonconnected = 2*n_otu-2; For(i,2*tree->n_otu-2) nonconnected[i] = i; available_nodes[0] = 2*n_otu-2; /* Node times are generated according to a Birth-death process. Formulae are as described by Yang and Rannala (1997) */ phydbl phi; phydbl rho; /* sampling intensity */ phydbl mu; /* birth rate */ phydbl lambda; /* death rate */ phydbl u; /* random U[0,1] */ phydbl expval; /* rho = 1.0 and mu = 0.0 correspond to the Yule process */ lambda = 6.7; mu = 2.5; rho = 9./150.; expval = EXP(MIN(1.E+2,mu-lambda)); phi = (rho*lambda*(expval-1.) + (mu-lambda)*expval)/(expval-1.); /* Equation 16 */ For(i,tree->n_otu-1) { u = rand(); u /= RAND_MAX; if(FABS(lambda - mu) > 1.E-4) t[i] = (LOG(phi-u*rho*lambda) - LOG(phi-u*rho*lambda + u*(lambda-mu)))/(mu-lambda); /* Equation 15 */ else t[i] = u / (1.+lambda*rho*(1-u)); /* Equation 17 */ } Qksort(t,NULL,0,tree->n_otu-2); /* Node times ordering in ascending order */ For(i,tree->n_otu-1) tmp[i] = t[tree->n_otu-2-i]; For(i,tree->n_otu-1) t[i] = -tmp[i]; /* Rescale t_node times such that the time at the root t_node is -100 */ for(i=1;in_otu-1;i++) { t[i] /= -t[0]; t[i] *= 1.E+02; } t[0] = -1.E+02; n_available = 1; curr_n = root; n_connected = 0; do { n1 = Rand_Int(0,n_nonconnected-1); n1 = nonconnected[n1]; connected[n1] = 1; n_nonconnected = 0; For(i,2*tree->n_otu-2) if(!connected[i]) {nonconnected[n_nonconnected++] = i;} n2 = Rand_Int(0,n_nonconnected-1); n2 = nonconnected[n2]; connected[n2] = 1; n_nonconnected = 0; For(i,2*tree->n_otu-2) if(!connected[i]) {nonconnected[n_nonconnected++] = i;} curr_n->v[1] = tree->a_nodes[n1]; curr_n->v[2] = tree->a_nodes[n2]; tree->a_nodes[n1]->v[0] = curr_n; tree->a_nodes[n2]->v[0] = curr_n; tree->rates->nd_t[curr_n->num] = t[n_connected/2]; available_nodes[n_available] = tree->a_nodes[n1]->num; For(i,n_available) if(available_nodes[i] == curr_n->num) { available_nodes[i] = tree->a_nodes[n2]->num; break; } n_available++; new_n = Rand_Int(0,n_available-1); curr_n = tree->a_nodes[available_nodes[new_n]]; n_connected+=2; }while(n_connected < 2*tree->n_otu-2); For(i,2*tree->n_otu-2) tmp[i] = tree->rates->nd_t[i]; /* Unroot the tree */ root->v[2]->v[0] = root->v[2]; root->v[1]->v[0] = root->v[1]; n_internal = n_external = 0; For(i,2*tree->n_otu-2) { if(tree->a_nodes[i]->v[1]) internal_nodes[n_internal++] = tree->a_nodes[i]; else external_nodes[n_external++] = tree->a_nodes[i]; } n_internal = n_external = 0; For(i,2*tree->n_otu-2) { if(i < tree->n_otu) { tree->a_nodes[i] = external_nodes[n_external++]; tree->a_nodes[i]->tax = 1; } else { tree->rates->nd_t[i] = tmp[internal_nodes[n_internal]->num]; tree->a_nodes[i] = internal_nodes[n_internal++]; tree->a_nodes[i]->tax = 0; } tree->a_nodes[i]->num = i; } For(i,tree->n_otu) tree->rates->nd_t[i] = 0.0; For(i,tree->n_otu) { if(!tree->a_nodes[i]->name) tree->a_nodes[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); strcpy(tree->a_nodes[i]->name,"x"); sprintf(tree->a_nodes[i]->name+1,"%d",i); } tree->num_curr_branch_available = 0; Connect_Edges_To_Nodes_Recur(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); Fill_Dir_Table(tree); Update_Dirs(tree); /* Add root */ if(rooted) { For(i,2*tree->n_otu-3) { if(((tree->a_edges[i]->left == root->v[1]) || (tree->a_edges[i]->rght == root->v[1])) && ((tree->a_edges[i]->left == root->v[2]) || (tree->a_edges[i]->rght == root->v[2]))) { Add_Root(tree->a_edges[i],tree); break; } } } /* Or not... */ else { Free_Node(root); } RATES_Random_Branch_Lengths(tree); Free(available_nodes); Free(connected); Free(nonconnected); Free(external_nodes); Free(internal_nodes); Free(t); Free(tmp); return tree; } #endif ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Random_Lineage_Rates(t_node *a, t_node *d, t_edge *b, phydbl stick_prob, phydbl *rates, int curr_rate, int n_rates, t_tree *tree) { phydbl uni; int new_rate; int i; if(b) { uni = rand(); uni /= RAND_MAX; if(uni > stick_prob) /* Randomly pick a new rate */ { uni = rand(); uni /= RAND_MAX; uni = (phydbl)(uni * (n_rates-1)); if(uni-(int)(uni) > 0.5-BIG) new_rate = (int)(uni)+1; else new_rate = (int)(uni); } else { new_rate = curr_rate; } For(i,3) if(a->v[i] == d) { a->b[i]->l->v *= rates[new_rate]; break; } For(i,3) if(a->v[i] == d) { if(!(a->b[i]->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(a->b[i]); if(rates[new_rate] > 1.0) strcpy(a->b[i]->labels[a->b[i]->n_labels],"FAST"); else if(rates[new_rate] < 1.0) strcpy(a->b[i]->labels[a->b[i]->n_labels],"SLOW"); else strcpy(a->b[i]->labels[a->b[i]->n_labels],"MEDIUM"); a->b[i]->n_labels++; break; } curr_rate = new_rate; } if(d->tax) return; else { For(i,3) if(d->v[i] != a) Random_Lineage_Rates(d,d->v[i],d->b[i],stick_prob,rates,curr_rate,n_rates,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_edge *Find_Edge_With_Label(char *label, t_tree *tree) { int i,j; For(i,2*tree->n_otu-3) { For(j,tree->a_edges[i]->n_labels) { if(!strcmp(tree->a_edges[i]->labels[j],label)) return tree->a_edges[i]; } } return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Evolve(calign *data, t_mod *mod, t_tree *tree) { int root_state, root_rate_class; int site,i; phydbl *orig_l; /* phydbl shape,scale,var,mean; */ int switch_to_yes; orig_l = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); For(i,2*tree->n_otu-3) orig_l[i] = tree->a_edges[i]->l->v; data->n_otu = tree->n_otu; data->io = tree->io; if(mod->use_m4mod) tree->write_labels = YES; Set_Br_Len_Var(tree); switch_to_yes = NO; if(tree->mod->gamma_mgf_bl == YES) { switch_to_yes = YES; /* tree->mod->gamma_mgf_bl = NO; */ } For(site,data->init_len) { Set_Model_Parameters(mod); /* Pick the rate class */ root_state = root_rate_class = -1; root_rate_class = Pick_State(mod->ras->n_catg,mod->ras->gamma_r_proba->v); /* /\* Get the change probability matrices *\/ */ /* For(i,2*tree->n_otu-3) */ /* { */ /* var = MAX(0.0,tree->a_edges[i]->l_var->v) * POW(tree->mod->ras->gamma_rr->v[root_rate_class],2); */ /* mean = orig_l[i]; */ /* shape = mean * mean / var; */ /* scale = var / mean; */ /* tree->a_edges[i]->l->v = Rgamma(shape,scale); */ /* } */ For(i,2*tree->n_otu-3) Update_PMat_At_Given_Edge(tree->a_edges[i],tree); /* Pick the root nucleotide/aa */ root_state = Pick_State(mod->ns,mod->e_frq->pi->v); data->c_seq[0]->state[site] = Reciproc_Assign_State(root_state,tree->io->datatype); /* tree->a_nodes[0] is considered as the root t_node */ Evolve_Recur(tree->a_nodes[0], tree->a_nodes[0]->v[0], tree->a_nodes[0]->b[0], root_state, root_rate_class, site, data, mod, tree); /* PhyML_Printf("%s\n",Write_Tree(tree,NO)); */ data->wght[site] = 1; } data->crunch_len = data->init_len; /* Print_CSeq(stdout,NO,data); */ For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = orig_l[i]; Free(orig_l); if(switch_to_yes == YES) tree->mod->gamma_mgf_bl = YES; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Pick_State(int n, phydbl *prob) { int pos; phydbl uni; do { pos = rand(); pos = (pos % n); uni = (phydbl)rand(); uni /= (phydbl)RAND_MAX; if(uni < prob[pos]) break; } while(1); return (int)pos; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Evolve_Recur(t_node *a, t_node *d, t_edge *b, int a_state, int r_class, int site_num, calign *gen_data, t_mod *mod, t_tree *tree) { int d_state; int dim1,dim2; dim1 = tree->mod->ns * tree->mod->ns; dim2 = tree->mod->ns; d_state = Pick_State(mod->ns,b->Pij_rr+r_class*dim1+a_state*dim2); /* PhyML_Printf("\n>> %c (%d,%d)",Reciproc_Assign_State(d_state,mod->io->datatype),d_state,(int)d_state/mod->m4mod->n_o); */ if(mod->use_m4mod) { phydbl rrate; /* relative rate of substitutions */ rrate = mod->m4mod->multipl[(int)d_state/mod->m4mod->n_o]; if(!(b->n_labels%BLOCK_LABELS)) Make_New_Edge_Label(b); if(rrate > 1.0) strcpy(b->labels[b->n_labels],"FASTER"); else strcpy(b->labels[b->n_labels],"SLOWER"); b->n_labels++; } if(d->tax) { gen_data->c_seq[d->num]->state[site_num] = Reciproc_Assign_State(d_state,tree->io->datatype); return; } else { int i; For(i,3) if(d->v[i] != a) Evolve_Recur(d,d->v[i],d->b[i], d_state,r_class,site_num,gen_data, mod,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Site_Diversity(t_tree *tree) { int i,j,k,ns; int *div,sum; ns = tree->mod->ns; div = (int *)mCalloc(ns,sizeof(int)); Site_Diversity_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree); Site_Diversity_Pre (tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree); For(i,2*tree->n_otu-3) { For(j,ns) { tree->a_edges[i]->div_post_pred_left[j] = 0; tree->a_edges[i]->div_post_pred_rght[j] = 0; } } For(i,tree->n_pattern) { For(j,2*tree->n_otu-3) { Binary_Decomposition(tree->a_edges[j]->ui_l[i],div,ns); sum = 0; For(k,ns) sum += div[k]; tree->a_edges[j]->div_post_pred_left[sum-1] += tree->data->wght[i]; Binary_Decomposition(tree->a_edges[j]->ui_r[i],div,ns); sum = 0; For(k,ns) sum += div[k]; tree->a_edges[j]->div_post_pred_rght[sum-1] += tree->data->wght[i]; } } /* For(j,2*tree->n_otu-3) */ /* { */ /* PhyML_Printf("\n. Edge %4d div_left = %4d %4d %4d %4d -- div_rght = %4d %4d %4d %4d", */ /* j, */ /* tree->a_edges[j]->div_post_pred_left[0], */ /* tree->a_edges[j]->div_post_pred_left[1], */ /* tree->a_edges[j]->div_post_pred_left[2], */ /* tree->a_edges[j]->div_post_pred_left[3], */ /* tree->a_edges[j]->div_post_pred_rght[0], */ /* tree->a_edges[j]->div_post_pred_rght[1], */ /* tree->a_edges[j]->div_post_pred_rght[2], */ /* tree->a_edges[j]->div_post_pred_rght[3]); */ /* } */ Free(div); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Site_Diversity_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) Site_Diversity_Post(d,d->v[i],d->b[i],tree); Subtree_Union(d,b,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Site_Diversity_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) { Subtree_Union(d,d->b[i],tree); Site_Diversity_Pre(d,d->v[i],d->b[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Subtree_Union(t_node *n, t_edge *b_fcus, t_tree *tree) { /* | |<- b_cus | n / \ / \ / \ */ int site; unsigned int *ui, *ui_v1, *ui_v2; ui = ui_v1 = ui_v2 = NULL; if(n == b_fcus->left) { ui = b_fcus->ui_l; ui_v1 = (n == n->b[b_fcus->l_v1]->left)? (n->b[b_fcus->l_v1]->ui_r): (n->b[b_fcus->l_v1]->ui_l); ui_v2 = (n == n->b[b_fcus->l_v2]->left)? (n->b[b_fcus->l_v2]->ui_r): (n->b[b_fcus->l_v2]->ui_l); } else { ui = b_fcus->ui_r; ui_v1 = (n == n->b[b_fcus->r_v1]->left)? (n->b[b_fcus->r_v1]->ui_r): (n->b[b_fcus->r_v1]->ui_l); ui_v2 = (n == n->b[b_fcus->r_v2]->left)? (n->b[b_fcus->r_v2]->ui_r): (n->b[b_fcus->r_v2]->ui_l); } For(site,tree->n_pattern) ui[site] = ui_v1[site] | ui_v2[site]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Binary_Decomposition(int value, int *bit_vect, int size) { int i,cumul; For(i,size) bit_vect[i] = 0; cumul = 0; for(i=size-1;i>=0;i--) { if(value - cumul < (int)POW(2,i)) { bit_vect[i] = 0; } else { bit_vect[i] = 1; cumul += (int)POW(2,i); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Print_Diversity_Header(FILE *fp, t_tree *tree) { /* PhyML_Fprintf(fp,"t_edge side mean\n"); */ PhyML_Fprintf(fp,"t_edge side diversity count\n"); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Estimation of density using kernel smoothing. - where : point where I want to estimate the density, - x : data vector, - sample_size : number of data points in x */ phydbl Univariate_Kernel_Density_Estimate(phydbl where, phydbl *x, int sample_size) { phydbl sd,h; phydbl density,sqrt2pi,cons; int i; sqrt2pi = 2.506628; sd = SQRT(Var(x,sample_size)); h = 1.06 * sd * POW(sample_size,-1./5.); /* Quick and dirty way to set the bandwidth */ cons = (1./sample_size) * (1./h) * (1./sqrt2pi); density = .0; For(i,sample_size) density += EXP(-0.5 * POW((x[i] - where)/h,2)); density *= cons; return density; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Estimation of a multivariate density using kernel smoothing. - where : vector where I want to estimate the density, - x : data matrix, i.e., sample of vectors, - sample_size : number of vectors, - vect_size : vector length. See "Multivariate Density Estimation" by David Scott. pp 150. */ phydbl Multivariate_Kernel_Density_Estimate(phydbl *where, phydbl **x, int sample_size, int vect_size) { phydbl sd,*h,cons,density,tmp; phydbl _2pi; int i,j; h = (phydbl *)mCalloc(vect_size,sizeof(phydbl)); _2pi = 6.283185; For(i,vect_size) { sd = SQRT(Var(x[i],sample_size)); /* h[i] = POW(4./(vect_size+2.),1./(vect_size+4)) * sd * POW(sample_size,-1./(vect_size+4)); */ h[i] = sd * POW(sample_size,-1./(vect_size+4)); /* PhyML_Printf("\n. sd = %f, h[i] = %f",sd,h[i]); */ } cons = sample_size; For(i,vect_size) cons *= h[i]; cons *= POW(_2pi,vect_size/2.); cons = 1./cons; density = .0; For(i,sample_size) { tmp = 1.0; For(j,vect_size) { tmp *= EXP(-0.5 * POW((x[j][i] - where[j])/h[j],2)); } density += tmp; } density *= cons; Free(h); return density; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Var(phydbl *x, int n) { phydbl mean, sum2; int i; mean = Mean(x,n); sum2 = .0; For(i,n) sum2 += x[i] * x[i]; return (1./n) * (sum2 - n * POW(mean,2)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Mean(phydbl *x, int n) { int i; phydbl sum; sum = .0; For(i,n) sum += x[i]; return sum / n; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Best_Of_NNI_And_SPR(t_tree *tree) { if(tree->mod->s_opt->random_input_tree) Speed_Spr_Loop(tree); /* Don't do simultaneous NNIs if starting tree is random */ else { t_tree *ori_tree,*best_tree; t_mod *ori_mod,*best_mod; phydbl *ori_bl,*best_bl; phydbl best_lnL,ori_lnL,nni_lnL,spr_lnL; int i; #ifdef BEAGLE tree->b_inst = create_beagle_instance(tree, tree->io->quiet, tree->io); #endif ori_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); best_bl = (phydbl *)mCalloc(2*tree->n_otu-3,sizeof(phydbl)); ori_mod = Copy_Model(tree->mod); best_mod = Copy_Model(tree->mod); ori_tree = Make_Tree_From_Scratch(tree->n_otu,tree->data); /* ori_tree = Make_Tree(tree->n_otu); */ /* Init_Tree(ori_tree,ori_tree->n_otu); */ /* Make_All_Tree_Nodes(ori_tree); */ /* Make_All_Tree_Edges(ori_tree); */ best_tree = Make_Tree_From_Scratch(tree->n_otu,tree->data); /* best_tree = Make_Tree(tree->n_otu); */ /* Init_Tree(best_tree,best_tree->n_otu); */ /* Make_All_Tree_Nodes(best_tree); */ /* Make_All_Tree_Edges(best_tree); */ Copy_Tree(tree,ori_tree);//Save a backup of the original tree in ori_tree Record_Br_Len(tree); For(i,2*tree->n_otu-3) ori_bl[i] = tree->a_edges[i]->l->v; best_lnL = UNLIKELY; Lk(NULL,tree); ori_lnL = tree->c_lnL; /* Record likelihood of the starting tree */ // ****** Perform NNI ****** Simu_Loop(tree); /* Perform simultaneous NNIs */ best_lnL = tree->c_lnL; /* Record the likelihood */ nni_lnL = tree->c_lnL; //Mark the NNI tree as the "best" tree Copy_Tree(tree,best_tree); /* Record the tree topology and branch lengths */ Record_Br_Len(tree); For(i,2*tree->n_otu-3) best_bl[i] = tree->a_edges[i]->l->v; For(i,2*tree->n_otu-3) best_tree->a_edges[i]->l->v = best_bl[i]; Record_Model(tree->mod,best_mod); Copy_Tree(ori_tree,tree); /* Back to the original tree topology */ For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = ori_bl[i]; /* Back to the original branch lengths */ Record_Model(ori_mod,tree->mod); /* Back to the original model */ /* Make sure the tree is in its original form */ Lk(NULL,tree); if(FABS(tree->c_lnL - ori_lnL) > tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n== ori_lnL = %f, c_lnL = %f",ori_lnL,tree->c_lnL); PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } // ****** Perform SPR ****** Speed_Spr_Loop(tree); spr_lnL = tree->c_lnL; //Did SPR perform better than NNI? if(tree->c_lnL > best_lnL) { #ifdef BEAGLE finalize_beagle_instance(best_tree);//Free the old BEAGLE instance associated with the NNI tree (since SPR is better) #endif best_lnL = spr_lnL; Copy_Tree(tree,best_tree); /* Record tree topology, branch lengths and model parameters */ Record_Br_Len(tree); For(i,2*tree->n_otu-3) best_bl[i] = tree->a_edges[i]->l->v; For(i,2*tree->n_otu-3) best_tree->a_edges[i]->l->v = best_bl[i]; Record_Model(tree->mod,best_mod); } Copy_Tree(best_tree,tree); Fill_Dir_Table(tree); Update_Dirs(tree); Init_P_Lk_Tips_Int(tree); Init_Ui_Tips(tree); Init_P_Pars_Tips(tree); For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = best_bl[i]; Record_Model(best_mod,tree->mod); /* Make sure the current tree has the best topology, branch lengths and model parameters */ Lk(NULL,tree); if(FABS(tree->c_lnL - best_lnL) > tree->mod->s_opt->min_diff_lk_local) { PhyML_Printf("\n. best_lnL = %f, c_lnL = %f",best_lnL,tree->c_lnL); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } if(tree->mod->s_opt->print) { PhyML_Printf("\n\n. Log likelihood obtained after NNI moves : %f",nni_lnL); PhyML_Printf("\n. Log likelihood obtained after SPR moves : %f",spr_lnL); } Free(ori_bl); Free(best_bl); Free_Tree(ori_tree); Free_Tree(best_tree); Free_Model_Complete(ori_mod); Free_Model_Complete(best_mod); M4_Free_M4_Model(ori_mod->m4mod); M4_Free_M4_Model(best_mod->m4mod); Free_Model_Basic(ori_mod); Free_Model_Basic(best_mod); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Polynomial interpolation. Adapted from "Numerical Recipes in C". Press, Flannery, Teukolsky, Vetterling, 1988. */ int Polint(phydbl *xa, phydbl *ya, int n, phydbl x, phydbl *y, phydbl *dy) { int i,m,ns=1; phydbl den,dif,dift,ho,hp,w; phydbl *c,*d; dif=FABS(x-xa[1]); c = (phydbl *)mCalloc(n,sizeof(phydbl)); d = (phydbl *)mCalloc(n,sizeof(phydbl)); for(i=1;i<=n;i++) { if((dift=FABS(x-xa[i])) < dif) { ns=i; dif=dift; } c[i]=ya[i]; d[i]=ya[i]; } *y=ya[ns--]; for (m=1;m -SMALL ) { /* Rprintf("\n. Error in routine POLINT.\n"); */ Exit("\n. Error in routine POLINT.\n"); return(-1); } den=w/den; d[i]=hp*den; c[i]=ho*den; } *y += (*dy=(2*ns < (n-m) ? c[ns+1] : d[ns--])); } Free(d); Free(c); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void JF(t_tree *tree) { //printing loglk for each site, to compute SH-like tests */ phydbl sum=0.0; PhyML_Printf("\n\nSITES LKS:\n"); int n_patterns = (int)FLOOR(tree->n_pattern); int site=0; For(site,n_patterns) { int wei=0; For(wei,tree->data->wght[site]) { PhyML_Printf("%f\n",tree->c_lnL_sorted[site] / tree->data->wght[site]); sum+=tree->c_lnL_sorted[site] / tree->data->wght[site]; } } PhyML_Printf("\n\nsum=%f\n\n",sum); int i=0; For(i,2*tree->n_otu-3) { if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) { PhyML_Printf("%3d %f %f %f\n", tree->a_edges[i]->bip_score,tree->a_edges[i]->alrt_statistic, tree->a_edges[i]->ratio_test,tree->a_edges[i]->l->v); } } /* //printing loglk for each site, to compute SH-like tests */ /* phydbl sum=0.0; */ /* PhyML_Printf("\n\nSITES LKS:\n"); */ /* int n_patterns = (int)FLOOR(tree->n_pattern); */ /* int site=0; */ /* For(site,n_patterns) { */ /* int wei=0; */ /* For(wei,tree->data->wght[site]) { */ /* PhyML_Printf("%f\n",tree->c_lnL_sorted[site] / tree->data->wght[site]); */ /* sum+=tree->c_lnL_sorted[site] / tree->data->wght[site]; */ /* } */ /* } */ /* PhyML_Printf("\n\nsum=%f\n\n",sum); */ /* int i=0; */ /* For(i,2*tree->n_otu-3) */ /* { */ /* if((!tree->a_edges[i]->left->tax) && (!tree->a_edges[i]->rght->tax)) */ /* { */ /* PhyML_Printf("%3d %f %f %f\n", */ /* tree->a_edges[i]->bip_score,tree->a_edges[i]->alrt_statistic, tree->a_edges[i]->ratio_test,tree->a_edges[i]->l->v); */ /* } */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_tree *Dist_And_BioNJ(calign *cdata, t_mod *mod, option *io) { t_tree *tree; matrix *mat; if(mod->s_opt->random_input_tree == NO) { if(!io->quiet) PhyML_Printf("\n. Computing pairwise distances..."); mat = ML_Dist(cdata,mod); Fill_Missing_Dist(mat); if(!io->quiet) PhyML_Printf("\n\n. Building BioNJ tree..."); mat->tree = Make_Tree_From_Scratch(cdata->n_otu,cdata); Bionj(mat); tree = mat->tree; tree->mat = mat; } else { tree = Make_Tree_From_Scratch(cdata->n_otu,cdata); tree->mat = NULL; } return tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Add_BioNJ_Branch_Lengths(t_tree *tree, calign *cdata, t_mod *mod) { matrix *mat; PhyML_Printf("\n"); PhyML_Printf("\n. Computing branch length estimates...\n"); Connect_CSeqs_To_Nodes(cdata,mod->io,tree); mat = ML_Dist(cdata,mod); mat->tree = tree; mat->method = 0; Bionj_Br_Length(mat); Free_Mat(mat); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *Bootstrap_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io) { t_tree *tree; tree = Read_Tree(&s_tree); tree->n_root = NULL; tree->e_root = NULL; if(!tree) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit(""); } tree->mod = mod; tree->io = io; tree->data = cdata; tree->n_pattern = tree->data->crunch_len; Connect_CSeqs_To_Nodes(cdata,io,tree); if(tree->mod->s_opt->random_input_tree) Random_Tree(tree); Fill_Dir_Table(tree); Update_Dirs(tree); Make_Tree_4_Pars(tree,cdata,cdata->init_len); Make_Tree_4_Lk(tree,cdata,cdata->init_len); tree->triplet_struct = Make_Triplet_Struct(mod); Init_Triplet_Struct(tree->triplet_struct); Unscale_Br_Len_Multiplier_Tree(tree); Br_Len_Not_Involving_Invar(tree); Make_Spr_List(tree); Make_Best_Spr(tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); #ifdef MPI Bootstrap_MPI(tree); #else Bootstrap(tree); #endif Free(s_tree); Rescale_Br_Len_Multiplier_Tree(tree); Br_Len_Involving_Invar(tree); s_tree = Write_Tree(tree,NO); Free_Spr_List(tree); Free_Triplet(tree->triplet_struct); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); return s_tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *aLRT_From_String(char *s_tree, calign *cdata, t_mod *mod, option *io) { t_tree *tree; tree = Read_Tree(&s_tree); tree->n_root = NULL; tree->e_root = NULL; if(!tree) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Warn_And_Exit(""); } tree->mod = mod; tree->io = io; tree->data = cdata; tree->n_pattern = tree->data->crunch_len; Connect_CSeqs_To_Nodes(cdata,io,tree); if(tree->mod->s_opt->random_input_tree) Random_Tree(tree); Fill_Dir_Table(tree); Update_Dirs(tree); Make_Tree_4_Pars(tree,cdata,cdata->init_len); Make_Tree_4_Lk(tree,cdata,cdata->init_len); tree->triplet_struct = Make_Triplet_Struct(mod); Init_Triplet_Struct(tree->triplet_struct); Make_Spr_List(tree); Make_Best_Spr(tree); #ifdef BEAGLE tree->b_inst = create_beagle_instance(tree, io->quiet, io); #endif Set_Both_Sides(YES,tree); // Print_All_Edge_Likelihoods(tree); Lk(NULL,tree); // Print_All_Edge_PMats(tree); // Print_All_Edge_Likelihoods(tree); aLRT(tree); Free(s_tree); s_tree = Write_Tree(tree,NO); #ifdef BEAGLE finalize_beagle_instance(tree); #endif Free_Spr_List(tree); Free_Triplet(tree->triplet_struct); Free_Tree_Pars(tree); Free_Tree_Lk(tree); Free_Tree(tree); return s_tree; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Prepare_Tree_For_Lk(t_tree *tree) { Connect_CSeqs_To_Nodes(tree->data,tree->io,tree); Fill_Dir_Table(tree); Update_Dirs(tree); Make_Tree_4_Pars(tree,tree->data,tree->data->init_len); Make_Tree_4_Lk(tree,tree->data,tree->data->init_len); tree->triplet_struct = Make_Triplet_Struct(tree->mod); Init_Triplet_Struct(tree->triplet_struct); Make_Spr_List(tree); Make_Best_Spr(tree); if(tree->is_mixt_tree) MIXT_Prepare_Tree_For_Lk(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Common_Tips(t_tree *tree1, t_tree *tree2) { int i,j; For(i,tree1->n_otu) tree1->a_nodes[i]->common = 0; For(i,tree2->n_otu) tree2->a_nodes[i]->common = 0; For(i,tree1->n_otu) { For(j,tree2->n_otu) { if(!strcmp(tree1->a_nodes[i]->name,tree2->a_nodes[j]->name)) { tree1->a_nodes[i]->common = 1; tree2->a_nodes[j]->common = 1; break; } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Get_Tree_Size(t_tree *tree) { int i; phydbl tree_size; tree_size = 0.0; For(i,2*tree->n_otu-3) tree_size += tree->a_edges[i]->l->v; if(tree->n_root) { tree_size += tree->n_root->b[1]->l->v; tree_size += tree->n_root->b[2]->l->v; } /* For(i,2*tree->n_otu-3) */ /* tree_size += */ /* FABS(tree->rates->nd_t[tree->a_edges[i]->left->num] - */ /* tree->rates->nd_t[tree->a_edges[i]->rght->num]); */ tree->size = tree_size; return tree_size; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Dist_To_Root_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { int i; if(b) d->dist_to_root = a->dist_to_root + b->l->v; if(d->tax) return; else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) Dist_To_Root_Pre(d,d->v[i],d->b[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Dist_To_Root(t_node *n_root, t_tree *tree) { /* n_root->v[2]->dist_to_root = tree->rates->cur_l[n_root->v[2]->num]; */ /* n_root->v[1]->dist_to_root = tree->rates->cur_l[n_root->v[1]->num]; */ n_root->v[2]->dist_to_root = tree->e_root->l->v * tree->n_root_pos; n_root->v[1]->dist_to_root = tree->e_root->l->v * (1. - tree->n_root_pos); Dist_To_Root_Pre(n_root,n_root->v[2],NULL,tree); Dist_To_Root_Pre(n_root,n_root->v[1],NULL,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* 'Borrowed' fromn libgen */ char *Basename(char *path) { char *p; if( path == NULL || *path == '\0' ) return "."; p = path + strlen(path) - 1; while( *p == '/' ) { if( p == path ) return path; *p-- = '\0'; } while( p >= path && *p != '/' ) p--; return p + 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Find the Last Common Ancestor of n1 and n2 */ t_node *Find_Lca_Pair_Of_Nodes(t_node *n1, t_node *n2, t_tree *tree) { t_node **list1, **list2, *lca; int size1, size2; if(n1 == n2) return(n1); if(!tree->n_root) { PhyML_Printf("\n. The tree must be rooted in this function."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } list1 = (t_node **)mCalloc(2*tree->n_otu-1,sizeof(t_node *)); list2 = (t_node **)mCalloc(2*tree->n_otu-1,sizeof(t_node *)); Get_List_Of_Ancestors(n1,list1,&size1,tree); Get_List_Of_Ancestors(n2,list2,&size2,tree); while(list1[size1] == list2[size2]) { size1--; size2--; if(size1 < 0 || size2 < 0) break; } lca = list1[size1+1]; Free(list1); Free(list2); if(lca == NULL) { PhyML_Printf("\n. %s",Write_Tree(tree,NO)); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } return lca; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Find the Last Common Ancestor of all the nodes in node_list */ t_node *Find_Lca_Clade(t_node **node_list, int node_list_size, t_tree *tree) { t_node ***list, *lca; int *size; int i; if(!tree->n_root) { PhyML_Printf("\n== The tree must be rooted in this function."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } list = (t_node ***)mCalloc(node_list_size,sizeof(t_node **)); For(i,node_list_size) list[i] = (t_node **)mCalloc(2*tree->n_otu-1,sizeof(t_node *)); size = (int *)mCalloc(node_list_size,sizeof(int)); For(i,node_list_size) { if(!Get_List_Of_Ancestors(node_list[i],list[i],size+i,tree)) { For(i,node_list_size) PhyML_Printf("\n== %s",node_list[i]->name); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } if(node_list_size > 1) { do { For(i,node_list_size-1) if(list[i][size[i]] != list[i+1][size[i+1]]) break; if(i != node_list_size-1) break; For(i,node_list_size) { size[i]--; if(size[i] == 1) break; // We have reached the tip corresponding to node_list[i] } if(node_list_size == 1) break; }while(1); lca = list[0][size[0]+1]; } else { lca = node_list[0]; } For(i,node_list_size) Free(list[i]); Free(list); Free(size); return lca; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Returns the list of the ancestors of ref_t_node from ref_t_node to the root included */ int Get_List_Of_Ancestors(t_node *ref_node, t_node **list, int *size, t_tree *tree) { t_node *n; n = ref_node; list[0] = n; *size = 1; if(!n) { PhyML_Printf("\n== There seems to be a problem with the calibration file.\n"); return 0; } while(n != tree->n_root) { n = n->anc; if(!n) { PhyML_Printf("\n== n->anc has not been set properly (call Update_Ancestors first...)\n"); return 0; } list[*size] = n; *size = *size+1; } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Edge_Num_To_Node_Num(int edge_num, t_tree *tree) { int node_num; t_edge *b; b = tree->a_edges[edge_num]; node_num = (b->left == b->rght->anc)?(b->rght->num):(b->left->num); return node_num; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Time_To_Branch(t_tree *tree) { Time_To_Branch_Pre(tree->n_root,tree->n_root->v[2],tree); Time_To_Branch_Pre(tree->n_root,tree->n_root->v[1],tree); tree->n_root->l[1] = tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]; tree->n_root->l[2] = tree->rates->nd_t[tree->n_root->v[1]->num] - tree->rates->nd_t[tree->n_root->num]; tree->e_root->l->v = tree->n_root->l[1] + tree->n_root->l[2]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Time_To_Branch_Pre(t_node *a, t_node *d, t_tree *tree) { int i; /* tree->rates->cur_l[d->num] = FABS(tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]); */ tree->rates->cur_l[d->num] = tree->rates->nd_t[d->num] - tree->rates->nd_t[a->num]; if(d->tax) return; else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) Time_To_Branch_Pre(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Assume an ultrametric tree. void Branch_To_Time(t_tree *tree) { Branch_To_Time_Pre(tree->n_root,tree->n_root->v[2],tree); Branch_To_Time_Pre(tree->n_root,tree->n_root->v[1],tree); tree->rates->nd_t[tree->n_root->num] = tree->rates->nd_t[tree->n_root->v[1]->num] - tree->n_root->l[1]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Branch_To_Time_Pre(t_node *a, t_node *d, t_tree *tree) { int i; if(d->tax) { tree->rates->nd_t[d->num] = 0.0; return; } else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { Branch_To_Time_Pre(d,d->v[i],tree); } For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) { tree->rates->nd_t[d->num] = tree->rates->nd_t[d->v[i]->num] - d->b[i]->l->v; break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Branch_Lengths_To_Rate_Lengths(t_tree *tree) { Branch_Lengths_To_Rate_Lengths_Pre(tree->n_root,tree->n_root->v[2],tree); Branch_Lengths_To_Rate_Lengths_Pre(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Branch_Lengths_To_Rate_Lengths_Pre(t_node *a, t_node *d, t_tree *tree) { int i; tree->rates->cur_l[d->num] = tree->rates->br_r[d->num] * tree->rates->clock_r * tree->rates->norm_fact; if(d->tax) return; else { For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) Branch_Lengths_To_Rate_Lengths_Pre(d,d->v[i],tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Find_Clade(char **tax_name_list, int list_size, t_tree *tree) { int *tax_num_list; t_node **tax_node_list; int i,j; int n_matches; t_node *lca; tax_num_list = (int *)mCalloc(list_size,sizeof(int)); tax_node_list = (t_node **)mCalloc(list_size,sizeof(t_node *)); For(i,list_size) tax_num_list[i] = -1; n_matches = 0; For(i,list_size) { For(j,tree->n_otu) { if(!strcmp(tax_name_list[i],tree->a_nodes[j]->name)) { tax_num_list[i] = tree->a_nodes[j]->num; tax_node_list[i] = tree->a_nodes[j]; n_matches++; break; } } if(j == tree->n_otu) { PhyML_Printf("\n== Problem with the calibration file."); PhyML_Printf("\n== Could not find taxon with name '%s' in the sequence or tree file.",tax_name_list[i]); Exit("\n"); } } lca = Find_Lca_Clade(tax_node_list,n_matches,tree); if(lca) return lca->num; else return -1; /* if(list_size == tree->n_otu) /\* Root node *\/ */ /* { */ /* int i,j; */ /* int score; */ /* score = 0; */ /* For(i,list_size) */ /* { */ /* For(j,tree->n_otu) */ /* { */ /* /\* if(!strcmp(tax_name_list[i],tree->a_nodes[j]->name)) score++; *\/ */ /* if(tax_num_list[i] == tree->a_nodes[j]->num) score++; */ /* } */ /* } */ /* Free(tax_num_list); */ /* if(score == tree->n_otu) return tree->n_root->num; */ /* else return -1; */ /* } */ /* else */ /* { */ /* int num; */ /* num = -1; */ /* Free_Bip(tree); */ /* Alloc_Bip(tree); */ /* Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); */ /* Find_Clade_Pre(tree->n_root,tree->n_root->v[2],tax_num_list,list_size,&num,tree); */ /* Find_Clade_Pre(tree->n_root,tree->n_root->v[1],tax_num_list,list_size,&num,tree); */ /* Free(tax_num_list); */ /* return num; */ /* } */ Free(tax_node_list); Free(tax_num_list); return -1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Clade_Pre(t_node *a, t_node *d, int *tax_num_list, int list_size, int *num, t_tree *tree) { int i,j,k; int score; For(i,3) if((d->v[i] == a) || (d->b[i] == tree->e_root)) { if(list_size == d->bip_size[i]) { score = 0; For(j,d->bip_size[i]) { For(k,list_size) { if(tax_num_list[k] == d->bip_node[i][j]->num) { score++; break; } } } if(score == list_size) *num = d->num; } break; } if(d->tax) return; else For(i,3) if((d->v[i] != a) && (d->b[i] != tree->e_root)) Find_Clade_Pre(d,d->v[i],tax_num_list,list_size,num,tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// t_edge *Find_Root_Edge(FILE *fp_input_tree, t_tree *tree) { char **subs; int degree; int i,j; t_node *left, *rght; int l_r, r_l; int score; char *line; char c; t_edge *root_edge; line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); rewind(fp_input_tree); do c=fgetc(fp_input_tree); while((c != '(') && (c != EOF)); if(c==EOF) { Free(line); return NULL; } i=0; for(;;) { if((c == ' ') || (c == '\n')) { c=fgetc(fp_input_tree); if(c==EOF) break; else continue; } line[i]=c; i++; c=fgetc(fp_input_tree); if(c==EOF || c==';') break; } Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); subs = Sub_Trees(line,°ree); Clean_Multifurcation(subs,degree,3); if(degree != 2) { PhyML_Printf("\n== The tree does not seem to be rooted..."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } left = rght = NULL; l_r = r_l = -1; For(i,2*tree->n_otu-3) { left = tree->a_edges[i]->left; rght = tree->a_edges[i]->rght; l_r = tree->a_edges[i]->l_r; r_l = tree->a_edges[i]->r_l; score = 0; For(j,left->bip_size[l_r]) if(strstr(subs[1],left->bip_node[l_r][j]->name)) score++; if(score == left->bip_size[l_r]) break; score = 0; For(j,rght->bip_size[r_l]) if(strstr(subs[1],rght->bip_node[r_l][j]->name)) score++; if(score == rght->bip_size[r_l]) break; } root_edge = tree->a_edges[i]; For(i,NODE_DEG_MAX) Free(subs[i]); Free(subs); Free(line); if(i == 2*tree->n_otu-3) { PhyML_Printf("\n== Could not find the root edge..."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } return root_edge; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Tree_Topology_With_Labels(t_tree *ori, t_tree *cpy) { int i,j; For(i,2*ori->n_otu-2) { For(j,3) { if(ori->a_nodes[i]->v[j]) { cpy->a_nodes[i]->v[j] = cpy->a_nodes[ori->a_nodes[i]->v[j]->num]; cpy->a_nodes[i]->l[j] = ori->a_nodes[i]->l[j]; } else cpy->a_nodes[i]->v[j] = NULL; } cpy->a_nodes[i]->num = ori->a_nodes[i]->num; cpy->a_nodes[i]->tax = 0; } For(i,2*ori->n_otu-3) { cpy->a_edges[i]->l->v = ori->a_edges[i]->l->v; } For(i,ori->n_otu) { cpy->a_nodes[i]->tax = 1; strcpy(cpy->a_nodes[i]->name,ori->a_nodes[i]->name); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Model_Name(t_mod *mod) { switch(mod->whichmodel) { case JC69: { strcpy(mod->modelname->s, "JC69"); break; } case K80: { strcpy(mod->modelname->s, "K80"); break; } case F81: { strcpy(mod->modelname->s, "F81"); break; } case HKY85: { strcpy(mod->modelname->s, "HKY85"); break; } case F84: { strcpy(mod->modelname->s, "F84"); break; } case TN93: { strcpy(mod->modelname->s, "TN93"); break; } case GTR: { strcpy(mod->modelname->s, "GTR"); break; } case CUSTOM: { strcpy(mod->modelname->s, "Custom"); break; } case DAYHOFF: { strcpy(mod->modelname->s, "Dayhoff"); break; } case JTT: { strcpy(mod->modelname->s, "JTT"); break; } case MTREV: { strcpy(mod->modelname->s, "MtREV"); break; } case LG: { strcpy(mod->modelname->s, "LG"); break; } case WAG: { strcpy(mod->modelname->s, "WAG"); break; } case DCMUT: { strcpy(mod->modelname->s, "DCMut"); break; } case RTREV: { strcpy(mod->modelname->s, "RtREV"); break; } case CPREV: { strcpy(mod->modelname->s, "CpREV"); break; } case VT: { strcpy(mod->modelname->s, "VT"); break; } case BLOSUM62: { strcpy(mod->modelname->s, "Blosum62"); break; } case MTMAM: { strcpy(mod->modelname->s, "MtMam"); break; } case MTART: { strcpy(mod->modelname->s, "MtArt"); break; } case HIVW: { strcpy(mod->modelname->s, "HIVw"); break; } case HIVB: { strcpy(mod->modelname->s, "HIVb"); break; } case AB: { strcpy(mod->modelname->s, "AB"); break; } case CUSTOMAA: { strcpy(mod->modelname->s, "Custom"); break; } default: { PhyML_Printf("\n== Unknown model name.\n"); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); break; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Adjust_Min_Diff_Lk(t_tree *tree) { if(sizeof(phydbl) == 4) { int exponent; exponent = (int)FLOOR(log10(FABS(tree->c_lnL))); tree->mod->s_opt->min_diff_lk_local = POW(10.,exponent - FLT_DIG + 1); tree->mod->s_opt->min_diff_lk_local = tree->mod->s_opt->min_diff_lk_local; tree->mod->s_opt->min_diff_lk_move = tree->mod->s_opt->min_diff_lk_local; } /* PhyML_Printf("\n. Exponent = %d Precision = %E DIG = %d",exponent,tree->mod->s_opt->min_diff_lk_local,FLT_DIG); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! tree->a_nodes[i]->name is initially a number. It is translated into a string of characters using the names provided in the tax_name array. */ void Translate_Tax_Names(char **tax_names, t_tree *tree) { int i; int tax_num; For(i,tree->n_otu) { tax_num = strtol(tree->a_nodes[i]->name,NULL,10); tree->a_nodes[i]->name = tax_names[tax_num-1]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Skip coment in NEXUS file. */ void Skip_Comment(FILE *fp) { int in_comment; char c; in_comment = 1; do { c = fgetc(fp); if(c == EOF) break; if(c == '[') in_comment++; else if(c == ']') in_comment--; } while(in_comment); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Determine the most appropriate position of the root if outgroup taxa are specified. */ void Get_Best_Root_Position(t_tree *tree) { int i,j; phydbl eps; phydbl s, s_max; t_edge *best_edge; int has_outgrp; best_edge = NULL; if(tree->n_root) { PhyML_Printf("\n== Tree already has a root."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } has_outgrp = NO; if(strstr(tree->a_nodes[0]->name,"*")) { /* PhyML_Printf("\n. Found outgroup taxon: %s",tree->a_nodes[0]->name); */ tree->a_nodes[0]->s_ingrp[0] = 0; tree->a_nodes[0]->s_outgrp[0] = 1; has_outgrp = YES; } else { tree->a_nodes[0]->s_ingrp[0] = 1; tree->a_nodes[0]->s_outgrp[0] = 0; } Get_Best_Root_Position_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],&has_outgrp,tree); Get_Best_Root_Position_Pre(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); if(has_outgrp == YES) { Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-2]); Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-2]); eps = 1.E-10; s = s_max = 0.0; For(i,2*tree->n_otu-2) { For(j,3) { s = (tree->a_nodes[i]->s_outgrp[j]+eps) / (tree->a_nodes[i]->s_ingrp[j] + eps) ; /* printf("\n. [%d %d] %d %d",i,j,tree->a_nodes[i]->s_outgrp[j],tree->a_nodes[i]->s_ingrp[j]); */ if(s > s_max) { s_max = s; best_edge = tree->a_nodes[i]->b[j]; } } } Add_Root(best_edge,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Determine the most appropriate position of the root if outgroup taxa are specified. Post-traversal. */ void Get_Best_Root_Position_Post(t_node *a, t_node *d, int *has_outgrp, t_tree *tree) { if(d->tax) { if(strstr(d->name,"*")) { *has_outgrp = YES; /* PhyML_Printf("\n. Found outgroup taxon: %s",d->name); */ d->s_ingrp[0] = NO; d->s_outgrp[0] = YES; } else { d->s_ingrp[0] = YES; d->s_outgrp[0] = NO; } return; } else { int i; For(i,3) if(d->v[i] != a && (d->b[i] != tree->e_root)) Get_Best_Root_Position_Post(d,d->v[i],has_outgrp,tree); Get_OutIn_Scores(a,d); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Determine the most appropriate position of the root if outgroup taxa are specified. Pre-traversal. */ void Get_Best_Root_Position_Pre(t_node *a, t_node *d, t_tree *tree) { if(d->tax) { return; } else { int i; For(i,3) if(d->v[i] != a && (d->b[i] != tree->e_root)) { Get_OutIn_Scores(d->v[i],d); Get_Best_Root_Position_Pre(d,d->v[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /*! Determine the most appropriate position of the root if outgroup taxa are specified. Core. */ void Get_OutIn_Scores(t_node *a, t_node *d) { int i,d_v1,d_v2,v1_d,v2_d,d_a; d_a = v1_d = v2_d = -1; d_v1 = d_v2 = -1; For(i,3) { if(d->v[i] != a) { if(d_v1 < 0) d_v1 = i; else d_v2 = i; } } For(i,3) if(d->v[i] == a) { d_a = i; break; } For(i,3) if(d->v[d_v1]->v[i] == d) { v1_d = i; break; } For(i,3) if(d->v[d_v2]->v[i] == d) { v2_d = i; break; } d->s_ingrp[d_a] = d->v[d_v1]->s_ingrp[v1_d] + d->v[d_v2]->s_ingrp[v2_d] ; d->s_outgrp[d_a] = d->v[d_v1]->s_outgrp[v1_d] + d->v[d_v2]->s_outgrp[v2_d] ; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Check_Sequence_Name(char *s) { int i; /* if(rindex(s,':')) */ For(i,strlen(s)) { if(s[i] == ':') { PhyML_Printf("\n== Character ':' is not permitted in sequence name (%s).",s); PhyML_Printf("\n== Err. in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } } /* if(rindex(s,',')) */ For(i,strlen(s)) { if(s[i] == ',') { PhyML_Printf("\n== Character ',' is not permitted in sequence name (%s).",s); PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } } /* if(rindex(s,' ')) */ For(i,strlen(s)) { if(s[i] == ' ') { PhyML_Printf("\n== Character ' ' is not permitted in sequence name (%s).",s); PhyML_Printf("\n== Err in file %s at line %d",__FILE__,__LINE__); Warn_And_Exit(""); } } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Scale_Subtree_Height(t_node *a, phydbl K, phydbl floor, int *n_nodes, t_tree *tree) { phydbl new_height; *n_nodes = 0; new_height = .0; if(!(tree->rates->nd_t[a->num] > floor)) new_height = K*(tree->rates->nd_t[a->num]-floor)+floor; if(a == tree->n_root) { tree->rates->nd_t[tree->n_root->num] = new_height; *n_nodes = 1; Scale_Node_Heights_Post(tree->n_root,tree->n_root->v[2],K,floor,n_nodes,tree); Scale_Node_Heights_Post(tree->n_root,tree->n_root->v[1],K,floor,n_nodes,tree); } else { int i; if(new_height < tree->rates->nd_t[a->anc->num]) return 0; else { tree->rates->nd_t[a->num] = new_height; *n_nodes = 1; } For(i,3) if(a->v[i] != a->anc && a->b[i] != tree->e_root) { Scale_Node_Heights_Post(a,a->v[i],K,floor,n_nodes,tree); } } return 1; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Scale_Node_Heights_Post(t_node *a, t_node *d, phydbl K, phydbl floor, int *n_nodes, t_tree *tree) { if(d == tree->n_root) { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } if(d->tax) { if(!(tree->rates->nd_t[d->num] > floor)) { /* Scaling does not change the node height here but, in theory this tip is among the scaled nodes. Therefore needs to count it in for working out correct Hastings ratios */ /* *n_nodes = *n_nodes+1; */ } return; } else { int i; /* It is tempting to set floor = tree->rates->t_prior_max[d->num]; but it then becomes possible for nodes with different floor values to have their orders interverted (i.e., ancestor below descendant) */ if(!(tree->rates->nd_t[d->num] > floor)) { tree->rates->nd_t[d->num] = K*(tree->rates->nd_t[d->num]-floor)+floor; *n_nodes = *n_nodes+1; } if(tree->rates->nd_t[d->num] < tree->rates->nd_t[a->num]) { PhyML_Printf("\n. K = %f floor = %f t_prior_max(a) = %f t_prior_max(d) = %f a->t = %f d->t %f", K,floor,tree->rates->t_prior_max[a->num],tree->rates->t_prior_max[d->num], tree->rates->nd_t[a->num],tree->rates->nd_t[d->num]); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Warn_And_Exit(""); } For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) Scale_Node_Heights_Post(d,d->v[i],K,floor,n_nodes,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Scale_Subtree_Rates(t_node *a, phydbl mult, int *n_nodes, t_tree *tree) { int res; int i; *n_nodes = 0; res = 1; if(a == tree->n_root) { res = Scale_Subtree_Rates_Post(a,a->v[2],mult,n_nodes,tree); if(res) res = Scale_Subtree_Rates_Post(a,a->v[1],mult,n_nodes,tree); return res; } else { For(i,3) if((a->v[i] != a->anc) && (a->b[i] != tree->e_root) && (res == 1)) res = Scale_Subtree_Rates_Post(a,a->v[i],mult,n_nodes,tree); return res; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Scale_Subtree_Rates_Post(t_node *a, t_node *d, phydbl mult, int *n_nodes, t_tree *tree) { if(tree->rates->model_log_rates == YES) { tree->rates->br_r[d->num] += LOG(mult); } else { tree->rates->br_r[d->num] *= mult; } *n_nodes = *n_nodes+1; if(tree->rates->br_r[d->num] < tree->rates->min_rate) return 0; if(tree->rates->br_r[d->num] > tree->rates->max_rate) return 0; if(d->tax) return 1; else { int i,res; res = 1; For(i,3) { if((d->v[i] != a) && (d->b[i] != tree->e_root) && (res == 1)) { res = Scale_Subtree_Rates_Post(d,d->v[i],mult,n_nodes,tree); } } return res; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Node_Ranks(t_tree *tree) { tree->n_root->rank = 1; Get_Node_Ranks_Pre(tree->n_root,tree->n_root->v[2],tree); Get_Node_Ranks_Pre(tree->n_root,tree->n_root->v[1],tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Node_Ranks_Pre(t_node *a, t_node *d,t_tree *tree) { d->rank = a->rank+1; if(d->tax) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != tree->e_root) { Get_Node_Ranks_Pre(d,d->v[i],tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Log_Br_Len(t_tree *tree) { int i; For(i,2*tree->n_otu-3) tree->a_edges[i]->l->v = LOG(tree->a_edges[i]->l->v); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Diff_Lk_Norm_At_Given_Edge(t_edge *b, t_tree *tree) { int i,dim,err; phydbl lk_exact,lk_norm,sum; Record_Br_Len(tree); dim = 2*tree->n_otu-3; sum = 0.0; For(i,tree->n_short_l) { b->l->v = tree->short_l[i]; lk_exact = Lk(b,tree); lk_norm = tree->norm_scale + Log_Dnorm(b->l->v,tree->rates->mean_l[b->num], tree->rates->cov_l[b->num*dim+b->num],&err); if(err) { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } sum += pow(lk_exact - lk_norm,2); } Restore_Br_Len(tree); Lk(b,tree); return(sum); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Adjust_Variances(t_tree *tree) { int i; phydbl new_diff,curr_diff; Make_Short_L(tree); For(i,tree->n_short_l) { tree->short_l[i] = tree->mod->l_min + i*(0.1 - tree->mod->l_min)/tree->n_short_l; } For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->l->v < 1.1*tree->mod->l_min) { tree->rates->mean_l[i] = -1.00; tree->rates->cov_l[i*(2*tree->n_otu-3)+i] = 0.1; tree->norm_scale = -100; new_diff = curr_diff = 10.0; do { curr_diff = new_diff; Generic_Brent_Lk(&(tree->norm_scale), -1E+6, 0.0, 1.E-10, 10000, NO, Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO); /* Generic_Brent_Lk(&(tree->rates->mean_l[0]), */ /* -100., */ /* 10*tree->mod->l_min, */ /* 1.E-3, */ /* 10000, */ /* NO, */ /* Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[0],tree,NULL); */ Generic_Brent_Lk(&(tree->rates->cov_l[i*(2*tree->n_otu-3)+i]), 0.0, 10.0, 1.E-10, 10000, NO, Wrap_Diff_Lk_Norm_At_Given_Edge,tree->a_edges[i],tree,NULL,NO); new_diff = Diff_Lk_Norm_At_Given_Edge(tree->a_edges[i],tree); }while(FABS(new_diff-curr_diff) > 1.E-3); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Effective_Sample_Size(phydbl first_val, phydbl last_val, phydbl sum, phydbl sumsq, phydbl sumcurnext, int n) { phydbl numerator,denom; phydbl mean; phydbl r; mean = sum / n; denom = sumsq - n * POW(mean,2); numerator = sumcurnext - (n+1.)*POW(mean,2) + (first_val+last_val)*mean; r = numerator/denom; return (phydbl)n * (1.-r)/(1.+r); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Rescale_Br_Len_Multiplier_Tree(t_tree *tree) { int i; if(tree->is_mixt_tree) { MIXT_Rescale_Br_Len_Multiplier_Tree(tree); return(-1.); } For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v *= tree->mod->br_len_mult->v; return(-1.); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Unscale_Br_Len_Multiplier_Tree(t_tree *tree) { int i; if(tree->is_mixt_tree) { MIXT_Unscale_Br_Len_Multiplier_Tree(tree); return(-1.); } For(i,2*tree->n_otu-1) tree->a_edges[i]->l->v /= tree->mod->br_len_mult->v; return(-1.); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Reflect(phydbl x, phydbl l, phydbl u) { int rounds; phydbl tmp; int k; if(u < l) { tmp = u; u = l; l = tmp; } if(x < l) x = x + 2.*(l - x); if(((x-u) > (u-l)) && (x > u)) { k = (x - (2.*u-l))/(2.*(u-l)); x = x - 2.*k*(u-l); } rounds = 0; do { rounds++; /* printf("\n. l=%f u=%f x=%f",l,u,x); */ if(x > u || x < l) { if(x > u) x = x - 2.*(x - u); else x = x + 2.*(l - x); } else break; /* printf(" x'=%f",x); */ } while(rounds < 100); if(rounds == 100 && (x > u || x < l)) { PhyML_Printf("\n. u=%f l=%f x=%f",u,l,x); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } return x; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Are_Equal(phydbl a, phydbl b, phydbl eps) { if(FABS(a-b) < eps) return TRUE; /* a==b */ else return FALSE; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Returns 1 if small_tree is displayed by big_tree, 0 otherwise Does not account for the root positions, if any. */ int Check_Topo_Constraints(t_tree *big_tree, t_tree *small_tree) { if(!small_tree) return 1; if(small_tree->n_otu < 4) return 1; if(small_tree->n_otu > big_tree->n_otu) { PhyML_Printf("\n"); PhyML_Printf("\n== The tree that defines the topological constraints can not"); PhyML_Printf("\n== display more taxa than %d",big_tree->n_otu); Exit("\n"); } t_tree *big_tree_cpy; int diffs,i; big_tree_cpy = Make_Tree_From_Scratch(big_tree->n_otu,NULL); Copy_Tree(big_tree,big_tree_cpy); Prune_Tree(big_tree_cpy,small_tree); /* For(i,2*small_tree->n_otu-3) printf("\nz %d . %d . %d", */ /* big_tree->a_edges[i]->does_exist, */ /* big_tree_cpy->a_edges[i]->does_exist, */ /* small_tree->a_edges[i]->does_exist); */ Free_Bip(small_tree); Alloc_Bip(small_tree); Get_Bip(small_tree->a_nodes[0],small_tree->a_nodes[0]->v[0],small_tree); Free_Bip(big_tree_cpy); Alloc_Bip(big_tree_cpy); Match_Tip_Numbers(small_tree,big_tree_cpy); Get_Bip(big_tree_cpy->a_nodes[0],big_tree_cpy->a_nodes[0]->v[0],big_tree_cpy); For(i,2*big_tree_cpy->n_otu-3) big_tree_cpy->a_edges[i]->bip_score = 0; For(i,2*small_tree->n_otu-3) small_tree->a_edges[i]->bip_score = 0; diffs = Compare_Bip(small_tree,big_tree_cpy,NO); /* printf("\n"); */ /* printf("\n. %s",Write_Tree(big_tree_cpy,NO)); */ /* printf("\n. %s",Write_Tree(small_tree,NO)); */ /* printf("\n. diffs=%d",diffs); */ Free_Tree(big_tree_cpy); t_tree *big_tree_cpy_bis; big_tree_cpy_bis = Make_Tree_From_Scratch(big_tree->n_otu,NULL); Copy_Tree(big_tree,big_tree_cpy_bis); Free_Tree(big_tree_cpy_bis); if(diffs == 0) return 1; /* Constraint is satisfied */ else return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Prune_Tree(t_tree *big_tree, t_tree *small_tree) { int i,j; int curr_ext_node, curr_int_node, curr_br, n_pruned_nodes;; t_node **pruned_nodes; t_edge **residual_edges; pruned_nodes = (t_node **)mCalloc(big_tree->n_otu,sizeof(t_node *)); residual_edges = (t_edge **)mCalloc(big_tree->n_otu,sizeof(t_edge *)); n_pruned_nodes = 0; For(i,big_tree->n_otu) { For(j,small_tree->n_otu) if(!strcmp(small_tree->a_nodes[j]->name,big_tree->a_nodes[i]->name)) break; if(j == small_tree->n_otu) { Prune_Subtree(big_tree->a_nodes[i]->v[0], big_tree->a_nodes[i], NULL,&(residual_edges[n_pruned_nodes]), big_tree); pruned_nodes[n_pruned_nodes] = big_tree->a_nodes[i]; n_pruned_nodes++; } } if(!n_pruned_nodes) { Free(pruned_nodes); Free(residual_edges); return; } Free(big_tree->t_dir); big_tree->n_otu -= n_pruned_nodes; curr_ext_node = 0; curr_int_node = big_tree->n_otu; curr_br = 0; For(i,big_tree->n_otu+n_pruned_nodes) { For(j,n_pruned_nodes) if(!strcmp(pruned_nodes[j]->name,big_tree->a_nodes[i]->name)) break; if(j == n_pruned_nodes) /* That t_node still belongs to the tree */ { Reassign_Node_Nums(big_tree->a_nodes[i],big_tree->a_nodes[i]->v[0], &curr_ext_node,&curr_int_node,big_tree); break; } } Reassign_Edge_Nums(big_tree->a_nodes[0],big_tree->a_nodes[0]->v[0],&curr_br,big_tree); big_tree->t_dir = (short int *)mCalloc((2*big_tree->n_otu-2)*(2*big_tree->n_otu-2),sizeof(short int)); For(i,n_pruned_nodes) { Free_Edge(residual_edges[i]); Free_Edge(pruned_nodes[i]->b[0]); Free_Node(pruned_nodes[i]->v[0]); Free_Node(pruned_nodes[i]); } Free(pruned_nodes); Free(residual_edges); big_tree->a_edges[2*big_tree->n_otu-3] = big_tree->a_edges[2*(big_tree->n_otu+n_pruned_nodes)-3]; big_tree->a_edges[2*big_tree->n_otu-2] = big_tree->a_edges[2*(big_tree->n_otu+n_pruned_nodes)-2]; big_tree->a_nodes[2*big_tree->n_otu-2] = big_tree->a_nodes[2*(big_tree->n_otu+n_pruned_nodes)-2]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* For every node in small_tree, find which node in big_tree it corresponds to and initialize the variable match_node accordingly (vice versa for big_tree) */ void Match_Nodes_In_Small_Tree(t_tree *small_tree, t_tree *big_tree) { int i,j,k,l,m,n,identical; int *score; if(small_tree->n_otu > big_tree->n_otu) { PhyML_Printf("\n. small_tree->n_otu=%d big_tree->n_otu=%d",small_tree->n_otu,big_tree->n_otu); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } Free_Bip(big_tree); Alloc_Bip(big_tree); Get_Bip(big_tree->a_nodes[0],big_tree->a_nodes[0]->v[0],big_tree); Free_Bip(small_tree); Alloc_Bip(small_tree); Get_Bip(small_tree->a_nodes[0],small_tree->a_nodes[0]->v[0],small_tree); if(!Check_Topo_Constraints(big_tree,small_tree)) { PhyML_Printf("\n. small_tree and big_tree cannot have distinct topologies."); PhyML_Printf("\n. Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } For(i,2*small_tree->n_otu-1) small_tree->a_nodes[i]->match_node = NULL; For(i,2*big_tree->n_otu-1) big_tree->a_nodes[i]->match_node = NULL; score = (int *)mCalloc(3,sizeof(int)); For(i,small_tree->n_otu) { For(j,big_tree->n_otu) { if(!strcmp(small_tree->a_nodes[i]->name,big_tree->a_nodes[j]->name)) { small_tree->a_nodes[i]->match_node = big_tree->a_nodes[j]; big_tree->a_nodes[j]->match_node = small_tree->a_nodes[i]; break; } } } For(i,2*small_tree->n_otu-2) { if(small_tree->a_nodes[i]->tax == NO) { For(j,2*big_tree->n_otu-2) { if(big_tree->a_nodes[j]->tax == NO) { For(k,3) score[k] = 0; For(k,3) { For(l,3) { identical = 0; For(m,small_tree->a_nodes[i]->bip_size[k]) { For(n,big_tree->a_nodes[j]->bip_size[l]) { if(!strcmp(small_tree->a_nodes[i]->bip_node[k][m]->name,big_tree->a_nodes[j]->bip_node[l][n]->name)) { identical++; break; } } } if(identical == small_tree->a_nodes[i]->bip_size[k]) { score[k]++; } } } /* printf("\n. [%d] [%d] %d %d %d -- %d %d %d",i,j, */ /* score[0],score[1],score[2], */ /* small_tree->a_nodes[i]->bip_size[0], */ /* small_tree->a_nodes[i]->bip_size[1], */ /* small_tree->a_nodes[i]->bip_size[2]); */ if( score[0] == 1 && score[1] == 1 && score[2] == 1 ) { small_tree->a_nodes[i]->match_node = big_tree->a_nodes[j]; big_tree->a_nodes[j]->match_node = small_tree->a_nodes[i]; break; } } } } } Free(score); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Surviving_Edges_In_Small_Tree(t_tree *small_tree, t_tree *big_tree) { int i; Match_Nodes_In_Small_Tree(small_tree,big_tree); For(i,2*small_tree->n_otu-1) small_tree->rates->has_survived[i] = NO; Find_Surviving_Edges_In_Small_Tree_Post(big_tree->n_root,big_tree->n_root->v[2],small_tree,big_tree); Find_Surviving_Edges_In_Small_Tree_Post(big_tree->n_root,big_tree->n_root->v[1],small_tree,big_tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Find_Surviving_Edges_In_Small_Tree_Post(t_node *a, t_node *d, t_tree *small_tree, t_tree *big_tree) { if(d->match_node && !a->match_node) { small_tree->rates->has_survived[d->match_node->num] = YES; } if(d->tax == YES) return; else { int i; For(i,3) { if(d->v[i] != a && d->b[i] != big_tree->e_root) { Find_Surviving_Edges_In_Small_Tree_Post(d,d->v[i],small_tree,big_tree); } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Taxa_Id_Ranking(t_tree *tree) { int i,j; For(i,tree->n_otu) tree->a_nodes[i]->id_rank = 0; For(i,tree->n_otu) { for(j=i+1;jn_otu;j++) { if(strcmp(tree->a_nodes[i]->name,tree->a_nodes[j]->name) > 0) tree->a_nodes[i]->id_rank++; else tree->a_nodes[j]->id_rank++; } } /* For(i,tree->n_otu) PhyML_Printf("\n. %20s %4d",tree->a_nodes[i]->name,tree->a_nodes[i]->id_rank); */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Edge_Binary_Coding_Number(t_tree *tree) { int i,j; int list_size; t_node **list; t_edge *b; int max_left,max_rght; if(tree->n_otu > 1000) { PhyML_Printf("\n== Can't work out edge binary code if the number of taxa >1000."); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } Free_Bip(tree); Alloc_Bip(tree); Get_Bip(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree); Set_Taxa_Id_Ranking(tree); b = NULL; For(i,2*tree->n_otu-3) { b = tree->a_edges[i]; max_left = 0; For(j,b->left->bip_size[b->l_r]) if(b->left->bip_node[b->l_r][j]->id_rank > max_left) max_left = b->left->bip_node[b->l_r][j]->id_rank; max_rght = 0; For(j,b->rght->bip_size[b->r_l]) if(b->rght->bip_node[b->r_l][j]->id_rank > max_rght) max_rght = b->rght->bip_node[b->r_l][j]->id_rank; if(max_left < max_rght) { list = b->left->bip_node[b->l_r]; list_size = b->left->bip_size[b->l_r]; } else { list = b->rght->bip_node[b->r_l]; list_size = b->rght->bip_size[b->r_l]; } b->bin_cod_num = 0.; For(j,list_size) b->bin_cod_num += POW(2,list[j]->id_rank); /* printf("\n. %f",b->bin_cod_num); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Make_MutMap(t_tree *tree) { // (# of edges) X (# of sites) X (# mutation types: A<->C A<->G A<->T C<->G C<->T G<->T) tree->mutmap = (int *)mCalloc((2*tree->n_otu-3)*(tree->n_pattern)*6,sizeof(int)); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Get_Mutmap_Val(int edge, int site, int mut, t_tree *tree) { int dim1,dim2; dim1 = (tree->n_pattern)*(2*tree->n_otu-3); dim2 = (tree->n_pattern); return tree->mutmap[mut*dim1 + edge*dim2 + site]; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Get_Mutmap_Coord(int idx, int *edge, int *site, int *mut, t_tree *tree) { int dim1,dim2; dim1 = (tree->n_pattern)*(2*tree->n_otu-3); dim2 = (tree->n_pattern); (*mut) = (int)idx/dim1; (*edge) = (int)(idx - (*mut)*dim1)/dim2; (*site) = (int)(idx - (*mut)*dim1 - (*edge)*dim2); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Copy_Edge_Lengths(t_tree *to, t_tree *from) { int i; For(i,2*from->n_otu-1) to->a_edges[i]->l->v = from->a_edges[i]->l->v; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *To_Lower_String(char *in) { char *out; int i; int len; len = (int)strlen(in); out = (char *)mCalloc(len+1,sizeof(char)); For(i,len) out[i] = (char)tolower(in[i]); out[len] = '\0'; return(out); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *To_Upper_String(char *in) { char *out; int i; int len; len = (int)strlen(in); out = (char *)mCalloc(len+1,sizeof(char)); For(i,len) { out[i] = (char)toupper(in[i]); } out[len] = '\0'; return(out); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Connect_CSeqs_To_Nodes(calign *cdata, option *io, t_tree *tree) { int i,j,n_otu_tree,n_otu_cdata; n_otu_tree = tree->n_otu; n_otu_cdata = cdata->n_otu; if((n_otu_tree != n_otu_cdata) && (io->fp_in_constraint_tree == NULL)) { PhyML_Printf("\n== Number of taxa in the tree: %d, number of sequences: %d.",n_otu_tree,n_otu_cdata); Warn_And_Exit("\n== The number of tips in the tree is not the same as the number of sequences\n"); } For(i,MAX(n_otu_tree,n_otu_cdata)) { For(j,MIN(n_otu_tree,n_otu_cdata)) { if(!strcmp(tree->a_nodes[i]->name,cdata->c_seq[j]->name)) break; } if(j==MIN(n_otu_tree,n_otu_cdata)) { PhyML_Printf("\n== Taxon '%s' was not found in sequence file '%s'.\n", tree->a_nodes[i]->name, io->in_align_file); Exit("\n"); } tree->a_nodes[i]->c_seq = cdata->c_seq[j]; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Switch_Eigen(int state, t_mod *mod) { t_mod *buff; buff = mod; do { buff->update_eigen = state; buff = buff->next; if(!buff) break; } while(1); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Both_Sides(int yesno, t_tree *mixt_tree) { t_tree *tree; tree = mixt_tree; do { tree->both_sides = yesno; tree = tree->next; } while(tree); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // Returns the matrix of pairwise distances between tips phydbl *Dist_Btw_Tips(t_tree *tree) { int i,j; phydbl *dist; dist = (phydbl *)mCalloc(tree->n_otu*tree->n_otu,sizeof(phydbl)); Fill_Dir_Table(tree); Update_Dirs(tree); For(i,tree->n_otu-1) { for(j=i+1;jn_otu;j++) { Path_Length(tree->a_nodes[i],tree->a_nodes[j],dist+i*tree->n_otu+j,tree); dist[j*tree->n_otu+i] = dist[i*tree->n_otu+j]; } } return(dist); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Random_SPRs_On_Rooted_Tree(t_tree *tree) { int i,j; t_node *a, *d, *v1, *v2,*target_nd; phydbl u; phydbl lim_sup,lim_inf; t_edge *residual,*nouse; phydbl new_t; int err; int ok_dir,dir12,dir21; /* printf("\n. >>>>>>>>>>>>>>.\n"); */ /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */ /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */ /* printf("\n. >>>>>>>>>>>>>>."); */ /* GEO_Update_Occup(tree->geo,tree); */ /* GEO_Lk(tree->geo,tree); */ /* PhyML_Printf("\n>> Init loglk: %f",tree->geo->c_lnL); */ target_nd = NULL; residual = NULL; nouse = NULL; a = d = v1 = v2 = NULL; For(i,tree->n_otu) // We will perform tree->n_otu random SPRs { a = tree->a_nodes[Rand_Int(tree->n_otu,2*tree->n_otu-3)]; if(a == tree->n_root) { PhyML_Printf("\n== Err. in file %s at line %d (function '%s') \n",__FILE__,__LINE__,__FUNCTION__); Exit("\n"); } /* if(a == tree->n_root->v[1] || a == tree->n_root->v[2]) continue; */ v1 = v2 = NULL; For(j,3) { if(a->v[j] != a->anc && a->b[j] != tree->e_root) { if(!v1) v1 = a->v[j]; else v2 = a->v[j]; } } u = Uni(); if(u < .5) d = v1; else d = v2; For(j,3) if(a->v[j] == d && a->b[j] == tree->e_root) break; if(j != 3) continue; lim_sup = tree->rates->nd_t[d->num]; lim_inf = tree->rates->nd_t[tree->n_root->num]; phydbl scale = Uni()*(50.-5.)+5.; scale = 50; err = NO; new_t = Rnorm_Trunc(tree->rates->nd_t[a->num], FABS(tree->rates->nd_t[tree->n_root->num]/scale), lim_inf, lim_sup, &err); if(err == YES) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); if(new_t < tree->rates->nd_t[a->num]) { target_nd = a; do { if(tree->rates->nd_t[target_nd->anc->num] < new_t) { if(target_nd == a) { if(v1 == d) target_nd = v2; else target_nd = v1; } break; } else { target_nd = target_nd->anc; } } while(1); } else { if(v1 == d) target_nd = v2; else target_nd = v1; do { if(tree->rates->nd_t[target_nd->num] > new_t) { break; } else { v1 = v2 = NULL; For(j,3) { if(target_nd->v[j] != target_nd->anc) { if(!v1) v1 = target_nd->v[j]; else v2 = target_nd->v[j]; } } u = Uni(); if(u < 0.5) target_nd = v1; else target_nd = v2; } }while(1); } ok_dir = -1; For(j,3) if(target_nd->v[j] == target_nd->anc || target_nd->b[j] == tree->e_root) ok_dir = j; dir12 = -1; For(j,3) if(tree->n_root->v[1]->v[j] == tree->n_root->v[2]) dir12 = j; if(dir12 == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); dir21 = -1; For(j,3) if(tree->n_root->v[2]->v[j] == tree->n_root->v[1]) dir21 = j; if(dir21 == -1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /* a = tree->a_nodes[101]; */ /* d = tree->a_nodes[105]; */ /* target_nd = tree->a_nodes[105]; */ /* printf("\n pull %d %d target %d",a->num,d->num,target_nd->num); */ /* printf("\n. %d %d %d",tree->n_root->num,tree->n_root->v[1]->num,tree->n_root->v[2]->num); */ /* printf("\n. %d %d",tree->e_root->num,target_nd->b[ok_dir]->num); */ Prune_Subtree(a,d,&nouse,&residual,tree); Graft_Subtree(target_nd->b[ok_dir],a,residual,tree); tree->rates->nd_t[a->num] = new_t; if(target_nd == tree->n_root->v[1]) { tree->n_root->v[1] = a; tree->e_root = tree->n_root->v[2]->b[dir21]; } if(target_nd == tree->n_root->v[2]) { tree->n_root->v[2] = a; tree->e_root = tree->n_root->v[1]->b[dir12]; } if(tree->n_root->v[1] == NULL) { tree->n_root->v[1] = tree->n_root->v[2]->v[dir21]; tree->e_root = tree->n_root->v[2]->b[dir21]; } if(tree->n_root->v[2] == NULL) { tree->n_root->v[2] = tree->n_root->v[1]->v[dir12]; tree->e_root = tree->n_root->v[1]->b[dir12]; } Update_Ancestors(tree->n_root,tree->n_root->v[2],tree); Update_Ancestors(tree->n_root,tree->n_root->v[1],tree); tree->n_root->anc = NULL; /* Print_Node(tree->n_root,tree->n_root->v[1],tree); */ /* Print_Node(tree->n_root,tree->n_root->v[2],tree); */ Time_To_Branch(tree); /* GEO_Update_Occup(tree->geo,tree); */ /* GEO_Lk(tree->geo,tree); */ /* PhyML_Printf("\nxx Init loglk: %f",tree->geo->c_lnL); */ } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* | | |d / \ / \ / \b / \ / \x (either n_v1 or n_v2) Returns p_lk and sum_scale for subtree with x as root, Pij for edge b */ void Set_P_Lk_One_Side(phydbl **Pij, phydbl **p_lk, int **sum_scale, t_node *d, t_edge *b, t_tree *tree #ifdef BEAGLE , int* child_p_idx, int* Pij_idx #endif ) { if(Pij) { *Pij = b->Pij_rr; #ifdef BEAGLE *Pij_idx = b->Pij_rr_idx; #endif } if(!d->tax)//if d is not a tip { //Does d lie on "left" or "right" of the branch b? if(d == b->left)//If d is on the left of b, then d's neighbor is on the right { *p_lk = b->p_lk_rght; *sum_scale = b->sum_scale_rght; #ifdef BEAGLE *child_p_idx = b->rght->tax? b->p_lk_tip_idx: b->p_lk_rght_idx; #endif } else { *p_lk = b->p_lk_left; *sum_scale = b->sum_scale_left; #ifdef BEAGLE *child_p_idx = b->rght->tax? b->p_lk_tip_idx: b->p_lk_left_idx; #endif } } else { #ifdef BEAGLE Warn_And_Exit(TODO_BEAGLE); #endif *p_lk = NULL; *sum_scale = NULL; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* | | |b | |d / \ / \ / \ / \ /v1 \v2 Set p_lk and sum_scale for subtrees with d, v1 and v2 as root, Pij for edges b, and the two edges connecting d to v1 and d to v2; Account for rooted trees. */ void Set_All_P_Lk(t_node **n_v1, t_node **n_v2, phydbl **p_lk , int **sum_scale , int **p_lk_loc, phydbl **Pij1, phydbl **p_lk_v1, int **sum_scale_v1, phydbl **Pij2, phydbl **p_lk_v2, int **sum_scale_v2, t_node *d, t_edge *b, t_tree *tree #ifdef BEAGLE , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx #endif ) { int i; if(!tree->n_root || tree->ignore_root == YES) { if(tree->n_root && (b == tree->n_root->b[1] || b == tree->n_root->b[2])) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); /* Does d lie on the "left" or "right" of the branch? */ if(d == b->left) { *p_lk = b->p_lk_left; *sum_scale = b->sum_scale_left; *p_lk_loc = b->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = b->p_lk_left_idx; #endif } else { *p_lk = b->p_lk_rght; *sum_scale = b->sum_scale_rght; *p_lk_loc = b->p_lk_loc_rght; #ifdef BEAGLE *dest_p_idx = b->p_lk_rght_idx; #endif } *n_v1 = *n_v2 = NULL; For(i,3)//A node has 3 branches { if(d->b[i] != b)//Skip d's own branch(i.e. the branch coming from d's parent); because we only care about the branches of d's neighbors { if(!(*n_v1))//if we haven't found d's first neighbor { *n_v1 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx); #else Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree); #endif } else if(!(*n_v2))//we found his second neighbor { *n_v2 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx); #else Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree); #endif } else { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } } } else { if(b == tree->e_root) { if(d == tree->n_root->v[1]) b = tree->n_root->b[1]; else if(d == tree->n_root->v[2]) b = tree->n_root->b[2]; else { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } if(d == tree->n_root) { if(b == tree->n_root->b[1]) { *p_lk = tree->n_root->b[1]->p_lk_left; *sum_scale = tree->n_root->b[1]->sum_scale_left; *p_lk_loc = tree->n_root->b[1]->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = tree->n_root->b[1]->p_lk_left_idx; #endif } else { *p_lk = tree->n_root->b[2]->p_lk_left; *sum_scale = tree->n_root->b[2]->sum_scale_left; *p_lk_loc = tree->n_root->b[2]->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = tree->n_root->b[2]->p_lk_left_idx; #endif } *n_v1 = NULL; *Pij1 = NULL; *p_lk_v1 = NULL; *sum_scale_v1 = NULL; if(b == tree->n_root->b[1]) { *n_v2 = tree->n_root->v[2]; *Pij2 = tree->n_root->b[2]->Pij_rr; *p_lk_v2 = tree->n_root->b[2]->p_lk_rght; *sum_scale_v2 = tree->n_root->b[2]->sum_scale_rght; #ifdef BEAGLE *child2_p_idx = tree->n_root->b[2]->p_lk_rght_idx; *Pij2_idx = tree->n_root->b[2]->Pij_rr_idx; #endif } else if(b == tree->n_root->b[2]) { *n_v2 = tree->n_root->v[1]; *Pij2 = tree->n_root->b[1]->Pij_rr; *p_lk_v2 = tree->n_root->b[1]->p_lk_rght; *sum_scale_v2 = tree->n_root->b[1]->sum_scale_rght; #ifdef BEAGLE *child2_p_idx = tree->n_root->b[1]->p_lk_rght_idx; *Pij2_idx = tree->n_root->b[1]->Pij_rr_idx; #endif } else { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } } else if(d == tree->n_root->v[1] || d == tree->n_root->v[2]) { if(b == tree->n_root->b[1] || b == tree->n_root->b[2]) { if(b == tree->n_root->b[1]) { *p_lk = tree->n_root->b[1]->p_lk_rght; *sum_scale = tree->n_root->b[1]->sum_scale_rght; *p_lk_loc = tree->n_root->b[1]->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = tree->n_root->b[1]->p_lk_rght_idx; #endif } else { *p_lk = tree->n_root->b[2]->p_lk_rght; *sum_scale = tree->n_root->b[2]->sum_scale_rght; *p_lk_loc = tree->n_root->b[2]->p_lk_loc_rght; #ifdef BEAGLE *dest_p_idx = tree->n_root->b[2]->p_lk_rght_idx; #endif } *n_v1 = *n_v2 = NULL; For(i,3) { if(d->b[i] != tree->e_root) { if(!(*n_v1)) { *n_v1 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx); #else Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree); #endif } else { *n_v2 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx); #else Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree); #endif } } } } else { if(d == b->left) { *p_lk = b->p_lk_left; *sum_scale = b->sum_scale_left; *p_lk_loc = b->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = b->p_lk_left_idx; #endif } else { *p_lk = b->p_lk_rght; *sum_scale = b->sum_scale_rght; *p_lk_loc = b->p_lk_loc_rght; #ifdef BEAGLE *dest_p_idx = b->p_lk_rght_idx; #endif } *n_v1 = tree->n_root; #ifdef BEAGLE Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d, (d == tree->n_root->v[1])? (tree->n_root->b[1]): (tree->n_root->b[2]), tree,child1_p_idx,Pij1_idx); #else Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d, (d == tree->n_root->v[1])? (tree->n_root->b[1]): (tree->n_root->b[2]), tree); #endif For(i,3) { if(d->b[i] != tree->e_root && d->b[i] != b) { *n_v2 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx); #else Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree); #endif break; } } } } else { if(d == b->left) { *p_lk = b->p_lk_left; *sum_scale = b->sum_scale_left; *p_lk_loc = b->p_lk_loc_left; #ifdef BEAGLE *dest_p_idx = b->p_lk_left_idx; #endif } else { *p_lk = b->p_lk_rght; *sum_scale = b->sum_scale_rght; *p_lk_loc = b->p_lk_loc_rght; #ifdef BEAGLE *dest_p_idx = b->p_lk_rght_idx; #endif } *n_v1 = *n_v2 = NULL; For(i,3) { if(d->b[i] != b) { if(!(*n_v1)) { *n_v1 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree,child1_p_idx,Pij1_idx); #else Set_P_Lk_One_Side(Pij1,p_lk_v1,sum_scale_v1,d,d->b[i],tree); #endif } else { *n_v2 = d->v[i]; #ifdef BEAGLE Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree,child2_p_idx,Pij2_idx); #else Set_P_Lk_One_Side(Pij2,p_lk_v2,sum_scale_v2,d,d->b[i],tree); #endif } } } } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Optimum_Root_Position_IL_Model(t_tree *tree) { if(tree->n_root) { PhyML_Printf("\n== The tree already has a root node"); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } else { int i; t_edge *best_edge; phydbl best_lnL; Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Lk_Rght(tree->a_edges[2*tree->n_otu-2]); Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-3]); Free_Edge_Pars_Rght(tree->a_edges[2*tree->n_otu-2]); best_edge = NULL; best_lnL = UNLIKELY; For(i,2*tree->n_otu-3) { PhyML_Printf("\n. Positionning root node on edge %4d",tree->a_edges[i]->num); Add_Root(tree->a_edges[i],tree); tree->ignore_root = NO; Set_Both_Sides(YES,tree); Lk(NULL,tree); /* Optimize_Br_Len_Serie(tree); */ Update_P_Lk(tree,tree->n_root->b[1],tree->n_root); Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[1],tree); Update_P_Lk(tree,tree->n_root->b[2],tree->n_root); Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[2],tree); PhyML_Printf(" -- lnL: %20f",tree->c_lnL); if(tree->c_lnL > best_lnL) { best_lnL = tree->c_lnL; best_edge = tree->a_edges[i]; } } Add_Root(best_edge,tree); Set_Both_Sides(YES,tree); Lk(NULL,tree); Update_P_Lk(tree,tree->n_root->b[1],tree->n_root); Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[1],tree); Update_P_Lk(tree,tree->n_root->b[2],tree->n_root); Br_Len_Brent(tree->mod->l_min,tree->mod->l_max,tree->n_root->b[2],tree); tree->ignore_root = YES; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Set_Br_Len_Var(t_tree *tree) { if(tree->is_mixt_tree) { MIXT_Set_Br_Len_Var(tree); return; } if(!tree->rates) { int i; phydbl len; For(i,2*tree->n_otu-1) { /* len = MAX(tree->mod->l_min,tree->a_edges[i]->l->v); */ /* len = MIN(tree->mod->l_max,len); */ len = MAX(0.0,tree->a_edges[i]->l->v); tree->a_edges[i]->l_var->v = POW(len,2)*tree->mod->l_var_sigma; } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Check_Br_Lens(t_tree *tree) { int i; scalar_dbl *l; For(i,2*tree->n_otu-1) { l = tree->a_edges[i]->l; do { /* if(l->v < tree->mod->l_min) l->v = tree->mod->l_min; */ /* if(l->v > tree->mod->l_max) l->v = tree->mod->l_max; */ if(l->v < 0.0) l->v = 0.0; l = l->next; } while(l); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree) { calign *orig_data; t_mod *orig_mod; int iter,n_iter_tot,i,j; phydbl *n_diff_states_all_l,*n_diff_states_all_r; Calculate_Number_Of_Diff_States(tree); PhyML_Printf("\n TRUE edge side states val"); For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO) { For(j,tree->mod->ns) { PhyML_Printf("\n TRUE %3d 0 %3d %d", i, j+1, tree->a_edges[i]->n_diff_states_l[j]); PhyML_Printf("\n TRUE %3d 1 %3d %d", i, j+1, tree->a_edges[i]->n_diff_states_r[j]); } } } n_iter_tot = 100; n_diff_states_all_l = (phydbl *)mCalloc((n_iter_tot) * (tree->mod->ns) * (2*tree->n_otu-3) * 2, sizeof(phydbl)); n_diff_states_all_r = (phydbl *)mCalloc((n_iter_tot) * (tree->mod->ns) * (2*tree->n_otu-3) * 2, sizeof(phydbl)); orig_mod = Copy_Model(tree->mod); orig_data = Copy_Cseq(tree->data,tree->io); orig_mod->io = tree->io; orig_mod->s_opt = tree->mod->s_opt; iter = 0; do { Evolve(tree->data,tree->mod,tree); Calculate_Number_Of_Diff_States(tree); For(i,2*tree->n_otu-3) { For(j,tree->mod->ns) { n_diff_states_all_l[j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot) + iter] = tree->a_edges[i]->n_diff_states_l[j]; n_diff_states_all_r[j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot) + iter] = tree->a_edges[i]->n_diff_states_r[j]; } } Free_Cseq(tree->data); Free_Model_Complete(tree->mod); Free_Model_Basic(tree->mod); tree->mod = Copy_Model(orig_mod); tree->data = Copy_Cseq(orig_data,tree->io); tree->mod->io = orig_mod->io; tree->mod->s_opt = orig_mod->s_opt; Connect_CSeqs_To_Nodes(tree->data,tree->io,tree); iter++; } while(iter < n_iter_tot); PhyML_Printf("\n SIM edge side states low up"); For(i,2*tree->n_otu-3) { if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO) { For(j,tree->mod->ns) { PhyML_Printf("\n SIM %3d 0 %3d %.0f %.0f", i, j+1, Quantile(n_diff_states_all_l + j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot), n_iter_tot, 0.10), Quantile(n_diff_states_all_l + j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot), n_iter_tot, 0.90)); PhyML_Printf("\n SIM %3d 1 %3d %.0f %.0f", i, j+1, Quantile(n_diff_states_all_r + j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot), n_iter_tot, 0.10), Quantile(n_diff_states_all_r + j*(2*tree->n_otu-3)*(n_iter_tot) + i*(n_iter_tot), n_iter_tot, 0.90)); } } } Add_Root(tree->a_edges[0],tree); DR_Draw_Tree("treefile",tree); Free(n_diff_states_all_l); Free(n_diff_states_all_r); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Calculate the number of sites at which 1,...,n states (n: 4 or 20) */ /* are observed, for every subtree */ void Calculate_Number_Of_Diff_States(t_tree *tree) { Init_Ui_Tips(tree); Calculate_Number_Of_Diff_States_Post(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree); Calculate_Number_Of_Diff_States_Pre(tree->a_nodes[0],tree->a_nodes[0]->v[0],tree->a_nodes[0]->b[0],tree); /* int i; */ /* For(i,2*tree->n_otu-3) */ /* { */ /* if(tree->a_edges[i]->left->tax == NO && tree->a_edges[i]->rght->tax == NO) */ /* printf("\n. Edge %d left : %d %d %d %d right: %d %d %d %d", */ /* i, */ /* tree->a_edges[i]->n_diff_states_l[0], */ /* tree->a_edges[i]->n_diff_states_l[1], */ /* tree->a_edges[i]->n_diff_states_l[2], */ /* tree->a_edges[i]->n_diff_states_l[3], */ /* tree->a_edges[i]->n_diff_states_r[0], */ /* tree->a_edges[i]->n_diff_states_r[1], */ /* tree->a_edges[i]->n_diff_states_r[2], */ /* tree->a_edges[i]->n_diff_states_r[3]); */ /* } */ } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Calculate_Number_Of_Diff_States_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) Calculate_Number_Of_Diff_States_Post(d,d->v[i],d->b[i],tree); Calculate_Number_Of_Diff_States_Core(a,d,b,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Calculate_Number_Of_Diff_States_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a) { Calculate_Number_Of_Diff_States_Core(d->v[i],d,d->b[i],tree); Calculate_Number_Of_Diff_States_Pre(d,d->v[i],d->b[i],tree); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Calculate_Number_Of_Diff_States_Core(t_node *a, t_node *d, t_edge *b, t_tree *tree) { unsigned int *ui, *ui_v1, *ui_v2; int sum,site,state; int *diff; t_node *v1, *v2; ui = ui_v1 = ui_v2 = NULL; v1 = v2 = NULL; if(d == b->left) { v1 = (d == d->b[b->l_v1]->left)? (d->b[b->l_v1]->rght): (d->b[b->l_v1]->left); v2 = (d == d->b[b->l_v2]->left)? (d->b[b->l_v2]->rght): (d->b[b->l_v2]->left); ui = b->ui_l; diff = b->n_diff_states_l; ui_v1 = (d == d->b[b->l_v1]->left)? (d->b[b->l_v1]->ui_r): (d->b[b->l_v1]->ui_l); ui_v2 = (d == d->b[b->l_v2]->left)? (d->b[b->l_v2]->ui_r): (d->b[b->l_v2]->ui_l); } else { v1 = (d == d->b[b->r_v1]->left)? (d->b[b->r_v1]->rght): (d->b[b->r_v1]->left); v2 = (d == d->b[b->r_v2]->left)? (d->b[b->r_v2]->rght): (d->b[b->r_v2]->left); ui = b->ui_r; diff = b->n_diff_states_r; ui_v1 = (d == d->b[b->r_v1]->left)? (d->b[b->r_v1]->ui_r): (d->b[b->r_v1]->ui_l); ui_v2 = (d == d->b[b->r_v2]->left)? (d->b[b->r_v2]->ui_r): (d->b[b->r_v2]->ui_l); } For(state,tree->mod->ns) diff[state] = 0; For(site,tree->n_pattern) { if(v1->tax == YES) { int sum; sum = Sum_Bits(ui_v1[site],tree->mod->ns); if(sum > 1) { int val = ui_v1[site]; int pos, iter; phydbl u = Uni(); iter = 0; do { pos = Rand_Int(0,tree->mod->ns-1); if(((val >> pos) & 1) && (u > 1./sum)) break; } while(iter++ < 1000); if(iter == 1000) { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } ui_v1[site] = POW(2,pos); } } if(v2->tax == YES) { int sum; sum = Sum_Bits(ui_v2[site],tree->mod->ns); if(sum > 1) { int val = ui_v2[site]; int pos, iter; phydbl u = Uni(); iter = 0; do { pos = Rand_Int(0,tree->mod->ns-1); if(((val >> pos) & 1) && (u > 1./sum)) break; } while(iter++ < 1000); if(iter == 1000) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); ui_v2[site] = POW(2,pos); } } ui[site] = ui_v1[site] | ui_v2[site]; sum = Sum_Bits(ui[site],tree->mod->ns); /* printf("\n. ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */ if(sum-1 > tree->mod->ns-1) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); diff[sum-1]++; } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// /* Returns the number of distinct states observed at a particular site */ int Number_Of_Diff_States_One_Site(int site, t_tree *tree) { int n_states; Number_Of_Diff_States_One_Site_Post(tree->a_nodes[0], tree->a_nodes[0]->v[0], tree->a_nodes[0]->b[0], site,tree); n_states = Sum_Bits(tree->a_nodes[0]->b[0]->ui_r[site] | tree->a_nodes[0]->b[0]->ui_l[site],tree->mod->ns); return(n_states); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void Number_Of_Diff_States_One_Site_Post(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree) { if(d->tax) return; else { int i; For(i,3) if(d->v[i] != a && d->b[i] != tree->e_root) Number_Of_Diff_States_One_Site_Post(d,d->v[i],d->b[i],site,tree); Number_Of_Diff_States_One_Site_Core(a,d,b,site,tree); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int Number_Of_Diff_States_One_Site_Core(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree) { unsigned int *ui, *ui_v1, *ui_v2; int sum; t_node *v1, *v2; ui = ui_v1 = ui_v2 = NULL; v1 = v2 = NULL; if(d == b->left) { v1 = (d == d->b[b->l_v1]->left)? (d->b[b->l_v1]->rght): (d->b[b->l_v1]->left); v2 = (d == d->b[b->l_v2]->left)? (d->b[b->l_v2]->rght): (d->b[b->l_v2]->left); ui = b->ui_l; ui_v1 = (d == d->b[b->l_v1]->left)? (d->b[b->l_v1]->ui_r): (d->b[b->l_v1]->ui_l); ui_v2 = (d == d->b[b->l_v2]->left)? (d->b[b->l_v2]->ui_r): (d->b[b->l_v2]->ui_l); } else { v1 = (d == d->b[b->r_v1]->left)? (d->b[b->r_v1]->rght): (d->b[b->r_v1]->left); v2 = (d == d->b[b->r_v2]->left)? (d->b[b->r_v2]->rght): (d->b[b->r_v2]->left); ui = b->ui_r; ui_v1 = (d == d->b[b->r_v1]->left)? (d->b[b->r_v1]->ui_r): (d->b[b->r_v1]->ui_l); ui_v2 = (d == d->b[b->r_v2]->left)? (d->b[b->r_v2]->ui_r): (d->b[b->r_v2]->ui_l); } if(v1->tax == YES) // Check for ambiguous character state at this tip { sum = Sum_Bits(ui_v1[site],tree->mod->ns); if(sum > 1) { int val = ui_v1[site]; int pos, iter; phydbl u = Uni(); // Select a state uniformly at random iter = 0; do { pos = Rand_Int(0,tree->mod->ns-1); if(((val >> pos) & 1) && (u > 1./sum)) break; } while(iter++ < 1000); if(iter == 1000) { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } ui_v1[site] = POW(2,pos); } } if(v2->tax == YES) { sum = Sum_Bits(ui_v2[site],tree->mod->ns); if(sum > 1) { int val = ui_v2[site]; int pos, iter; phydbl u = Uni(); iter = 0; do { pos = Rand_Int(0,tree->mod->ns-1); if(((val >> pos) & 1) && (u > 1./sum)) break; } while(iter++ < 1000); if(iter == 1000) Generic_Exit(__FILE__,__LINE__,__FUNCTION__); ui_v2[site] = POW(2,pos); } } ui[site] = ui_v1[site] | ui_v2[site]; sum = Sum_Bits(ui[site],tree->mod->ns); /* printf("\n. ui_v1: %d ui_v2: %d ui: %d sum: %d",ui_v1[site],ui_v2[site],ui[site],sum); fflush(NULL); */ if(sum-1 > tree->mod->ns-1) { Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } return sum; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phydbl Get_Lk(t_tree *tree) { t_tree *loc_tree; loc_tree = tree; /*! Rewind back to the first mixt_tree */ while(loc_tree->prev) loc_tree = loc_tree->prev; return loc_tree->c_lnL; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ align **Make_Empty_Alignment(option *io) { int i; char *line; align **data; line = (char *)mCalloc(T_MAX_LINE,sizeof(char)); data = (align **)mCalloc(io->n_otu,sizeof(align *)); For(i,io->n_otu) { data[i] = (align *)mCalloc(1,sizeof(align)); data[i]->name = (char *)mCalloc(T_MAX_NAME,sizeof(char)); data[i]->state = (char *)mCalloc(io->init_len*io->state_len+1,sizeof(char)); data[i]->is_ambigu = NULL; data[i]->len = 0; Random_String(data[i]->name,5); while(data[i]->len < io->init_len * io->state_len) { data[i]->state[data[i]->len] = 'X'; data[i]->len++; } } For(i,io->n_otu) data[i]->state[data[i]->len] = '\0'; Free(line); return data; } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ /* Mean observed frequency of difference between the n(n-1)/2 pairs of sequences */ phydbl Mean_Identity(calign *data) { int i,j,n; phydbl tot_idt; n = data->n_otu; tot_idt = 0.0; For(i,n-1) { for(j=i+1; jcrunch_len) if(data->c_seq[i]->state[k] == data->c_seq[j]->state[k]) div += (phydbl)data->wght[k]; /* observed proportion of identity */ p = 1. - div / (phydbl)data->init_len; d = 0.0; if(data->io->datatype == NT) { if(p > 3./4.) return 0.25; else { /* Jukes & Cantor distance */ d = -(3./4.)*LOG(1. - 4./3.*p); } } else if(data->io->datatype == AA) { if(p > 19./20.) return 1./20.; else { /* Jukes & Cantor distance */ d = -(19./20.)*LOG(1. - 20./19.*p); } } else Generic_Exit(__FILE__,__LINE__,__FUNCTION__); return(EXP(-d)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Fst(int i, int j, calign *data) { phydbl FA, Fr; FA = Mean_Identity(data); Fr = Pairwise_Identity(i,j,data); return((Fr-FA)/(1-FA)); } /*//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////*/ phydbl Nucleotide_Diversity(calign *data) { int i,j,n; phydbl pair_div; n = data->n_otu; pair_div = 0.0; For(i,n-1) { for(j=i+1; j #ifndef UTILITIES_H #define UTILITIES_H #include #include #include #include #include #include #include #include #include #include #include #include extern int n_sec1; extern int n_sec2; #define For(i,n) for(i=0; i 0.0 ? fabs(a) : -fabs(a)) #define SHFT(a,b,c,d) (a)=(b);(b)=(c);(c)=(d); #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #endif #define READ 0 #define WRITE 1 #ifndef isnan # define isnan(x) \ (sizeof (x) == sizeof (long double) ? isnan_ld (x) \ : sizeof (x) == sizeof (double) ? isnan_d (x) \ : isnan_f (x)) static inline int isnan_f (float x) { return x != x; } static inline int isnan_d (double x) { return x != x; } static inline int isnan_ld (long double x) { return x != x; } #endif #ifndef isinf # define isinf(x) \ (sizeof (x) == sizeof (long double) ? isinf_ld (x) \ : sizeof (x) == sizeof (double) ? isinf_d (x) \ : isinf_f (x)) static inline int isinf_f (float x) { return isnan (x - x); } static inline int isinf_d (double x) { return isnan (x - x); } static inline int isinf_ld (long double x) { return isnan (x - x); } #endif #define AC 0 #define AG 1 #define AT 2 #define CG 3 #define CT 4 #define GT 5 #ifndef M_1_SQRT_2PI #define M_1_SQRT_2PI 0.398942280401432677939946059934 /* 1/sqrt(2pi) */ #endif #define T_MAX_MCMC_MOVE_NAME 500 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 800 #define RR_MIN 0.01 #define RR_MAX 200.0 #define PHYREX_UNIFORM 0 #define PHYREX_NORMAL 1 #define MCMC_MOVE_RANDWALK_UNIFORM 0 #define MCMC_MOVE_LOG_RANDWALK_UNIFORM 1 #define MCMC_MOVE_RANDWALK_NORMAL 2 #define MCMC_MOVE_LOG_RANDWALK_NORMAL 3 #define MCMC_MOVE_SCALE_THORNE 4 #define MCMC_MOVE_SCALE_GAMMA 5 #define N_MAX_MOVES 50 #define N_MAX_NEX_COM 20 #define T_MAX_NEX_COM 100 #define N_MAX_NEX_PARM 50 #define T_MAX_TOKEN 200 #define T_MAX_ID_COORD 5 #define T_MAX_ID_DISK 5 #define N_MAX_MIXT_CLASSES 1000 #define NEXUS_COM 0 #define NEXUS_PARM 1 #define NEXUS_EQUAL 2 #define NEXUS_VALUE 3 #define NEXUS_SPACE 4 #define NNI_MOVE 0 #define SPR_MOVE 1 #define BEST_OF_NNI_AND_SPR 2 #define M_1_SQRT_2_PI 0.398942280401432677939946059934 #define M_SQRT_32 5.656854249492380195206754896838 #define PI 3.14159265358979311600 #define SQRT2PI 2.50662827463100024161 #define LOG2PI 1.83787706640934533908 #define LOG2 0.69314718055994528623 #define LOG_SQRT_2_PI 0.918938533204672741780329736406 #define NORMAL 1 #define EXACT 2 #define PHYLIP 0 #define NEXUS 1 #ifndef YES #define YES 1 #endif #ifndef NO #define NO 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define ON 1 #define OFF 0 #define SMALL_DBL 1.E-20 #define NT 0 /*! nucleotides */ #define AA 1 /*! amino acids */ #define GENERIC 2 /*! custom alphabet */ #define UNDEFINED -1 #define ACGT 0 /*! A,G,G,T encoding */ #define RY 1 /*! R,Y encoding */ #define INTERFACE_DATA_TYPE 0 #define INTERFACE_MULTIGENE 1 #define INTERFACE_MODEL 2 #define INTERFACE_TOPO_SEARCH 3 #define INTERFACE_BRANCH_SUPPORT 4 #define LEFT 0 #define RGHT 1 #ifndef INFINITY #define INFINITY HUGE #endif #define N_MAX_OPTIONS 100 #define NEXT_BLOCK_SIZE 50 #define T_MAX_FILE 200 #define T_MAX_LINE 2000000 #define T_MAX_NAME 100 #define T_MAX_ID 20 #define T_MAX_SEQ 2000000 #define T_MAX_OPTION 100 #define T_MAX_LABEL 10 #define T_MAX_STATE 5 #define N_MAX_LABEL 10 #define BLOCK_LABELS 100 #define NODE_DEG_MAX 500 #define BRENT_IT_MAX 500 #define BRENT_CGOLD 0.3819660 #define BRENT_ZEPS 1.e-10 #define MNBRAK_GOLD 1.618034 #define MNBRAK_GLIMIT 100.0 #define MNBRAK_TINY 1.e-20 #define ALPHA_MIN 0.04 #define ALPHA_MAX 100 #define BL_START 1.e-04 #define GOLDEN_R 0.61803399 #define GOLDEN_C (1.0-GOLDEN_R) #define N_MAX_INSERT 20 #define N_MAX_OTU 4000 #define UNLIKELY -1.e10 #define NJ_SEUIL 0.1 #define ROUND_MAX 100 #define DIST_MAX 2.00 #define AROUND_LK 50.0 #define PROP_STEP 1.0 #define T_MAX_ALPHABET 22 #define MDBL_MIN FLT_MIN #define MDBL_MAX FLT_MAX #define POWELL_ITMAX 200 #define LINMIN_TOL 2.0E-04 #define SCALE_POW 10 /*! Scaling factor will be 2^SCALE_POW or 2^(-SCALE_POW) [[ WARNING: SCALE_POW < 31 ]]*/ #define DEFAULT_SIZE_SPR_LIST 20 #define NEWICK 0 #define NEXUS 1 #define OUTPUT_TREE_FORMAT NEWICK #define MAX_PARS 1000000000 #define LIM_SCALE_VAL 1.E-50 /*! Scaling limit (deprecated) */ #define MIN_CLOCK_RATE 1.E-10 #define MIN_VAR_BL 1.E-8 #define MAX_VAR_BL 1.E+3 #define JC69 1 #define K80 2 #define F81 3 #define HKY85 4 #define F84 5 #define TN93 6 #define GTR 7 #define CUSTOM 8 #define WAG 11 #define DAYHOFF 12 #define JTT 13 #define BLOSUM62 14 #define MTREV 15 #define RTREV 16 #define CPREV 17 #define DCMUT 18 #define VT 19 #define MTMAM 20 #define MTART 21 #define HIVW 22 #define HIVB 23 #define FLU 24 #define CUSTOMAA 25 #define LG 26 #define AB 27 // Amino acid ordering: // Ala Arg Asn Asp Cys Gln Glu Gly His Ile Leu Lys Met Phe Pro Ser Thr Trp Tyr Val #define COMPOUND_COR 0 #define COMPOUND_NOCOR 1 #define EXPONENTIAL 2 #define GAMMA 3 #define THORNE 4 #define GUINDON 5 #define STRICTCLOCK 6 #define NONE -1 #define ALRTSTAT 1 #define ALRTCHI2 2 #define MINALRTCHI2SH 3 #define SH 4 #define ABAYES 5 /* /\* Uncomment the lines below to switch to single precision *\/ */ /* typedef float phydbl; */ /* #define LOG logf */ /* #define POW powf */ /* #define EXP expf */ /* #define FABS fabsf */ /* #define SQRT sqrtf */ /* #define CEIL ceilf */ /* #define FLOOR floorf */ /* #define RINT rintf */ /* #define ROUND roundf */ /* #define TRUNC truncf */ /* #define COS cosf */ /* #define SIN sinf */ /* #define TAN tanf */ /* #define SMALL FLT_MIN */ /* #define BIG FLT_MAX */ /* #define SMALL_PIJ 1.E-10 */ /* #define BL_MIN 1.E-5 */ /* #define P_LK_LIM_INF 2.168404e-19 /\* 2^-62 *\/ */ /* #define P_LK_LIM_SUP 4.611686e+18 /\* 2^62 *\/ */ /* Uncomment the line below to switch to double precision */ typedef double phydbl; #define LOG log #define POW pow #define EXP exp #define FABS fabs #define SQRT sqrt #define CEIL ceil #define FLOOR floor #define RINT rint #define ROUND round #define TRUNC trunc #define COS cos #define SIN sin #define TAN tan #define SMALL DBL_MIN #define BIG DBL_MAX #define SMALL_PIJ 1.E-20 #define LOGBIG 690. #define LOGSMALL -690. #if !(defined PHYTIME || defined SERGEII) #define BL_MIN 1.E-8 #define BL_MAX 100. #else #define BL_MIN 1.E-6 #define BL_MAX 1. #endif /* #define P_LK_LIM_INF 7.888609052e-31 */ /* #define P_LK_LIM_MAX 1.267650600e+30 */ /* #define P_LK_LIM_INF 4.909093465e-91 /\* R: format(2^(-300),digits=10) *\/ */ /* #define P_LK_LIM_SUP 2.037035976e+90 /\* R: format(2^(+300),digits=10) *\/ */ #define P_LK_LIM_INF 3.054936e-151 /* 2^-500 */ #define P_LK_LIM_SUP 3.273391e+150 /* 2^500 */ //#define P_LK_LIM_INF 4.656612873e-10 /*2^-31 */ #define T_MAX_XML_TAG 64 #define NARGS_SEQ(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N #define NARGS(...) NARGS_SEQ(__VA_ARGS__, 8, 7, 6, 5, 4, 3, 2, 1) #define PRIMITIVE_CAT(x, y) x ## y #define CAT(x, y) PRIMITIVE_CAT(x, y) #define FOR_EACH(macro, ...) CAT(FOR_EACH_, NARGS(__VA_ARGS__))(macro, __VA_ARGS__) #define FOR_EACH_1(m, x1) m(x1) #define FOR_EACH_2(m, x1, x2) m(x1) m(x2) #define FOR_EACH_3(m, x1, x2, x3) m(x1) m(x2) m(x3) #define FOR_EACH_4(m, x1, x2, x3, x4) m(x1) m(x2) m(x3) m(x4) #define FOR_EACH_5(m, x1, x2, x3, x4, x5) m(x1) m(x2) m(x3) m(x4) m(x5) #define FOR_EACH_6(m, x1, x2, x3, x4, x5, x6) m(x1) m(x2) m(x3) m(x4) m(x5) m(x6) #define FOR_EACH_7(m, x1, x2, x3, x4, x5, x6, x7) m(x1) m(x2) m(x3) m(x4) m(x5) m(x6) m(x7) #define FOR_EACH_8(m, x1, x2, x3, x4, x5, x6, x7, x8) m(x1) m(x2) m(x3) m(x4) m(x5) m(x6) m(x7) m(x8) #define DUMP_EACH_INT(v) fprintf(stderr,"\n\t\tDEBUG:%s:\t\t%s--->%i",__PRETTY_FUNCTION__,#v,(v));fflush(stderr); #define DUMP_EACH_STRING(v) fprintf(stderr,"\n\t\tDEBUG:%s:\t\t%s--->%s",__PRETTY_FUNCTION__,#v,(v));fflush(stderr); #define DUMP_EACH_DECIMAL(v) fprintf(stderr,"\n\t\tDEBUG:%s:\t\t%s--->%f",__PRETTY_FUNCTION__,#v,(v));fflush(stderr); #define DUMP_EACH_SCI(v) fprintf(stderr,"\n\t\tDEBUG:%s:\t\t%s--->%e",__PRETTY_FUNCTION__,#v,(v));fflush(stderr); #define DUMP_I(...) FOR_EACH(DUMP_EACH_INT, __VA_ARGS__) #define DUMP_S(...) FOR_EACH(DUMP_EACH_STRING, __VA_ARGS__) #define DUMP_D(...) FOR_EACH(DUMP_EACH_DECIMAL, __VA_ARGS__) #define DUMP_E(...) FOR_EACH(DUMP_EACH_SCI, __VA_ARGS__) /*!********************************************************/ typedef struct __Scalar_Int { int v; struct __Scalar_Int *next; struct __Scalar_Int *prev; }scalar_int; /*!********************************************************/ typedef struct __Scalar_Dbl { phydbl v; bool onoff; struct __Scalar_Dbl *next; struct __Scalar_Dbl *prev; }scalar_dbl; /*!********************************************************/ typedef struct __Vect_Int { int *v; int len; struct __Vect_Int *next; struct __Vect_Int *prev; }vect_int; /*!********************************************************/ typedef struct __Vect_Dbl { phydbl *v; int len; struct __Vect_Dbl *next; struct __Vect_Dbl *prev; }vect_dbl; /*!********************************************************/ typedef struct __String { char *s; int len; struct __String *next; struct __String *prev; }t_string; /*!********************************************************/ typedef struct __Node { struct __Node **v; /*! table of pointers to neighbor nodes. Dimension = 3 */ struct __Node ***bip_node; /*! three lists of pointer to tip nodes. One list for each direction */ struct __Edge **b; /*! table of pointers to neighbor branches */ struct __Node *anc; /*! direct ancestor t_node (for rooted tree only) */ struct __Node *ext_node; struct __Node *match_node; struct __Align *c_seq; /*! corresponding compressed sequence */ struct __Align *c_seq_anc; /*! corresponding compressed ancestral sequence */ struct __Node *next; /*! tree->a_nodes[i]->next <=> tree->next->a_nodes[i] */ struct __Node *prev; /*! See above */ struct __Node *next_mixt; /*! Next mixture tree*/ struct __Node *prev_mixt; /*! Parent mixture tree */ struct __Calibration **calib; short int *calib_applies_to; int n_calib; int *bip_size; /*! Size of each of the three lists from bip_node */ int num; /*! t_node number */ int tax; /*! tax = 1 -> external node, else -> internal t_node */ int check_branch; /*! check_branch=1 is the corresponding branch is labelled with '*' */ char *name; /*! taxon name (if exists) */ char *ori_name; /*! taxon name (if exists) */ phydbl *score; /*! score used in BioNJ to determine the best pair of nodes to agglomerate */ phydbl *l; /*! lengths of the (three or one) branche(s) connected this t_node */ phydbl dist_to_root; /*! distance to the root t_node */ short int common; phydbl y_rank; phydbl y_rank_ori; phydbl y_rank_min; phydbl y_rank_max; int *s_ingrp; /*! does the subtree beneath belong to the ingroup */ int *s_outgrp; /*! does the subtree beneath belong to the outgroup */ int id_rank; /*! order taxa alphabetically and use id_rank to store the ranks */ int rank; int rank_max; struct __Geo_Coord *coord; }t_node; /*!********************************************************/ typedef struct __Edge { /*! syntax : (node) [edge] (left_1) . .(right_1) \ (left) (right) / \._____________./ / [b_fcus] \ / \ (left_2) . .(right_2) */ struct __Node *left,*rght; /*! t_node on the left/right side of the t_edge */ short int l_r,r_l,l_v1,l_v2,r_v1,r_v2; /*! these are directions (i.e., 0, 1 or 2): */ /*! l_r (left to right) -> left[b_fcus->l_r] = right */ /*! r_l (right to left) -> right[b_fcus->r_l] = left */ /*! l_v1 (left t_node to first t_node != from right) -> left[b_fcus->l_v1] = left_1 */ /*! l_v2 (left t_node to secnd t_node != from right) -> left[b_fcus->l_v2] = left_2 */ /*! r_v1 (right t_node to first t_node != from left) -> right[b_fcus->r_v1] = right_1 */ /*! r_v2 (right t_node to secnd t_node != from left) -> right[b_fcus->r_v2] = right_2 */ struct __NNI *nni; struct __Edge *next; struct __Edge *prev; struct __Edge *next_mixt; struct __Edge *prev_mixt; int num; /*! branch number */ scalar_dbl *l; /*! branch length */ scalar_dbl *best_l; /*! best branch length found so far */ scalar_dbl *l_old; /*! old branch length */ scalar_dbl *l_var; /*! variance of edge length */ scalar_dbl *l_var_old; /*! variance of edge length (previous value) */ int bip_score; /*! score of the bipartition generated by the corresponding edge bip_score = 1 iif the branch is found in both trees to be compared, bip_score = 0 otherwise. */ phydbl *p_lk_left,*p_lk_rght; /*! likelihoods of the subtree on the left and right side (for each site and each relative rate category) */ short int *p_lk_tip_r, *p_lk_tip_l; #ifdef BEAGLE int p_lk_left_idx, p_lk_rght_idx; int p_lk_tip_idx; #endif short int *div_post_pred_left; /*! posterior prediction of nucleotide/aa diversity (left-hand subtree) */ short int *div_post_pred_rght; /*! posterior prediction of nucleotide/aa diversity (rght-hand subtree) */ short int does_exist; int *patt_id_left; int *patt_id_rght; int *p_lk_loc_left; int *p_lk_loc_rght; phydbl *Pij_rr; /*! matrix of change probabilities and its first and secnd derivates (rate*state*state) */ #ifdef BEAGLE int Pij_rr_idx; #endif int *pars_l,*pars_r; /*! parsimony of the subtree on the left and right sides (for each site) */ unsigned int *ui_l, *ui_r; /*! union - intersection vectors used in Fitch's parsimony algorithm */ int *p_pars_l, *p_pars_r; /*! conditional parsimony vectors */ int num_st_left; /*! number of the subtree on the left side */ int num_st_rght; /*! number of the subtree on the right side */ /*! Below are the likelihood scaling factors (used in functions `Get_All_Partial_Lk_Scale' in lk.c. */ /* For every site, every subtree and every rate class, PhyML maintains a`sum_scale_pow' value where sum_scale_pow = sum_scale_pow_v1 + sum_scale_pow_v2 + curr_scale_pow' sum_scale_pow_v1 and sum_scale_pow_v2 are sum_scale_pow of the left and right subtrees. curr_scale_pow is an integer greater than one. The smaller the partials, the larger curr_scale_pow. Now the partials for this subtree are scaled by *multiplying* each of them by 2^curr_scale_pow. The reason for doing the scaling this way is that multiplications by 2^x (x an integer) can be done in an 'exact' manner (i.e., there is no loss of numerical precision) At the root edge, the log-likelihood is then logL = logL' - (sum_scale_pow_left + sum_scale_pow_right)log(2), where L' is the scaled likelihood. */ int *sum_scale_left_cat; int *sum_scale_rght_cat; int *sum_scale_left; int *sum_scale_rght; phydbl bootval; /*! bootstrap value (if exists) */ short int is_alive; /*! is_alive = 1 if this t_edge is used in a tree */ phydbl dist_btw_edges; int topo_dist_btw_edges; int has_zero_br_len; phydbl ratio_test; /*! approximate likelihood ratio test */ phydbl alrt_statistic; /*! aLRT statistic */ char **labels; /*! string of characters that labels the corresponding t_edge */ int n_labels; /*! number of labels */ int n_jumps; /*! number of jumps of substitution rates */ int *n_diff_states_l; /*! Number of different states found in the subtree on the left of this edge */ int *n_diff_states_r; /*! Number of different states found in the subtree on the right of this edge */ phydbl bin_cod_num; }t_edge; /*!********************************************************/ typedef struct __Tree{ struct __Node *n_root; /*! root t_node */ struct __Edge *e_root; /*! t_edge on which lies the root */ struct __Node **a_nodes; /*! array of nodes that defines the tree topology */ struct __Edge **a_edges; /*! array of edges */ struct __Model *mod; /*! substitution model */ struct __Calign *data; /*! sequences */ struct __Tree *next; /*! set to NULL by default. Used for mixture models */ struct __Tree *prev; /*! set to NULL by default. Used for mixture models */ struct __Tree *next_mixt; /*! set to NULL by default. Used for mixture models */ struct __Tree *prev_mixt; /*! set to NULL by default. Used for mixture models */ struct __Tree *mixt_tree; /*! set to NULL by default. Used for mixture models */ struct __Option *io; /*! input/output */ struct __Matrix *mat; /*! pairwise distance matrix */ struct __Node **curr_path; /*! list of nodes that form a path in the tree */ struct __SPR **spr_list; struct __SPR *best_spr; struct __Tdraw *ps_tree; /*! structure for drawing trees in postscript format */ struct __T_Rate *rates; /*! structure for handling rates of evolution */ struct __Tmcmc *mcmc; struct __Triplet *triplet_struct; struct __Phylogeo *geo; struct __Migrep_Model *mmod; struct __Disk_Event *disk; int is_mixt_tree; int tree_num; /*! tree number. Used for mixture models */ int ps_page_number; /*! when multiple trees are printed, this variable give the current page number */ int depth_curr_path; /*! depth of the t_node path defined by curr_path */ int has_bip; /*!if has_bip=1, then the structure to compare tree topologies is allocated, has_bip=0 otherwise */ int n_otu; /*! number of taxa */ int curr_site; /*! current site of the alignment to be processed */ int curr_catg; /*! current class of the discrete gamma rate distribution */ int n_swap; /*! number of NNIs performed */ int n_pattern; /*! number of distinct site patterns */ int has_branch_lengths; /*! =1 iff input tree displays branch lengths */ int print_boot_val; /*! if print_boot_val=1, the bootstrap values are printed */ int print_alrt_val; /*! if print_boot_val=1, the aLRT values are printed */ int both_sides; /*! both_sides=1 -> a pre-order and a post-order tree traversals are required to compute the likelihood of every subtree in the phylogeny*/ int num_curr_branch_available; /*!gives the number of the next cell in a_edges that is free to receive a pointer to a branch */ short int *t_dir; int n_improvements; int n_moves; int dp; /*! Data partition */ int s_mod_num; /*! Substitution model number */ int lock_topo; /*! = 1 any subsequent topological modification will be banished */ int write_labels; int write_br_lens; int *mutmap; /*! Mutational map */ phydbl init_lnL; phydbl best_lnL; /*! highest value of the loglikelihood found so far */ int best_pars; /*! highest value of the parsimony found so far */ phydbl c_lnL; /*! loglikelihood */ phydbl old_lnL; /*! old loglikelihood */ phydbl sum_min_sum_scale; /*! common factor of scaling factors */ phydbl *c_lnL_sorted; /*! used to compute c_lnL by adding sorted terms to minimize CPU errors */ phydbl *cur_site_lk; /*! vector of loglikelihoods at individual sites */ phydbl *old_site_lk; /*! vector of likelihoods at individual sites */ phydbl annealing_temp; /*! annealing temperature in simulated annealing optimization algo */ phydbl *unscaled_site_lk_cat; /*! partially scaled site likelihood at individual sites */ phydbl *site_lk_cat; /*! loglikelihood at a single site and for each class of rate*/ phydbl unconstraint_lk; /*! unconstrained (or multinomial) likelihood */ int *fact_sum_scale; phydbl **log_lks_aLRT; /*! used to compute several branch supports */ phydbl n_root_pos; /*! position of the root on its t_edge */ phydbl size; /*! tree size */ int *site_pars; int c_pars; int *step_mat; int size_spr_list; int perform_spr_right_away; time_t t_beg; time_t t_current; int bl_from_node_stamps; /*! == 1 -> Branch lengths are determined by t_node times */ phydbl sum_y_dist_sq; phydbl sum_y_dist; phydbl tip_order_score; int write_tax_names; int update_alias_subpatt; phydbl geo_mig_sd; /*! standard deviation of the migration step random variable */ phydbl geo_lnL; /*! log likelihood of the phylo-geography model */ int bl_ndigits; phydbl *short_l; /*! Vector of short branch length values */ int n_short_l; /*! Length of short_l */ phydbl norm_scale; short int br_len_recorded; int max_spr_depth; short int apply_lk_scaling; /*! Applying scaling of likelihoods. YES/NO */ phydbl *K; /*! a vector of the norm.constants for the node times prior. */ short int ignore_root; #ifdef BEAGLE int b_inst; /*! The BEAGLE instance id associated with this tree. */ #endif }t_tree; /*!********************************************************/ typedef struct __Super_Tree { struct __Tree *tree; struct __List_Tree *treelist; /*! list of trees. One tree for each data set to be processed */ struct __Calign *curr_cdata; struct __Option **optionlist; /*! list of pointers to input structures (used in supertrees) */ struct __Node ***match_st_node_in_gt; /*! match_st_in_gt_node[subdataset number][supertree t_node number] * gives the t_node in tree estimated from 'subdataset number' that corresponds * to 'supertree t_node number' in the supertree */ struct __Node *****map_st_node_in_gt; /*! mat_st_gt_node[gt_num][st_node_num][direction] gives the * t_node in gt gt_num that maps t_node st_node_num in st. */ struct __Edge ***map_st_edge_in_gt; /*! map_st_gt_br[gt_num][st_branch_num] gives the * branch in gt gt_num that maps branch st_branch_num * in st. */ struct __Edge ****map_gt_edge_in_st; /*! mat_gt_st_br[gt_num][gt_branch_num][] is the list of * branches in st that map branch gt_branch_num * in gt gt_num. */ int **size_map_gt_edge_in_st; /*! size_map_gt_st_br[gt_num][gt_branch_num] gives the * size of the list map_gt_st_br[gt_num][gt_branch_num][] */ struct __Edge ***match_st_edge_in_gt; /*! match_st_edge_in_gt[gt_num][st_branch_num] gives the * branch in gt gt_num that matches branch st_branch_num */ struct __Edge ***match_gt_edge_in_st; /*! match_gt_edge_in_st[gt_num][gt_branch_num] gives the * branch in st that matches branch gt_branch_num */ struct __Node ****closest_match; /*! closest_match[gt_num][st_node_num][dir] gives the * closest t_node in st that matches a t_node in gt gt_num */ int ***closest_dist; /*! closest_dist[gt_num][st_node_num][dir] gives the * number of edges to traverse to get to node * closest_match[gt_num][st_node_num][dir] */ int n_part; /*! number of trees */ phydbl **bl; /*! bl[gt_num][gt_branch_num] gives the length of * branch gt_branch_num */ phydbl **bl_cpy; /*! copy of bl */ phydbl **bl0; /*! bl estimated during NNI (original topo) * See Mg_NNI. */ phydbl **bl1; /*! bl estimated during NNI (topo conf 1) * See Mg_NNI. */ phydbl **bl2; /*! bl estimated during NNI (topo conf 2) * See Mg_NNI. */ int *bl_partition; /*! partition[gt_num] gives the t_edge partition number * gt_num belongs to. */ int n_bl_part; struct __Model **s_mod; /*! substitution model */ int n_s_mod; int lock_br_len; }supert_tree; /*!********************************************************/ typedef struct __List_Tree { /*! a list of trees */ struct __Tree **tree; int list_size; /*! number of trees in the list */ }t_treelist; /*!********************************************************/ typedef struct __Align { char *name; /*! sequence name */ int len; /*! sequence length */ char *state; /*! sequence itself */ int *d_state; /*! sequence itself (digits) */ short int *is_ambigu; /*! is_ambigu[site] = 1 if state[site] is an ambiguous character. 0 otherwise */ }align; /*!********************************************************/ typedef struct __Calign { struct __Align **c_seq; /*! compressed sequences */ struct __Option *io; /*! input/output */ phydbl *b_frq; /*! observed state frequencies */ short int *invar; /*! < 0 -> polymorphism observed */ int *wght; /*! # of each site in c_align */ short int *ambigu; /*! ambigu[i]=1 is one or more of the sequences at site i display an ambiguous character */ phydbl obs_pinvar; int n_otu; /*! number of taxa */ int clean_len; /*! uncrunched sequences lenghts without gaps */ int crunch_len; /*! crunched sequences lengths */ int init_len; /*! length of the uncompressed sequences */ int *sitepatt; /*! this array maps the position of the patterns in the compressed alignment to the positions in the uncompressed one */ int format; /*! 0 (default): PHYLIP. 1: NEXUS. */ }calign; /*!********************************************************/ typedef struct __Matrix { /*! mostly used in BIONJ */ phydbl **P,**Q,**dist; /*! observed proportions of transition, transverion and distances between pairs of sequences */ t_tree *tree; /*! tree... */ int *on_off; /*! on_off[i]=1 if column/line i corresponds to a t_node that has not been agglomerated yet */ int n_otu; /*! number of taxa */ char **name; /*! sequence names */ int r; /*! number of nodes that have not been agglomerated yet */ struct __Node **tip_node; /*! array of pointer to the leaves of the tree */ int curr_int; /*! used in the NJ/BIONJ algorithms */ int method; /*! if method=1->NJ method is used, BIONJ otherwise */ }matrix; /*!********************************************************/ typedef struct __RateMatrix { int n_diff_rr; /*! number of different relative substitution rates in the custom model */ vect_dbl *rr; /*! relative rate parameters of the GTR or custom model (given by rr_val[rr_num[i]]) */ vect_dbl *rr_val; /*! relative rate parameters of the GTR or custom model */ vect_int *rr_num; vect_int *n_rr_per_cat; /*! number of rate parameters in each category */ vect_dbl *qmat; vect_dbl *qmat_buff; struct __RateMatrix *next; struct __RateMatrix *prev; }t_rmat; /*!********************************************************/ typedef struct __RAS { /*! Rate across sites */ int n_catg; /*! number of categories in the discrete gamma distribution */ int invar; /*! =1 iff the substitution model takes into account invariable sites */ int gamma_median; /*! 1: use the median of each bin in the discrete gamma distribution. 0: the mean is used */ vect_dbl *gamma_r_proba; /*! probabilities of the substitution rates defined by the discrete gamma distribution */ vect_dbl *gamma_r_proba_unscaled; vect_dbl *gamma_rr; /*! substitution rates defined by the RAS distribution */ vect_dbl *gamma_rr_unscaled; /*! substitution rates defined by the RAS distribution (unscaled) */ scalar_dbl *alpha; /*! gamma shapa parameter */ int free_mixt_rates; scalar_dbl *free_rate_mr; /*! mean relative rate as given by the FreeRate model */ int parent_class_number; scalar_dbl *pinvar; /*! proportion of invariable sites */ short int init_rr; short int init_r_proba; short int normalise_rr; short int *skip_rate_cat; /*! indicates whether of not the the likelihood for a given rate class shall be calculated. The default model in PhyML has four rate classes and the likelihood at a given site is then \sum_{i=1}^{4} \Pr(D|R=i) \Pr(R=i). Now, when optimising the rate for say the first rate class (i=1) one does not need to re-compute \Pr(D|R=2), \Pr(D|R=3) and \Pr(D|R=4) (which is the time consuming part of the likelihood calculation). This is where 'skip_rate_category' comes in handy. */ short int sort_rate_classes; /*! When doing MCMC moves on rate classes, one needs to have the rate classes sorted */ struct __RAS *next; struct __RAS *prev; }t_ras; /*!********************************************************/ typedef struct __EquFreq { /*! Equilibrium frequencies */ vect_dbl *pi; /*! states frequencies */ vect_dbl *pi_unscaled; /*! states frequencies (unscaled) */ struct __EquFreq *next; struct __EquFreq *prev; }t_efrq; /*!********************************************************/ typedef struct __Model { struct __Optimiz *s_opt; /*! pointer to parameters to optimize */ struct __Eigen *eigen; struct __M4 *m4mod; struct __Option *io; struct __Model *next; struct __Model *prev; struct __Model *next_mixt; struct __Model *prev_mixt; struct __RateMatrix *r_mat; struct __EquFreq *e_frq; struct __RAS *ras; t_string *aa_rate_mat_file; FILE *fp_aa_rate_mat; vect_dbl *user_b_freq; /*! user-defined nucleotide frequencies */ t_string *modelname; t_string *custom_mod_string; /*! string of characters used to define custom models of substitution */ int mod_num; /*! model number */ int update_eigen; /*! update_eigen=1-> eigen values/vectors need to be updated */ int whichmodel; int is_mixt_mod; int augmented; int ns; /*! number of states (4 for ADN, 20 for AA) */ int bootstrap; /*! Number of bootstrap replicates (0 : no bootstrap analysis is launched) */ int use_m4mod; /*! Use a Makrkov modulated Markov model ? */ scalar_dbl *kappa; /*! transition/transversion rate */ scalar_dbl *lambda; /*! parameter used to define the ts/tv ratios in the F84 and TN93 models */ scalar_dbl *br_len_mult; /*! when users want to fix the relative length of edges and simply estimate the total length of the tree. This multiplier does the trick */ scalar_dbl *br_len_mult_unscaled; vect_dbl *Pij_rr; /*! matrix of change probabilities */ scalar_dbl *mr; /*! mean rate = branch length/time interval mr = -sum(i)(vct_pi[i].mat_Q[ii]) */ short int log_l; /*! Edge lengths are actually log(Edge lengths) if log_l == YES !*/ phydbl l_min; /*! Minimum branch length !*/ phydbl l_max; /*! Maximum branch length !*/ phydbl l_var_sigma; /*! For any edge b we have b->l_var->v = l_var_sigma * (b->l->v)^2 */ phydbl l_var_min; /*! Min of variance of branch lengths (used in conjunction with gamma_mgf_bl == YES) */ phydbl l_var_max; /*! Max of variance of branch lengths (used in conjunction with gamma_mgf_bl == YES) */ int gamma_mgf_bl; /*! P = \int_0^inf exp(QL) p(L) where L=\int_0^t R(s) ds and p(L) is the gamma density. Set to NO by default !*/ int n_mixt_classes; /* Number of classes in the mixture model. */ scalar_dbl *r_mat_weight; scalar_dbl *e_frq_weight; #ifdef BEAGLE int b_inst; bool optimizing_topology; /*! This is a flag that prevents the resetting of category weights. Why? Read */ /* Recall that while optimizing the toplogy, PhyML temporarily only uses 2 * rate categories. Recall also that a BEAGLE instance is created with all the * required categories, but we temporarily assign 0 weight to the other categories * thus effectively using only 2 categories. However, subsequent calls to * update the rates (i.e. update_beagle_ras()) will reset the weights. This flag * prevents this resetting from happening */ #endif }t_mod; /*!********************************************************/ typedef struct __Eigen{ int size; /*! matrix is size * size */ phydbl *q; /*! matrix for which eigen values and vectors are computed */ phydbl *space; int *space_int; phydbl *e_val; /*! eigen values (vector), real part. */ phydbl *e_val_im; /*! eigen values (vector), imaginary part */ phydbl *r_e_vect; /*! right eigen vector (matrix), real part */ phydbl *r_e_vect_im; /*! right eigen vector (matrix), imaginary part */ phydbl *l_e_vect; /*! left eigen vector (matrix), real part */ struct __Eigen *prev; struct __Eigen *next; }eigen; /*!********************************************************/ typedef struct __Option { /*! mostly used in 'help.c' */ struct __Model *mod; /*! pointer to a substitution model */ struct __Tree *tree; /*! pointer to the current tree */ struct __Align **data; /*! pointer to the uncompressed sequences */ struct __Tree *cstr_tree; /*! pointer to a constraint tree (can be a multifurcating one) */ struct __Calign *cdata; /*! pointer to the compressed sequences */ struct __Super_Tree *st; /*! pointer to supertree */ struct __Tnexcom **nex_com_list; struct __List_Tree *treelist; /*! list of trees. */ struct __Option *next; struct __Option *prev; int interleaved; /*! interleaved or sequential sequence file format ? */ int in_tree; /*! =1 iff a user input tree is used as input */ char *in_align_file; /*! alignment file name */ FILE *fp_in_align; /*! pointer to the alignment file */ char *in_tree_file; /*! input tree file name */ FILE *fp_in_tree; /*! pointer to the input tree file */ char *in_constraint_tree_file; /*! input constraint tree file name */ FILE *fp_in_constraint_tree; /*! pointer to the input constraint tree file */ char *out_tree_file; /*! name of the tree file */ FILE *fp_out_tree; char *out_trees_file; /*! name of the tree file */ FILE *fp_out_trees; /*! pointer to the tree file containing all the trees estimated using random starting trees */ char *out_boot_tree_file; /*! name of the tree file */ FILE *fp_out_boot_tree; /*! pointer to the bootstrap tree file */ char *out_boot_stats_file; /*! name of the tree file */ FILE *fp_out_boot_stats; /*! pointer to the statistics file */ char *out_stats_file; /*! name of the statistics file */ FILE *fp_out_stats; char *out_trace_file; /*! name of the file in which the likelihood of the model is written */ FILE *fp_out_trace; char *out_lk_file; /*! name of the file in which the likelihood of the model is written */ FILE *fp_out_lk; char *out_summary_file; /*! name of the file in which summary statistics are written */ FILE *fp_out_summary; char *out_ps_file; /*! name of the file in which tree(s) is(are) written */ FILE *fp_out_ps; char *out_ancestral_file; /*! name of the file containing the ancestral sequences */ FILE *fp_out_ancestral; /*! pointer to the file containing the ancestral sequences */ char *in_coord_file; /*! name of input file containing coordinates */ FILE *fp_in_coord; /*! pointer to the file containing coordinates */ char *out_file; /*! name of the output file */ char *clade_list_file; int datatype; /*! 0->DNA, 1->AA */ int print_boot_trees; /*! =1 if the bootstrapped trees are printed in output */ int out_stats_file_open_mode; /*! opening file mode for statistics file */ int out_tree_file_open_mode; /*! opening file mode for tree file */ int n_data_sets; /*! number of data sets to be analysed */ int n_trees; /*! number of trees */ int init_len; /*! sequence length */ int n_otu; /*! number of taxa */ int n_data_set_asked; /*! number of bootstrap replicates */ char *nt_or_cd; /*! nucleotide or codon data ? (not used) */ int multigene; /*! if=1 -> analyse several partitions. */ int config_multigene; int n_part; /*! number of data partitions */ int curr_gt; int ratio_test; /*! from 1 to 4 for specific branch supports, 0 of not */ int ready_to_go; int data_file_format; /*! Data format: Phylip or Nexus */ int tree_file_format; /*! Tree format: Phylip or Nexus */ int state_len; int curr_interface; int r_seed; /*! random seed */ int collapse_boot; /*! 0 -> branch length on bootstrap trees are not collapsed if too small */ int random_boot_seq_order; /*! !0 -> sequence order in bootstrapped data set is random */ int print_trace; int print_site_lnl; int m4_model; int rm_ambigu; /*! 0 is the default. 1: columns with ambiguous characters are discarded prior further analysis */ int colalias; int append_run_ID; char *run_id_string; int quiet; /*! 0 is the default. 1: no interactive question (for batch mode) */ int lk_approx; /* EXACT or NORMAL */ char **alphabet; int codpos; int mutmap; int use_xml; char **long_tax_names; char **short_tax_names; int size_tax_names; phydbl *z_scores; phydbl *lat; phydbl *lon; int boot_prog_every; int mem_question; int do_alias_subpatt; struct __Tmcmc *mcmc; struct __T_Rate *rates; #ifdef BEAGLE int beagle_resource; #endif int ancestral; }option; /*!********************************************************/ typedef struct __Optimiz { /*! parameters to be optimised (mostly used in 'optimiz.c') */ int print; /*! =1 -> verbose mode */ int opt_alpha; /*! =1 -> the gamma shape parameter is optimised */ int opt_kappa; /*! =1 -> the ts/tv ratio parameter is optimised */ int opt_lambda; /*! =1 -> the F84|TN93 model specific parameter is optimised */ int opt_pinvar; /*! =1 -> the proportion of invariants is optimised */ int opt_state_freq; /*! =1 -> the nucleotide frequencies are optimised */ int opt_rr; /*! =1 -> the relative rate parameters of the GTR or the customn model are optimised */ int opt_subst_param; /*! if opt_topo=0 and opt_subst_param=1 -> the numerical parameters of the model are optimised. if opt_topo=0 and opt_free_param=0 -> no parameter is optimised */ int opt_cov_delta; int opt_cov_alpha; int opt_cov_free_rates; int opt_bl; /*! =1 -> the branch lengths are optimised */ int opt_topo; /*! =1 -> the tree topology is optimised */ int topo_search; phydbl init_lk; /*! initial loglikelihood value */ int n_it_max; /*! maximum bnumber of iteration during an optimisation step */ int last_opt; /*! =1 -> the numerical parameters are optimised further while the tree topology remains fixed */ int random_input_tree; /*! boolean */ int n_rand_starts; /*! number of random starting points */ int brent_it_max; int steph_spr; int user_state_freq; int opt_five_branch; int pars_thresh; int hybrid_thresh; int opt_br_len_mult; phydbl tree_size_mult; /*! tree size multiplier */ phydbl min_diff_lk_local; phydbl min_diff_lk_global; phydbl min_diff_lk_move; phydbl p_moves_to_examine; int fast_nni; int greedy; int general_pars; int quickdirty; int spr_pars; int spr_lnL; int max_depth_path; int min_depth_path; int deepest_path; phydbl max_delta_lnL_spr; int br_len_in_spr; int opt_free_mixt_rates; int constrained_br_len; int opt_gamma_br_len; int first_opt_free_mixt_rates; int wim_n_rgrft; int wim_n_globl; int wim_max_dist; int wim_n_optim; int wim_n_best; int wim_inside_opt; int opt_rmat_weight; int opt_efrq_weight; int skip_tree_traversal; int serial_free_rates; int curr_opt_free_rates; }t_opt; /*!********************************************************/ typedef struct __NNI{ struct __Node *left; struct __Node *rght; struct __Edge *b; phydbl score; phydbl init_l; phydbl init_lk; phydbl best_l; phydbl lk0,lk1,lk2; phydbl l0,l1,l2; struct __Node *swap_node_v1; struct __Node *swap_node_v2; struct __Node *swap_node_v3; struct __Node *swap_node_v4; int best_conf; /*! best topological configuration : ((left_1,left_2),right_1,right_2) or ((left_1,right_2),right_1,left_2) or ((left_1,right_1),right_1,left_2) */ }nni; /*!********************************************************/ typedef struct __SPR{ struct __Node *n_link; struct __Node *n_opp_to_link; struct __Edge *b_opp_to_link; struct __Edge *b_target; struct __Edge *b_init_target; struct __Node **path; phydbl init_target_l; phydbl init_target_v; phydbl l0,l1,l2; phydbl v0,v1,v2; phydbl lnL; int depth_path; int pars; int dist; struct __SPR *next; struct __SPR *prev; struct __SPR *next_mixt; struct __SPR *prev_mixt; }t_spr; /*!********************************************************/ typedef struct __Triplet{ int size; phydbl *F_bc; phydbl *F_cd; phydbl *F_bd; phydbl ****core; phydbl ***p_one_site; phydbl ***sum_p_one_site; phydbl *pi_bc; phydbl *pi_cd; phydbl *pi_bd; struct __Eigen *eigen_struct; struct __Model *mod; struct __Triplet *next; struct __Triplet *prev; }triplet; /*!********************************************************/ typedef struct __Pnode{ struct __Pnode **next; int weight; int num; }pnode; /*!********************************************************/ typedef struct __M4 { int n_h; /*! number of hidden states */ int n_o; /*! number of observable states */ int use_cov_alpha; int use_cov_free; phydbl **o_mats; /*! set of matrices of substitution rates across observable states */ phydbl *multipl; /*! vector of values that multiply each o_mats matrix */ phydbl *o_rr; /*! relative rates (symmetric) of substitution between observable states */ phydbl *h_rr; /*! relative rates (symmetric) of substitution between hidden states */ phydbl *h_mat; /*! matrix that describes the substitutions between hidden states (aka switches) */ phydbl *o_fq; /*! equilibrium frequencies for the observable states */ phydbl *h_fq; /*! equilibrium frequencies for the hidden states */ phydbl *h_fq_unscaled; /*! unscaled equilibrium frequencies for the hidden states */ phydbl *multipl_unscaled; /*! unscaled vector of values that multiply each o_mats matrix */ phydbl delta; /*! switching rate */ phydbl alpha; /*! gamma shape parameter */ }m4; /*!********************************************************/ typedef struct __Tdraw { phydbl *xcoord; /*! t_node coordinates on the x axis */ phydbl *ycoord; /*! t_node coordinates on the y axis */ phydbl *xcoord_s; /*! t_node coordinates on the x axis (scaled) */ phydbl *ycoord_s; /*! t_node coordinates on the y axis (scaled) */ int page_width; int page_height; int tree_box_width; int *cdf_mat; phydbl *cdf_mat_x; phydbl *cdf_mat_y; phydbl max_dist_to_root; }tdraw; /*!********************************************************/ typedef struct __T_Rate { phydbl lexp; /*! Parameter of the exponential distribution that governs the rate at which substitution between rate classes ocur */ phydbl alpha; phydbl less_likely; phydbl birth_rate; phydbl birth_rate_min; phydbl birth_rate_max; phydbl min_rate; phydbl max_rate; phydbl c_lnL1; phydbl c_lnL2; phydbl c_lnL_rates; /*! Prob(Br len | time stamps, model of rate evolution) */ phydbl c_lnL_times; /*! Prob(time stamps) */ phydbl c_lnL_jps; /*! Prob(# Jumps | time stamps, rates, model of rate evolution) */ phydbl clock_r; /*! Mean substitution rate, i.e., 'molecular clock' rate */ phydbl min_clock; phydbl max_clock; phydbl lbda_nu; phydbl min_dt; phydbl step_rate; phydbl true_tree_size; phydbl p_max; phydbl norm_fact; phydbl nu; /*! Parameter of the Exponential distribution for the corresponding model */ phydbl min_nu; phydbl max_nu; phydbl covdet; phydbl sum_invalid_areas; phydbl *nd_r; /*! Current rates at nodes */ phydbl *br_r; /*! Current rates along edges */ phydbl *nd_t; /*! Current t_node times */ phydbl *triplet; phydbl *true_t; /*! true t_node times (including root node) */ phydbl *true_r; /*! true t_edge rates (on rooted tree) */ phydbl *buff_t; phydbl *buff_r; phydbl *dens; /*! Probability densities of mean substitution rates at the nodes */ phydbl *ml_l; /*! ML t_edge lengths (rooted) */ phydbl *cur_l; /*! Current t_edge lengths (rooted) */ phydbl *u_ml_l; /*! ML t_edge lengths (unrooted) */ phydbl *u_cur_l; /*! Current t_edge lengths (unrooted) */ phydbl *invcov; phydbl *cov_r; phydbl *mean_r; /*! average values of br_r taken across the sampled values during the MCMC */ phydbl *mean_t; /*! average values of nd_t taken across the sampled values during the MCMC */ phydbl *_2n_vect1; phydbl *_2n_vect2; phydbl *_2n_vect3; phydbl *_2n_vect4; short int *_2n_vect5; phydbl *_2n2n_vect1; phydbl *_2n2n_vect2; phydbl *trip_cond_cov; phydbl *trip_reg_coeff; phydbl *cond_var; phydbl *reg_coeff; phydbl *t_prior; phydbl *t_prior_min; phydbl *t_prior_max; phydbl *t_floor; phydbl *t_mean; int *t_rank; /* rank of nodes, e.g., tree->nd_a[tree->rates->t_rank[0]] is the oldest node */ phydbl *mean_l; phydbl *cov_l; phydbl *grad_l; /* gradient */ phydbl inflate_var; phydbl *time_slice_lims; phydbl *survival_rank; phydbl *survival_dur; phydbl *calib_prob; int adjust_rates; /*! if = 1, branch rates are adjusted such that a modification of a given t_node time does not modify any branch lengths */ int use_rates; /*! if = 0, branch lengths are expressed as differences between t_node times */ int bl_from_rt; /*! if =1, branch lengths are obtained as the product of cur_r and t */ int approx; int model; /*! Model number */ int is_allocated; int met_within_gibbs; int update_mean_l; int update_cov_l; int *n_jps; int *t_jps; int n_time_slices; int *n_time_slice_spans; int *curr_slice; int *n_tips_below; short int *t_has_prior; struct __Node **lca; /*! 2-way table of common ancestral nodes for each pari of nodes */ short int *br_do_updt; phydbl *cur_gamma_prior_mean; phydbl *cur_gamma_prior_var; int model_log_rates; short int nd_t_recorded; short int br_r_recorded; int *has_survived; struct __Calibration *calib; int tot_num_cal; int *curr_nd_for_cal; phydbl c_lnL_Hastings_ratio; phydbl *t_prior_min_ori; phydbl *t_prior_max_ori; phydbl *times_partial_proba; phydbl log_K_cur; int cur_comb_numb; int *numb_calib_chosen; phydbl *node_height_dens_log_norm_const_update; int update_time_norm_const; }t_rate; /*!********************************************************/ typedef struct __Tmcmc { struct __Option *io; phydbl *tune_move; phydbl *move_weight; phydbl *acc_rate; int *acc_move; int *run_move; int *prev_acc_move; int *prev_run_move; int *num_move; int *move_type; char **move_name; int num_move_nd_r; int num_move_br_r; int num_move_nd_t; int num_move_nu; int num_move_clock_r; int num_move_tree_height; int num_move_subtree_height; int num_move_kappa; int num_move_tree_rates; int num_move_subtree_rates; int num_move_updown_nu_cr; int num_move_updown_t_cr; int num_move_updown_t_br; int num_move_ras; int num_move_cov_rates; int num_move_cov_switch; int num_move_birth_rate; int num_move_jump_calibration; int num_move_geo_lambda; int num_move_geo_sigma; int num_move_geo_tau; int num_move_geo_dum; int num_move_geo_updown_tau_lbda; int num_move_geo_updown_lbda_sigma; int num_move_phyrex_lbda; int num_move_phyrex_mu; int num_move_phyrex_rad; int num_move_phyrex_indel_disk; int num_move_phyrex_move_disk_ct; int num_move_phyrex_move_disk_ud; int num_move_phyrex_swap_disk; int num_move_phyrex_indel_hit; int num_move_phyrex_spr; int num_move_phyrex_scale_times; int num_move_phyrex_ldscape_lim; int num_move_phyrex_sigsq; int num_move_phyrex_sim; int num_move_phyrex_traj; int num_move_phyrex_lbda_times; int num_move_phyrex_indel_disk_serial; int num_move_phyrex_sim_plus; int num_move_phyrex_indel_hit_serial; int num_move_phyrex_ldsk_and_disk; int num_move_phyrex_ldsk_multi; int num_move_phyrex_disk_multi; int num_move_phyrex_ldsk_given_disk; int num_move_phyrex_disk_given_ldsk; int nd_t_digits; int *monitor; char *out_filename; time_t t_beg; time_t t_cur; time_t t_last_print; FILE *out_fp_stats; FILE *out_fp_trees; FILE *out_fp_means; FILE *out_fp_last; FILE *out_fp_constree; FILE *in_fp_par; int *adjust_tuning; int n_moves; int use_data; int randomize; int norm_freq; int run; int chain_len; int sample_interval; int chain_len_burnin; int print_every; int is_burnin; int max_lag; phydbl max_tune; phydbl min_tune; phydbl *sampled_val; int sample_size; int sample_num; phydbl *ess; int *ess_run; int *start_ess; phydbl *mode; int always_yes; /* Always accept proposed move (as long as log-likelihood > UNLIKELY) */ int is; /* Importance sampling? Yes or NO */ }t_mcmc; /*!********************************************************/ typedef struct __Tpart { int *ns; /*! number of states for each partition (e.g., 2, 4, 3) */ int *cum_ns; /*! cumulative number of states (e.g., 0, 2, 6) */ int ns_max; /*! maximum number of states */ int ns_min; /*! minimum number of states */ int n_partitions; /*! number of partitions */ struct __Eigen *eigen; }part; /*!********************************************************/ typedef struct __Tnexcom { char *name; int nparm; int nxt_token_t; int cur_token_t; struct __Tnexparm **parm; }nexcom; /*!********************************************************/ typedef struct __Tnexparm { char *name; char *value; int nxt_token_t; int cur_token_t; int (*fp)(char *, struct __Tnexparm *, struct __Option *); struct __Tnexcom *com; }nexparm; /*!********************************************************/ typedef struct __ParamInt { int val; }t_param_int; /*!********************************************************/ typedef struct __ParamDbl { phydbl val; }t_param_dbl; /*!********************************************************/ typedef struct __XML_node { struct __XML_attr *attr; // Pointer to the first element of a list of attributes int n_attr; // Number of attributes struct __XML_node *next; // Next sibling struct __XML_node *prev; // Previous sibling struct __XML_node *parent; // Parent of this node struct __XML_node *child; // Child of this node char *id; char *name; char *value; struct __Generic_Data_Structure *ds; // Pointer to a data strucuture. Can be a scalar, a vector, anything. }xml_node; /*!********************************************************/ typedef struct __Generic_Data_Structure { void *obj; struct __Generic_Data_Structure *next; }t_ds; /*!********************************************************/ typedef struct __XML_attr { char *name; char *value; struct __XML_attr *next; // Next attribute struct __XML_attr *prev; // Previous attribute }xml_attr; /*!********************************************************/ typedef struct __Calibration { phydbl *proba; // Probability of this calibration (set by the user and fixed throughout) phydbl lower; // lower bound phydbl upper; // upper bound int cur_applies_to; phydbl calib_proba; struct __Node **all_applies_to; int n_all_applies_to; struct __Calibration *next; struct __Calibration *prev; }t_cal; /*!********************************************************/ typedef struct __Phylogeo{ phydbl *cov; // Covariance of migrations (n_dim x n_dim) phydbl *r_mat; // R matrix. Gives the rates of migrations between locations. See article. phydbl *f_mat; // F matrix. See article. int *occup; // Vector giving the number of lineages that occupy each location int *idx_loc; // Index of location for each lineage int *idx_loc_beneath; // Gives the index of location occupied beneath each node in the tree int ldscape_sz; // Landscape size: number of locations int n_dim; // Dimension of the data (e.g., longitude + lattitude -> n_dim = 2) int update_fmat; struct __Geo_Coord **coord_loc; // Coordinates of the observed locations phydbl sigma; // Dispersal parameter phydbl min_sigma; phydbl max_sigma; phydbl sigma_thresh; // beyond sigma_thresh, there is no dispersal bias. phydbl lbda; // Competition parameter phydbl min_lbda; phydbl max_lbda; phydbl c_lnL; struct __Node **sorted_nd; // Table of nodes sorted wrt their heights. phydbl tau; // overall migration rate parameter phydbl min_tau; phydbl max_tau; phydbl dum; // dummy parameter use to assess non-identifiability issues phydbl min_dum; phydbl max_dum; }t_geo; /*!********************************************************/ // Structure for the Etheridge-Barton migration/reproduction model typedef struct __Migrep_Model{ int name; int n_dim; phydbl lbda; // rate at which events occur phydbl min_lbda; // min of rate at which events occur phydbl max_lbda; // max of rate at which events occur phydbl prior_param_lbda; // parameter of the parameter for the prior on lbda phydbl mu; // per-capita and per event death probability phydbl min_mu; // min of per-capita and per event death probability phydbl max_mu; // max of per-capita and per event death probability phydbl prior_param_mu; // parameter of the parameter for the prior on mu phydbl rad; // radius of the migrep disk phydbl min_rad; // min of radius of the migrep disk phydbl max_rad; // max of radius of the migrep disk phydbl prior_param_rad; // parameter of the parameter for the prior on radius int update_rad; phydbl sigsq; // parent to offspring distance variance (i.e., gene flow) parameter. phydbl min_sigsq; // min phydbl max_sigsq; // max phydbl prior_param_sigsq; // parameter of the parameter for the prior phydbl rho; // intensity parameter of the Poisson point processs phydbl c_lnL; // current value of log-likelihood phydbl c_ln_prior_rad; // current value of log prior for the prior on radius phydbl c_ln_prior_lbda; // current value of log prior for the prior on lbda phydbl c_ln_prior_mu; // current value of log prior for the prior on mu phydbl c_ln_prior_sigsq; // current value of log prior for the prior on sigsq=4.pi.lbda.mu.rad^4 int safe_phyrex; phydbl soft_bound_area; struct __Geo_Coord *lim; // max longitude and lattitude (the min are both set to zero) phydbl sampl_area; }t_phyrex_mod; /*!********************************************************/ typedef struct __Disk_Event{ struct __Geo_Coord *centr; phydbl time; struct __Disk_Event *next; struct __Disk_Event *prev; struct __Lindisk_Node **ldsk_a; // array of lindisk nodes corresponding to this disk event int n_ldsk_a; // size of ldsk_a struct __Lindisk_Node *ldsk; struct __Migrep_Model *mmod; char *id; phydbl c_lnL; }t_dsk; /*!********************************************************/ typedef struct __Geo_Coord{ phydbl *lonlat; /* longitude-latitude vector */ int dim; char *id; struct __Geo_Coord *cpy; /* keep a copy of this coordinate */ }t_geo_coord; /*!********************************************************/ typedef struct __Lindisk_Node{ struct __Disk_Event *disk; struct __Lindisk_Node **next; struct __Lindisk_Node *prev; struct __Geo_Coord *coord; struct __Geo_Coord *cpy_coord; short int is_hit; int n_next; struct __Node *nd; }t_ldsk; /*!********************************************************/ typedef struct __Polygon{ struct __Geo_Coord **poly_vert; /* array of polygon vertex coordinates */ int n_poly_vert; /* number of vertices */ }t_poly; /*!********************************************************/ /*!********************************************************/ /*!********************************************************/ /*!********************************************************/ /*!********************************************************/ /*!********************************************************/ void Unroot_Tree(char **subtrees); void Init_Tree(t_tree *tree,int n_otu); void Init_Edge_Light(t_edge *b,int num); void Init_Node_Light(t_node *n,int num); void Set_Edge_Dirs(t_edge *b,t_node *a,t_node *d,t_tree *tree); void Init_NNI(nni *a_nni); void Init_Nexus_Format(nexcom **com); void Restrict_To_Coding_Position(align **data,option *io); void Uppercase(char *ch); void Lowercase(char *ch); calign *Compact_Data(align **data,option *io); calign *Compact_Cdata(calign *data,option *io); void Traverse_Prefix_Tree(int site,int seqnum,int *patt_num,int *n_patt,align **data,option *io,pnode *n); pnode *Create_Pnode(int size); void Get_Base_Freqs(calign *data); void Get_AA_Freqs(calign *data); void Swap_Nodes_On_Edges(t_edge *e1,t_edge *e2,int swap,t_tree *tree); void Connect_Edges_To_Nodes_Recur(t_node *a,t_node *d,t_tree *tree); void Connect_One_Edge_To_Two_Nodes(t_node *a,t_node *d,t_edge *b,t_tree *tree); void Update_Dirs(t_tree *tree); void Exit(char *message); void *mCalloc(int nb,size_t size); void *mRealloc(void *p,int nb,size_t size); int Sort_Phydbl_Decrease(const void *a,const void *b); void Qksort_Int(int *A,int *B,int ilo,int ihi); void Qksort(phydbl *A,phydbl *B,int ilo,int ihi); void Qksort_Matrix(phydbl **A,int col,int ilo,int ihi); void Order_Tree_Seq(t_tree *tree,align **data); char *Add_Taxa_To_Constraint_Tree(FILE *fp,calign *cdata); void Check_Constraint_Tree_Taxa_Names(t_tree *tree,calign *cdata); void Order_Tree_CSeq(t_tree *tree,calign *cdata); void Init_Mat(matrix *mat,calign *data); void Copy_Tax_Names_To_Tip_Labels(t_tree *tree,calign *data); void Share_Lk_Struct(t_tree *t_full,t_tree *t_empt); void Share_Spr_Struct(t_tree *t_full,t_tree *t_empt); void Share_Pars_Struct(t_tree *t_full,t_tree *t_empt); int Sort_Edges_NNI_Score(t_tree *tree,t_edge **sorted_edges,int n_elem); int Sort_Edges_Depth(t_tree *tree,t_edge **sorted_edges,int n_elem); void NNI(t_tree *tree,t_edge *b_fcus,int do_swap); void NNI_Pars(t_tree *tree,t_edge *b_fcus,int do_swap); void Swap(t_node *a,t_node *b,t_node *c,t_node *d,t_tree *tree); void Update_All_Partial_Lk(t_edge *b_fcus,t_tree *tree); void Update_SubTree_Partial_Lk(t_edge *b_fcus,t_node *a,t_node *d,t_tree *tree); void Copy_Seq_Names_To_Tip_Labels(t_tree *tree,calign *data); calign *Copy_Cseq(calign *ori,option *io); int Filexists(char *filename); matrix *K80_dist(calign *data,phydbl g_shape); matrix *JC69_Dist(calign *data,t_mod *mod); matrix *Hamming_Dist(calign *data,t_mod *mod); int Is_Invar(int patt_num,int stepsize,int datatype,calign *data); int Is_Ambigu(char *state,int datatype,int stepsize); void Check_Ambiguities(calign *data,int datatype,int stepsize); int Get_State_From_Ui(int ui,int datatype); int Assign_State(char *c,int datatype,int stepsize); char Reciproc_Assign_State(int i_state,int datatype); int Assign_State_With_Ambiguity(char *c,int datatype,int stepsize); void Clean_Tree_Connections(t_tree *tree); void Bootstrap(t_tree *tree); void Br_Len_Involving_Invar(t_tree *tree); void Br_Len_Not_Involving_Invar(t_tree *tree); void Getstring_Stdin(char *s); phydbl Num_Derivatives_One_Param(phydbl (*func)(t_tree *tree), t_tree *tree, phydbl f0, phydbl *param, int which, int n_param, phydbl stepsize, int logt, phydbl *err, int precise, int is_positive); phydbl Num_Derivatives_One_Param_Nonaligned(phydbl (*func)(t_tree *tree), t_tree *tree, phydbl f0, phydbl **param, int which, int n_param, phydbl stepsize, int logt, phydbl *err, int precise, int is_positive); int Num_Derivative_Several_Param(t_tree *tree,phydbl *param,int n_param,phydbl stepsize,int logt,phydbl(*func)(t_tree *tree),phydbl *derivatives, int is_positive); int Num_Derivative_Several_Param_Nonaligned(t_tree *tree, phydbl **param, int n_param, phydbl stepsize, int logt, phydbl (*func)(t_tree *tree), phydbl *derivatives, int is_positive); int Compare_Two_States(char *state1,char *state2,int state_size); void Copy_One_State(char *from,char *to,int state_size); void Copy_Dist(phydbl **cpy,phydbl **orig,int n); t_mod *Copy_Model(t_mod *ori); void Record_Model(t_mod *ori,t_mod *cpy); void Set_Defaults_Input(option *io); void Set_Defaults_Model(t_mod *mod); void Set_Defaults_Optimiz(t_opt *s_opt); void Test_Node_Table_Consistency(t_tree *tree); void Get_Bip(t_node *a,t_node *d,t_tree *tree); void Alloc_Bip(t_tree *tree); int Sort_Phydbl_Increase(const void *a,const void *b); int Sort_String(const void *a,const void *b); int Compare_Bip(t_tree *tree1,t_tree *tree2,int on_existing_edges_only); void Match_Tip_Numbers(t_tree *tree1,t_tree *tree2); void Test_Multiple_Data_Set_Format(option *io); int Are_Compatible(char *statea,char *stateb,int stepsize,int datatype); void Hide_Ambiguities(calign *data); void Copy_Tree(t_tree *ori,t_tree *cpy); void Prune_Subtree(t_node *a,t_node *d,t_edge **target,t_edge **residual,t_tree *tree); void Graft_Subtree(t_edge *target,t_node *link,t_edge *residual,t_tree *tree); void Reassign_Node_Nums(t_node *a,t_node *d,int *curr_ext_node,int *curr_int_node,t_tree *tree); void Reassign_Edge_Nums(t_node *a,t_node *d,int *curr_br,t_tree *tree); void Find_Mutual_Direction(t_node *n1,t_node *n2,short int *dir_n1_to_n2,short int *dir_n2_to_n1); void Update_Dir_To_Tips(t_node *a,t_node *d,t_tree *tree); void Fill_Dir_Table(t_tree *tree); int Get_Subtree_Size(t_node *a,t_node *d); void Fast_Br_Len(t_edge *b,t_tree *tree,int approx); void Init_Eigen_Struct(eigen *this); phydbl Triple_Dist(t_node *a,t_tree *tree,int approx); void Make_Symmetric(phydbl **F,int size); void Round_Down_Freq_Patt(phydbl **F,t_tree *tree); phydbl Get_Sum_Of_Cells(phydbl *F,t_tree *tree); void Divide_Cells(phydbl **F,phydbl div,t_tree *tree); void Divide_Mat_By_Vect(phydbl **F,phydbl *vect,int size); void Multiply_Mat_By_Vect(phydbl **F,phydbl *vect,int size); void Found_In_Subtree(t_node *a,t_node *d,t_node *target,int *match,t_tree *tree); void Get_List_Of_Target_Edges(t_node *a,t_node *d,t_edge **list,int *list_size,t_tree *tree); void Fix_All(t_tree *tree); void Record_Br_Len(t_tree *tree); void Restore_Br_Len(t_tree *tree); void Get_Dist_Btw_Edges(t_node *a,t_node *d,t_tree *tree); void Detect_Polytomies(t_edge *b,phydbl l_thresh,t_tree *tree); void Get_List_Of_Nodes_In_Polytomy(t_node *a,t_node *d,t_node ***list,int *size_list); void Check_Path(t_node *a,t_node *d,t_node *target,t_tree *tree); void Connect_Two_Nodes(t_node *a,t_node *d); void Get_List_Of_Adjacent_Targets(t_node *a,t_node *d,t_node ***node_list,t_edge ***edge_list,int *list_size); void Sort_List_Of_Adjacent_Targets(t_edge ***list,int list_size); t_node *Common_Nodes_Btw_Two_Edges(t_edge *a,t_edge *b); int KH_Test(phydbl *site_lk_M1,phydbl *site_lk_M2,t_tree *tree); void Random_Tree(t_tree *tree); void Reorganize_Edges_Given_Lk_Struct(t_tree *tree); void Random_NNI(int n_moves,t_tree *tree); void Fill_Missing_Dist(matrix *mat); void Fill_Missing_Dist_XY(int x,int y,matrix *mat); phydbl Least_Square_Missing_Dist_XY(int x,int y,phydbl dxy,matrix *mat); void Check_Memory_Amount(t_tree *tree); int Get_State_From_P_Lk(phydbl *p_lk,int pos,t_tree *tree); int Get_State_From_P_Pars(short int *p_pars,int pos,t_tree *tree); void Check_Dirs(t_tree *tree); void Warn_And_Exit(const char *s); void Randomize_Sequence_Order(calign *cdata); void Update_Root_Pos(t_tree *tree); void Add_Root(t_edge *target,t_tree *tree); void Update_Ancestors(t_node *a,t_node *d,t_tree *tree); #if (defined PHYTIME || defined SERGEII) t_tree *Generate_Random_Tree_From_Scratch(int n_otu,int rooted); #endif void Random_Lineage_Rates(t_node *a,t_node *d,t_edge *b,phydbl stick_prob,phydbl *rates,int curr_rate,int n_rates,t_tree *tree); t_edge *Find_Edge_With_Label(char *label,t_tree *tree); void Evolve(calign *data,t_mod *mod,t_tree *tree); int Pick_State(int n,phydbl *prob); void Evolve_Recur(t_node *a,t_node *d,t_edge *b,int a_state,int r_class,int site_num,calign *gen_data,t_mod *mod,t_tree *tree); void Site_Diversity(t_tree *tree); void Site_Diversity_Post(t_node *a,t_node *d,t_edge *b,t_tree *tree); void Site_Diversity_Pre(t_node *a,t_node *d,t_edge *b,t_tree *tree); void Subtree_Union(t_node *n,t_edge *b_fcus,t_tree *tree); void Binary_Decomposition(int value,int *bit_vect,int size); void Print_Diversity_Header(FILE *fp,t_tree *tree); phydbl Univariate_Kernel_Density_Estimate(phydbl where,phydbl *x,int sample_size); phydbl Multivariate_Kernel_Density_Estimate(phydbl *where,phydbl **x,int sample_size,int vect_size); phydbl Var(phydbl *x,int n); phydbl Mean(phydbl *x,int n); void Best_Of_NNI_And_SPR(t_tree *tree); int Polint(phydbl *xa,phydbl *ya,int n,phydbl x,phydbl *y,phydbl *dy); void JF(t_tree *tree); t_tree *Dist_And_BioNJ(calign *cdata,t_mod *mod,option *io); void Add_BioNJ_Branch_Lengths(t_tree *tree,calign *cdata,t_mod *mod); char *Bootstrap_From_String(char *s_tree,calign *cdata,t_mod *mod,option *io); char *aLRT_From_String(char *s_tree,calign *cdata,t_mod *mod,option *io); void Prepare_Tree_For_Lk(t_tree *tree); void Find_Common_Tips(t_tree *tree1,t_tree *tree2); phydbl Get_Tree_Size(t_tree *tree); void Dist_To_Root_Pre(t_node *a,t_node *d,t_edge *b,t_tree *tree); void Dist_To_Root(t_node *n_root,t_tree *tree); char *Basename(char *path); t_node *Find_Lca_Pair_Of_Nodes(t_node *n1,t_node *n2,t_tree *tree); t_node *Find_Lca_Clade(t_node **node_list,int node_list_size,t_tree *tree); int Get_List_Of_Ancestors(t_node *ref_node,t_node **list,int *size,t_tree *tree); int Edge_Num_To_Node_Num(int edge_num,t_tree *tree); void Time_To_Branch(t_tree *tree); void Time_To_Branch_Pre(t_node *a,t_node *d,t_tree *tree); void Branch_Lengths_To_Rate_Lengths(t_tree *tree); void Branch_Lengths_To_Rate_Lengths_Pre(t_node *a,t_node *d,t_tree *tree); int Find_Clade(char **tax_name_list,int list_size,t_tree *tree); void Find_Clade_Pre(t_node *a,t_node *d,int *tax_num_list,int list_size,int *num,t_tree *tree); t_edge *Find_Root_Edge(FILE *fp_input_tree,t_tree *tree); void Copy_Tree_Topology_With_Labels(t_tree *ori,t_tree *cpy); void Set_Model_Name(t_mod *mod); void Adjust_Min_Diff_Lk(t_tree *tree); void Translate_Tax_Names(char **tax_names,t_tree *tree); void Skip_Comment(FILE *fp); void Get_Best_Root_Position(t_tree *tree); void Get_Best_Root_Position_Post(t_node *a,t_node *d,int *has_outgrp,t_tree *tree); void Get_Best_Root_Position_Pre(t_node *a,t_node *d,t_tree *tree); void Get_OutIn_Scores(t_node *a,t_node *d); int Check_Sequence_Name(char *s); int Scale_Subtree_Height(t_node *a,phydbl K,phydbl floor,int *n_nodes,t_tree *tree); void Scale_Node_Heights_Post(t_node *a,t_node *d,phydbl K,phydbl floor,int *n_nodes,t_tree *tree); int Scale_Subtree_Rates(t_node *a,phydbl mult,int *n_nodes,t_tree *tree); void Check_Br_Len_Bounds(t_tree *tree); int Scale_Subtree_Rates_Post(t_node *a,t_node *d,phydbl mult,int *n_nodes,t_tree *tree); void Get_Node_Ranks(t_tree *tree); void Get_Node_Ranks_Pre(t_node *a,t_node *d,t_tree *tree); void Log_Br_Len(t_tree *tree); phydbl Diff_Lk_Norm_At_Given_Edge(t_edge *b,t_tree *tree); void Adjust_Variances(t_tree *tree); phydbl Effective_Sample_Size(phydbl first_val,phydbl last_val,phydbl sum,phydbl sumsq,phydbl sumcurnext,int n); void Rescale_Free_Rate_Tree(t_tree *tree); phydbl Rescale_Br_Len_Multiplier_Tree(t_tree *tree); phydbl Unscale_Br_Len_Multiplier_Tree(t_tree *tree); phydbl Reflect(phydbl x,phydbl l,phydbl u); int Are_Equal(phydbl a,phydbl b,phydbl eps); int Check_Topo_Constraints(t_tree *big_tree,t_tree *small_tree); void Prune_Tree(t_tree *big_tree,t_tree *small_tree); void Match_Nodes_In_Small_Tree(t_tree *small_tree,t_tree *big_tree); void Find_Surviving_Edges_In_Small_Tree(t_tree *small_tree,t_tree *big_tree); void Find_Surviving_Edges_In_Small_Tree_Post(t_node *a,t_node *d,t_tree *small_tree,t_tree *big_tree); void Set_Taxa_Id_Ranking(t_tree *tree); void Get_Edge_Binary_Coding_Number(t_tree *tree); void Make_Ancestral_Seq(t_tree *tree); void Make_MutMap(t_tree *tree); int Get_Mutmap_Val(int edge,int site,int mut,t_tree *tree); void Get_Mutmap_Coord(int idx,int *edge,int *site,int *mut,t_tree *tree); void Copy_Edge_Lengths(t_tree *to,t_tree *from); void Init_Scalar_Dbl(scalar_dbl *p); void Init_Scalar_Int(scalar_int *p); void Init_Vect_Dbl(int len,vect_dbl *p); void Init_Vect_Int(int len,vect_int *p); char *To_Lower_String(char *in); phydbl String_To_Dbl(char *string); char *To_Upper_String(char *in); void Connect_CSeqs_To_Nodes(calign *cdata, option *io, t_tree *tree); void Switch_Eigen(int state, t_mod *mod); void Joint_Proba_States_Left_Right(phydbl *Pij, phydbl *p_lk_left, phydbl *p_lk_rght, vect_dbl *pi, int scale_left, int scale_rght, phydbl *F, int n, int site, t_tree *tree); void Set_Both_Sides(int yesno, t_tree *tree); void Set_D_States(calign *data, int datatype, int stepsize); void Branch_To_Time(t_tree *tree); void Branch_To_Time_Pre(t_node *a, t_node *d, t_tree *tree); void Path_Length(t_node *dep, t_node *arr, phydbl *len, t_tree *tree); phydbl *Dist_Btw_Tips(t_tree *tree); void Random_SPRs_On_Rooted_Tree(t_tree *tree); void Set_P_Lk_One_Side(phydbl **Pij, phydbl **p_lk, int **sum_scale, t_node *d, t_edge *b, t_tree *tree #ifdef BEAGLE , int* child_p_idx, int* Pij_idx #endif ); void Set_All_P_Lk(t_node **n_v1, t_node **n_v2, phydbl **p_lk , int **sum_scale , int **p_lk_loc, phydbl **Pij1, phydbl **p_lk1, int **sum_scale1, phydbl **Pij2, phydbl **p_lk2, int **sum_scale2, t_node *d, t_edge *b, t_tree *tree #ifdef BEAGLE , int *dest_p_idx, int *child1_p_idx, int* child2_p_idx, int* Pij1_idx, int* Pij2_idx #endif ); void Optimum_Root_Position_IL_Model(t_tree *tree); void Set_Br_Len_Var(t_tree *tree); void Check_Br_Lens(t_tree *tree); void Calculate_Number_Of_Diff_States_Post(t_node *a, t_node *d, t_edge *b, t_tree *tree); void Calculate_Number_Of_Diff_States_Pre(t_node *a, t_node *d, t_edge *b, t_tree *tree); void Calculate_Number_Of_Diff_States_Core(t_node *a, t_node *d, t_edge *b, t_tree *tree); void Calculate_Number_Of_Diff_States(t_tree *tree); void Build_Distrib_Number_Of_Diff_States_Under_Model(t_tree *tree); int Number_Of_Diff_States_One_Site(int site, t_tree *tree); void Number_Of_Diff_States_One_Site_Post(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree); int Number_Of_Diff_States_One_Site_Core(t_node *a, t_node *d, t_edge *b, int site, t_tree *tree); phydbl Get_Lk(t_tree *tree); align **Make_Empty_Alignment(option *io); void Connect_Edges_To_Nodes_Serial(t_tree *tree); phydbl Mean_Identity(calign *data); phydbl Pairwise_Identity(int i, int j, calign *data); phydbl Fst(int i, int j, calign *data); phydbl Nucleotide_Diversity(calign *data); #include "xml.h" #include "free.h" #include "spr.h" #include "lk.h" #include "optimiz.h" #include "models.h" #include "bionj.h" #include "simu.h" #include "eigen.h" #include "pars.h" #include "alrt.h" #include "stats.h" #include "help.h" #include "io.h" #include "make.h" #include "nexus.h" #include "init.h" #include "mcmc.h" #ifdef GEO #include "geo.h" #endif #ifdef PHYREX #include "phyrex.h" #endif #ifdef MPI #include "mpi_boot.h" #endif #ifdef MG #include "mg.h" #endif #ifdef TIME #include "times.h" #include "rates.h" #endif #ifdef _NOT_NEEDED_A_PRIORI #include "m4.h" #endif #endif phyml-3.2.0/src/xml.c000066400000000000000000000665021263450375500144230ustar00rootroot00000000000000#include "xml.h" ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Load_File(FILE *fp) { int c; char *buffer,*bufptr; int bufsize; xml_node *parent,*node; buffer = (char *)mCalloc(T_MAX_XML_TAG,sizeof(char)); bufsize = T_MAX_XML_TAG; bufptr = buffer; parent = NULL; node = NULL; while((c = fgetc(fp)) != EOF) { if(c == '<' && bufptr > buffer) { *bufptr = '\0'; /* PhyML_Printf("\n. Read value '%s' for node '%s'",buffer,node->name); */ /* fflush(NULL); */ XML_Set_Node_Value(node,buffer); bufptr = buffer; } if(c == '<') { bufptr = buffer; while((c = fgetc(fp)) != EOF) { if(isspace(c) != NO || c == '>' || (c == '/' && bufptr > buffer)) break; // End of open or close tag else if(c == '<') { Exit("\n== Bare < in element!"); } else if(XML_Add_Character(c,&bufptr,&buffer,&bufsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } *bufptr = '\0'; if(!strcmp(buffer,"!--")) // Get the rest of the comment { while((c = fgetc(fp)) != EOF) { if(c == '>' && bufptr > (buffer + 4) && bufptr[-3] != '-' && bufptr[-2] == '-' && bufptr[-1] == '-') break; else if(XML_Add_Character(c,&bufptr,&buffer,&bufsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } *bufptr = '\0'; if(c != '>') { PhyML_Printf("\n== Early EOF in comment node."); Exit("\n"); } } else if(buffer[0] == '/') // Close tag { if(strcmp(buffer+1,parent->name)) { PhyML_Printf("\n== Opened tag with name '%s' and closed it with '%s'...",node->name,buffer+1); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } /* printf("\n. Closing node with name '%s'",node->name); */ if(node->parent) { parent = parent->parent; node = parent; } } else if(buffer[0] == '?') { while((c = fgetc(fp)) != EOF) { if (c == '>' && bufptr > buffer && bufptr[-1] == '?') break; else if (XML_Add_Character(c, &bufptr, &buffer, &bufsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } if(c != '>') { PhyML_Printf("\n== An error occurred when reading the processing instruction."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } *bufptr = '\0'; } else // Open tag { node = XML_Make_Node(buffer); XML_Init_Node(parent,node,buffer); if(!parent) parent = node; if(isspace(c) != NO) c=XML_Parse_Element(fp,node); else if(c == '/') { if((c=fgetc(fp)) != '>') { PhyML_Printf("\n== Expected '>' but read '%c' instead",c); Exit("\n"); } c = '/'; } if(c != '/') parent = node; buffer[0] = '\0'; } bufptr = buffer; } else if(isspace(c) == NO) { if(XML_Add_Character(c,&bufptr,&buffer,&bufsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } Free(buffer); return node; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Add_Character(int c, char **bufptr, char **buffer, int *bufsize) { char *newbuffer; if(*bufptr >= (*buffer + *bufsize - 4)) { // Increase the size of the buffer... if (*bufsize < 1024) (*bufsize) *= 2; else (*bufsize) += 1024; if((newbuffer = realloc(*buffer, *bufsize)) == NULL) { Free(*buffer); PhyML_Printf("\n== Unable to expand string buffer to %d bytes!", *bufsize); Exit("\n"); } *bufptr = newbuffer + (*bufptr - *buffer); *buffer = newbuffer; } /* *(*bufptr)++ = tolower(c); */ *(*bufptr)++ = c; return 0; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Parse_Element(FILE *fp, xml_node *n) { int c; int quote; char *name, *value, *ptr; int namesize, valsize; name = (char *)mCalloc(64,sizeof(char)); value = (char *)mCalloc(64,sizeof(char)); namesize = 64; valsize = 64; while((c = fgetc(fp)) != EOF) { if(isspace(c) != NO) continue; if(c == '/') // End of tag { /* printf("\n. Closing node '%s'.",n->name); */ quote = fgetc(fp); if(quote != '>') { PhyML_Printf("\n== Expected '>' after '%c' but read '%c' instead",c,quote); Exit("\n"); } break; } else if(c == '<') { Exit("\n== Bare < in element!"); } else if(c == '>') // End of tag { break; } name[0] = c; ptr = name + 1; if(c == '\"' || c == '\'') // Name is in quotes { quote = c; while((c = fgetc(fp)) != EOF) { if(XML_Add_Character(c,&ptr,&name,&namesize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(c == quote) break; } } else // Name not in quotes { while((c = fgetc(fp)) != EOF) { if(isspace(c) != NO || c == '=' || c == '/' || c == '>' || c == '?') break; else { if(XML_Add_Character(c,&ptr,&name,&namesize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } } *ptr = '\0'; while(c != EOF && isspace(c) != NO) c = fgetc(fp); if(c == '=') // Read the attribute value { while((c = fgetc(fp)) != EOF && isspace(c) != NO); if(c == EOF) { PhyML_Printf("\n== Missing value in attribute."); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(c == '\'' || c == '\"') { quote = c; ptr = value; while((c = fgetc(fp)) != EOF) { if(c == quote) break; else { if(XML_Add_Character(c,&ptr,&value,&valsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } *ptr = '\0'; } else { value[0] = c; ptr = value + 1; while((c = fgetc(fp)) != EOF) { if(isspace(c) != NO || c == '=' || c == '/' || c == '>') break; else { if(XML_Add_Character(c,&ptr,&value,&valsize)) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } } } } } /* printf("\n. Setting attribute '%s=%s' to node '%s'",name,value,n->name); */ XML_Set_Attribute(n,name,value); if(c == '>') break; } Free(name); Free(value); /* printf("\n. Return '%c'\n",c); */ return(c); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_attr *XML_Search_Attribute(xml_node *n, char *target_attr_name) { xml_attr *attr; attr = n->attr; do { if(!strcmp(attr->name,target_attr_name)) return attr; attr = attr->next; } while(attr); return(NULL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Set_Attribute(xml_node *n, char *attr_name, char *attr_value) { xml_attr *prev; char *s; prev = NULL; while(n->attr != NULL) { prev = n->attr; n->attr = n->attr->next; } n->attr = XML_Make_Attribute(prev,attr_name,attr_value); XML_Init_Attribute(n->attr); n->n_attr++; // rewind while(n->attr->prev != NULL) n->attr = n->attr->prev; s = To_Lower_String(attr_name); if(!strcmp(s,"id")) { XML_Set_Node_Id(n,attr_value); /* printf("\n. Node '%s' id is '%s'",n->name,n->id); */ } Free(s); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Set_Node_Id(xml_node *n, char *id) { XML_Make_Node_Id(n,id); strcpy(n->id,id); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Set_Node_Value(xml_node *n, char *val) { XML_Make_Node_Value(n,val); strcpy(n->value,val); return(0); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Search_Node_Generic(char *nd_name, char *attr_name, char *attr_val, int skip, xml_node *node) { xml_node *match; /* if(nd_name) printf("\n. [1] nd_name:%s attr_name:%s attr_val:%s \n", nd_name, attr_name, attr_val); */ /* else printf("\n. attr_name:%s attr_val:%s \n", attr_name, attr_val); */ /* printf("\n. name:%s child:%s next:%s ", */ /* node?node->name:"xx", */ /* node->child?node->child->name:"xx", */ /* node->next?node->next->name:"xx"); fflush(NULL); */ match = NULL; if(skip == NO && nd_name && attr_name && attr_val) { if(!strcmp(nd_name, node -> name)) { xml_attr *attr = XML_Search_Attribute(node, attr_name); if(attr && !strcmp(attr -> value, attr_val)) match = node; } } else if(skip == NO && !nd_name && attr_name && attr_val) { xml_attr *attr = XML_Search_Attribute(node, attr_name); if(attr && !strcmp(attr -> value, attr_val)) match = node; } else if(skip == NO && nd_name && !attr_name && attr_val) { if(!strcmp(nd_name, node -> name)) { do { if(!strcmp(node -> attr -> value, attr_val)) { match = node; break; } node -> attr = node -> attr -> next; if(!node -> attr) break; } while(1); } } else if(skip == NO && nd_name && attr_name && !attr_val) { if(!strcmp(nd_name, node -> name)) { do { if(!strcmp(node -> attr -> name, attr_name)) { match = node; break; } node -> attr = node -> attr -> next; if(!node -> attr) break; } while(1); } } else if(skip == NO && nd_name && !attr_name && !attr_val) { if(!strcmp(nd_name, node -> name)) match = node; } else if(skip == NO && !nd_name && attr_name && !attr_val) { xml_attr *attr = XML_Search_Attribute(node, attr_name); if(attr) match = node; } else if(skip == NO && !nd_name && !attr_name && attr_val) { do { if(!strcmp(node -> attr -> value, attr_val)) { match = node; break; } node -> attr = node -> attr -> next; if(!node -> attr) break; } while(1); } // If node has a child, node = child, else if node has next, node = next, else if node // has parent, node = parent->next else node = NULL if(match) return(match); if(node -> child) { match = XML_Search_Node_Generic(nd_name, attr_name, attr_val, NO, node -> child); } if(!match && node -> next) { match = XML_Search_Node_Generic(nd_name, attr_name, attr_val, NO, node -> next); } if(match == NULL && node -> parent) { if(node -> parent == NULL) // Reached the root { PhyML_Printf("\n== Could not find a node with name '%s'.", attr_name); Exit("\n"); } return NULL; } return match; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Search_Node_Name(char *name, int skip, xml_node *node) { xml_node *match; /* printf("\n. name:%s child:%s next:%s ", */ /* node?node->name:"xx", */ /* node->child?node->child->name:"xx", */ /* node->next?node->next->name:"xx"); fflush(NULL); */ match = NULL; if(skip == NO && !strcmp(node->name,name)) match = node; else { // If node has a child, node = child, else if node has next, node = next, else if node // has parent, node = parent->next else node = NULL if(node->child) { match = XML_Search_Node_Name(name,NO,node->child); } if(match == NULL && node->next) { match = XML_Search_Node_Name(name,NO,node->next); } if(match == NULL && node->parent) { if(node->parent == NULL) // Reached the root { PhyML_Printf("\n== Could not find a node with name '%s'.",name); Exit("\n"); } return NULL; } } return match; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Search_Node_ID(char *id, int skip, xml_node *node) { xml_node *match; if(!node) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } match = NULL; if(skip == NO && node->id && !strcmp(node->id,id)) match = node; else { // If node has a child, node = child, else if node has next, node = next, else if node // has parent, node = parent->next else node = NULL if(node->child) { match = XML_Search_Node_ID(id,NO,node->child); } if(match == NULL && node->next) { match = XML_Search_Node_ID(id,NO,node->next); } if(match == NULL && node->parent) { if(node->parent == NULL) // Reached the root { PhyML_Printf("\n== Could not find a node with id '%s'.",id); Exit("\n"); } return NULL; } } return match; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// xml_node *XML_Search_Node_Attribute_Value(char *attr_name, char *value, int skip, xml_node *node) { xml_node *match; if(!node) { PhyML_Printf("\n== node: %p attr: %p",node,node?node->attr:NULL); PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } match = NULL; if(skip) { match = XML_Search_Node_Attribute_Value(attr_name, value, NO, node->child); return match; } if(skip == NO && node->attr) { xml_attr *attr; char *sname, *sval; attr = node->attr; do { sname = To_Lower_String(attr->name); sval = To_Lower_String(attr->value); if(!strcmp(sname,attr_name) && !strcmp(sval,value)) { match = node; Free(sname); Free(sval); break; } Free(sname); Free(sval); attr = attr->next; if(!attr) break; } while(1); } if(match) return(match); if(node->child) { match = XML_Search_Node_Attribute_Value(attr_name,value,NO,node->child); return match; } if(node->next && !match) { match = XML_Search_Node_Attribute_Value(attr_name,value,NO,node->next); return match; } return NULL; } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// char *XML_Get_Attribute_Value(xml_node *node, char *attr_name) { xml_attr *attr; attr = node->attr; while(attr && strcmp(attr->name,attr_name)) { attr = attr->next; /* if(attr == NULL) */ /* { */ /* PhyML_Printf("\n== Could not find an attribute with name '%s' in node with name '%s'.",id,node->name); */ /* Exit("\n"); */ /* } */ } return(attr?attr->value:NULL); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Validate_Attr_Int(char *target, int num, ...) { va_list args; int i; char *s,*sc_s; char *sc_target; sc_target = To_Lower_String(target); va_start(args,num); For(i,num) { s = va_arg(args, char *); sc_s = To_Lower_String(s); if(!strcmp(sc_s,sc_target)) { Free(sc_s); break; } Free(sc_s); } va_end(args); if(i == num) { i = -1; PhyML_Printf("\n== Attribute value '%s' is not valid",target); Exit("\n"); } Free(sc_target); return(i); } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// void XML_Check_Siterates_Node(xml_node *parent) { xml_node *n; int n_weights_nodes; char *rate_value = NULL; phydbl buff; int n_zeros; char *endptr; if(!parent) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } if(strcmp(parent->name,"siterates")) { PhyML_Printf("\n== Node name '%s' should be 'siterates'",parent->name); Exit("\n"); } // Check that only one 'weights' node is present n_weights_nodes = 0; n = parent->child; do { if(!strcmp(n->name,"weights")) n_weights_nodes++; if(n_weights_nodes > 1) { PhyML_Printf("\n== Only one distribution is authorized for 'siterates' nodes."); Exit("\n"); } n = n->next; if(!n) break; } while(1); // Check that one rate value is set to zero if gamma+inv model is used n = XML_Search_Node_Attribute_Value("family","gamma+inv",YES,parent); if(!n) return; else { n_zeros = 0; n = parent->child; do { if(!strcmp(n->name,"instance")) { rate_value = NULL; rate_value = XML_Get_Attribute_Value(n,"init.value"); if(rate_value) { errno = 0; buff = strtod(rate_value,&endptr); if(rate_value == endptr || errno == ERANGE) { PhyML_Printf("\n== value: %s",rate_value); PhyML_Printf("\n== Error in reading attribute 'init.value' in node 'instance'."); Exit("\n"); } if(buff < 1.E-20) n_zeros++; } } n = n->next; if(!n) break; } while(1); if(n_zeros != 1) { PhyML_Printf("\n== # of zero-rates: %d",n_zeros); PhyML_Printf("\n== Exactly one rate value has to be set to zero when using the 'gamma+inv' model."); PhyML_Printf("\n== Component id: %s",parent->id); Exit("\n"); } } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// int XML_Get_Number_Of_Classes_Siterates(xml_node *parent) { xml_node *n; int n_classes; if(!parent) { PhyML_Printf("\n== Err. in file %s at line %d\n",__FILE__,__LINE__); Generic_Exit(__FILE__,__LINE__,__FUNCTION__); } n_classes = 0; n = parent->child; do { if(!strcmp(n->name,"instance")) n_classes++; n = n->next; if(!n) break; } while(1); n = NULL; n = XML_Search_Node_Attribute_Value("family","gamma+inv",YES,parent); if(!n) return n_classes; else return n_classes-1; } ////////////////////////////////////////////////////////////// int XML_Siterates_Has_Invariants(xml_node *parent) { xml_node *n; if(!parent) { PhyML_Printf("\n== Err in file %s at line %d\n",__FILE__,__LINE__); Exit("\n"); } n = NULL; n = XML_Search_Node_Attribute_Value("family","gamma+inv",YES,parent); if(!n) return NO; else return YES; } ////////////////////////////////////////////////////////////// void XML_Count_Number_Of_Node_With_ID(char *id, int *count, xml_node *n) { if(!id) return; if(n->id && !strcmp(n->id,id)) (*count)++; if(n->child) XML_Count_Number_Of_Node_With_ID(id,count,n->child); if(n->next) XML_Count_Number_Of_Node_With_ID(id,count,n->next); } ////////////////////////////////////////////////////////////// void XML_Count_Number_Of_Node_With_Name(char *name, int *count, xml_node *n) { if(!name) return; if(n->name && !strcmp(n->name,name)) (*count)++; if(n->child) XML_Count_Number_Of_Node_With_Name(name,count,n->child); if(n->next) XML_Count_Number_Of_Node_With_Name(name,count,n->next); } ////////////////////////////////////////////////////////////// void XML_Check_Duplicate_ID(xml_node *n) { int count; count = 0; XML_Count_Number_Of_Node_With_ID(n->id,&count,n); if(count > 1) { PhyML_Printf("\n== Node ID'%s' was found in more than once.",n->id); PhyML_Printf("\n== Each ID must be unique. Please amend your XML"); PhyML_Printf("\n== file accordingly."); Exit("\n"); } if(n->child) XML_Check_Duplicate_ID(n->child); if(n->next) XML_Check_Duplicate_ID(n->next); } ////////////////////////////////////////////////////////////// xml_node *XML_Copy_XML_Graph(xml_node *root) { xml_node *cpy_root; cpy_root = XML_Make_Node(root->name); XML_Copy_XML_Node(cpy_root,root); return(cpy_root); } ////////////////////////////////////////////////////////////// void XML_Copy_XML_Node(xml_node *cpy_root, xml_node *root) { xml_attr *attr,*cpy_attr; strcpy(cpy_root->name,root->name); XML_Make_Node_Id(cpy_root,root->id); if(root->id) strcpy(cpy_root->id,root->id); XML_Make_Node_Value(cpy_root,root->value); if(root->value) strcpy(cpy_root->value,root->value); cpy_root->n_attr = root->n_attr; if(root->attr) { cpy_root->attr = XML_Make_Attribute(NULL,root->attr->name,root->attr->value); XML_Init_Attribute(cpy_root->attr); attr = root->attr; cpy_attr = cpy_root->attr; while(attr->next) { fflush(NULL); cpy_attr->next = XML_Make_Attribute(cpy_attr,attr->next->name,attr->next->value); XML_Init_Attribute(cpy_attr->next); attr = attr->next; cpy_attr = cpy_attr->next; } } if(root->child) { cpy_root->child = XML_Make_Node(root->child->name); cpy_root->child->parent = cpy_root; XML_Copy_XML_Node(cpy_root->child,root->child); } if(root->next) { cpy_root->next = XML_Make_Node(root->next->name); cpy_root->next->prev = cpy_root; XML_Copy_XML_Node(cpy_root->next,root->next); } } ////////////////////////////////////////////////////////////// void XML_Write_XML_Graph(FILE *fp, xml_node *root) { int indent; indent = 0; XML_Write_XML_Node(fp,&indent,root); } ////////////////////////////////////////////////////////////// void XML_Write_XML_Node(FILE *fp, int *indent, xml_node *root) { xml_node *n; xml_attr *attr; char *s; int i; s = (char *)mCalloc((*indent)+1,sizeof(char)); For(i,(*indent)) s[i]='\t'; s[i]='\0'; PhyML_Fprintf(fp,"\n%s",s); n = root; PhyML_Fprintf(fp,"<%s",n->name); attr = n->attr; while(attr) { PhyML_Fprintf(fp," %s=\"%s\"",attr->name,attr->value); fflush(NULL); attr = attr->next; } if(n->child) { (*indent)++; PhyML_Fprintf(fp,">"); XML_Write_XML_Node(fp,indent,n->child); PhyML_Fprintf(fp,"\n%s\n",s,n->name); (*indent)--; } else { PhyML_Fprintf(fp,"/>"); } if(n->next) XML_Write_XML_Node(fp,indent,n->next); Free(s); } ////////////////////////////////////////////////////////////// void Check_Mandatory_XML_Node(xml_node *root, char *name) { if(!XML_Search_Node_Name(name,NO,root)) { PhyML_Printf("\n== Could not find mandatory XML node with name '%s'.",name); PhyML_Printf("\n== Please amend your XML file."); Exit("\n"); } } ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// phyml-3.2.0/src/xml.h000066400000000000000000000035501263450375500144220ustar00rootroot00000000000000#include #ifndef XML_H #define XML_H #include "utilities.h" xml_node *XML_Load_File(FILE *fp); int XML_Add_Character(int c, char **bufptr, char **buffer, int *bufsize); int XML_Parse_Element(FILE *fp, xml_node *n); int XML_Set_Attribute(xml_node *n, char *attr_name, char *attr_value); xml_attr *XML_Make_Attribute(xml_attr *prev, char *attr_name, char *attr_value); void XML_Make_Node_Id(xml_node *n, char *id); int XML_Set_Node_Id(xml_node *n, char *id); int XML_Set_Node_Value(xml_node *n, char *val); void XML_Make_Node_Value(xml_node *n, char *val); xml_node *XML_Search_Node_Name(char *name, int skip, xml_node *node); char *XML_Get_Attribute_Value(xml_node *node, char *id); int XML_Validate_Attr_Int(char *target, int num, ...); void XML_Free_XML_Attr(xml_attr *attr); void XML_Free_XML_Node(xml_node *node); void XML_Free_XML_Tree(xml_node *node); xml_node *XML_Search_Node_ID(char *id, int skip, xml_node *node); xml_node *XML_Make_Node(char *name); xml_node *XML_Search_Node_Attribute_Value(char *attr_name, char *value, int skip, xml_node *node); void XML_Check_Siterates_Node(xml_node *prev); int XML_Get_Number_Of_Classes_Siterates(xml_node *prev); int XML_Siterates_Number_Of_Classes(xml_node *sr_node); void XML_Check_Duplicate_ID(xml_node *n); void XML_Count_Number_Of_Node_With_ID(char *id, int *count, xml_node *n); void XML_Count_Number_Of_Node_With_Name(char *name, int *count, xml_node *n); void XML_Write_XML_Graph(FILE *fp, xml_node *root); void XML_Write_XML_Node(FILE *fp, int *indent, xml_node *root); xml_attr *XML_Search_Attribute(xml_node *n, char *target_attr_name); xml_node *XML_Copy_XML_Graph(xml_node *root); void XML_Copy_XML_Node(xml_node *cpy_root, xml_node *root); void Check_Mandatory_XML_Node(xml_node *root, char *name); xml_node *XML_Search_Node_Generic(char *nd_name, char *attr_name, char *attr_val, int skip, xml_node *node); #endif phyml-3.2.0/version000066400000000000000000000000111263450375500142570ustar00rootroot00000000000000396:449M