[med-svn] [prottest] 01/02: Imported Upstream version 3.4+dfsg
Andreas Tille
tille at debian.org
Sun Sep 6 06:25:19 UTC 2015
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository prottest.
commit 051a6202331e706d5aa41881810feb8c816b146f
Author: Andreas Tille <tille at debian.org>
Date: Sun Sep 6 08:11:14 2015 +0200
Imported Upstream version 3.4+dfsg
---
COPYING | 340 +++
INSTALL | 16 +
THIRDPARTYLICENSES | 576 +++++
build.xml | 36 +
buildconf/build-impl.xml | 707 ++++++
buildconf/project.properties | 79 +
lib/AbsoluteLayout.jar | Bin 0 -> 2879 bytes
lib/copylibs.jar | Bin 0 -> 17150 bytes
lib/swing-worker-1.1.jar | Bin 0 -> 11103 bytes
manifest.mf | 8 +
.../services/org.jdesktop.application.Application | 1 +
.../java/es/uvigo/darwin/prottest/ProtTest.java | 363 +++
.../uvigo/darwin/prottest/consensus/Consensus.java | 911 +++++++
.../uvigo/darwin/prottest/consensus/package.html | 20 +
.../darwin/prottest/exe/AminoAcidRunEstimator.java | 66 +
.../prottest/exe/ExternalExecutionManager.java | 108 +
.../darwin/prottest/exe/ExternalExecutor.java | 97 +
.../prottest/exe/ParallelModelEstimator.java | 154 ++
.../prottest/exe/PhyMLv3AminoAcidRunEstimator.java | 464 ++++
.../darwin/prottest/exe/PhymlStreamGobbler.java | 65 +
.../prottest/exe/RaxMLAminoAcidRunEstimator.java | 341 +++
.../darwin/prottest/exe/RaxMLStreamGobbler.java | 60 +
.../es/uvigo/darwin/prottest/exe/RunEstimator.java | 60 +
.../darwin/prottest/exe/RunEstimatorImpl.java | 212 ++
.../uvigo/darwin/prottest/exe/StreamGobbler.java | 53 +
.../java/es/uvigo/darwin/prottest/exe/package.html | 30 +
.../prottest/exe/util/TemporaryFileManager.java | 256 ++
.../es/uvigo/darwin/prottest/exe/util/package.html | 21 +
.../darwin/prottest/facade/ProtTestFacade.java | 144 ++
.../darwin/prottest/facade/ProtTestFacadeImpl.java | 276 +++
.../darwin/prottest/facade/ProtTestFacadeMPJ.java | 210 ++
.../prottest/facade/ProtTestFacadeSequential.java | 135 ++
.../prottest/facade/ProtTestFacadeThread.java | 231 ++
.../uvigo/darwin/prottest/facade/TreeFacade.java | 96 +
.../darwin/prottest/facade/TreeFacadeImpl.java | 93 +
.../es/uvigo/darwin/prottest/facade/package.html | 27 +
.../facade/strategy/DistributionStrategy.java | 147 ++
.../prottest/facade/strategy/Distributor.java | 203 ++
.../strategy/DynamicDistributionStrategy.java | 162 ++
.../strategy/HybridDistributionStrategy.java | 230 ++
.../ImprovedDynamicDistributionStrategy.java | 147 ++
.../facade/strategy/MultipleDistributor.java | 246 ++
.../strategy/StaticDistributionStrategy.java | 145 ++
.../darwin/prottest/facade/strategy/package.html | 24 +
.../facade/thread/ThreadPoolSynchronizer.java | 104 +
.../darwin/prottest/facade/thread/package.html | 21 +
.../prottest/facade/util/ProtTestParameterVO.java | 144 ++
.../prottest/facade/util/SelectionChunk.java | 210 ++
.../uvigo/darwin/prottest/facade/util/package.html | 21 +
.../global/AminoAcidApplicationGlobals.java | 63 +
.../darwin/prottest/global/ApplicationGlobals.java | 70 +
.../prottest/global/ProtTestConsoleParameters.java | 74 +
.../darwin/prottest/global/ProtTestConstants.java | 111 +
.../global/RaxmlAminoAcidApplicationGlobals.java | 52 +
.../global/options/ApplicationOptions.java | 841 +++++++
.../options/SerializableApplicationOptions.java | 194 ++
.../darwin/prottest/global/options/package.html | 21 +
.../es/uvigo/darwin/prottest/global/package.html | 21 +
.../darwin/prottest/model/AminoAcidModel.java | 88 +
.../java/es/uvigo/darwin/prottest/model/Model.java | 479 ++++
.../es/uvigo/darwin/prottest/model/package.html | 22 +
.../prottest/model/state/ModelEmptyLkState.java | 89 +
.../prottest/model/state/ModelFilledLkState.java | 100 +
.../darwin/prottest/model/state/ModelLkState.java | 78 +
.../uvigo/darwin/prottest/model/state/package.html | 21 +
.../prottest/observer/ModelUpdaterObserver.java | 40 +
.../prottest/observer/ObservableModelUpdater.java | 83 +
.../es/uvigo/darwin/prottest/observer/package.html | 22 +
.../java/es/uvigo/darwin/prottest/package.html | 22 +
.../es/uvigo/darwin/prottest/selection/AIC.java | 89 +
.../es/uvigo/darwin/prottest/selection/AICc.java | 74 +
.../es/uvigo/darwin/prottest/selection/BIC.java | 87 +
.../es/uvigo/darwin/prottest/selection/DT.java | 87 +
.../prottest/selection/InformationCriterion.java | 423 ++++
.../es/uvigo/darwin/prottest/selection/LNL.java | 71 +
.../selection/model/AICSelectionModel.java | 37 +
.../selection/model/AICcSelectionModel.java | 39 +
.../selection/model/BICSelectionModel.java | 37 +
.../prottest/selection/model/DTSelectionModel.java | 54 +
.../selection/model/LNLSelectionModel.java | 37 +
.../prottest/selection/model/SelectionModel.java | 165 ++
.../darwin/prottest/selection/model/package.html | 21 +
.../uvigo/darwin/prottest/selection/package.html | 25 +
.../selection/printer/AminoAcidPrintFramework.java | 68 +
.../prottest/selection/printer/PrintFramework.java | 407 ++++
.../darwin/prottest/selection/printer/package.html | 21 +
.../java/es/uvigo/darwin/prottest/taxa/Taxon.java | 164 ++
.../uvigo/darwin/prottest/taxa/TaxonomicLevel.java | 69 +
.../es/uvigo/darwin/prottest/taxa/package.html | 21 +
.../darwin/prottest/tree/TreeDistancesCache.java | 157 ++
.../prottest/tree/TreeEuclideanDistancesCache.java | 44 +
.../es/uvigo/darwin/prottest/tree/TreeUtils.java | 516 ++++
.../uvigo/darwin/prottest/tree/WeightedTree.java | 60 +
.../es/uvigo/darwin/prottest/tree/package.html | 21 +
.../es/uvigo/darwin/prottest/util/FixedBitSet.java | 268 +++
.../darwin/prottest/util/ProtTestAlignment.java | 177 ++
.../uvigo/darwin/prottest/util/StatFramework.java | 141 ++
.../es/uvigo/darwin/prottest/util/Utilities.java | 299 +++
.../darwin/prottest/util/WriterOutputStream.java | 87 +
.../argumentparser/AminoAcidArgumentParser.java | 98 +
.../argumentparser/ProtTestArgumentParser.java | 293 +++
.../prottest/util/argumentparser/package.html | 21 +
.../prottest/util/attributable/Attributable.java | 57 +
.../util/attributable/AttributableHelper.java | 41 +
.../darwin/prottest/util/attributable/package.html | 21 +
.../util/checkpoint/CheckPointManager.java | 185 ++
.../darwin/prottest/util/checkpoint/package.html | 21 +
.../util/checkpoint/status/ApplicationStatus.java | 47 +
.../util/checkpoint/status/ProtTestStatus.java | 80 +
.../prottest/util/checkpoint/status/package.html | 21 +
.../prottest/util/collection/ModelCollection.java | 349 +++
.../util/collection/ParallelModelCollection.java | 269 +++
.../util/collection/ParallelModelQueue.java | 81 +
.../util/collection/SingleModelCollection.java | 56 +
.../darwin/prottest/util/collection/package.html | 21 +
.../AminoAcidModelNaturalComparator.java | 63 +
.../prottest/util/comparator/LKComparator.java | 44 +
.../comparator/ModelDistributionHeuristic.java | 55 +
.../util/comparator/ModelWeightComparator.java | 48 +
.../darwin/prottest/util/comparator/package.html | 21 +
.../util/exception/AlignmentParseException.java | 46 +
.../prottest/util/exception/ImportException.java | 59 +
.../util/exception/ModelOptimizationException.java | 165 ++
.../util/exception/ProtTestCheckedException.java | 42 +
.../util/exception/ProtTestInternalException.java | 45 +
.../util/exception/TreeFormatException.java | 45 +
.../prottest/util/factory/ProtTestFactory.java | 317 +++
.../darwin/prottest/util/factory/package.html | 21 +
.../prottest/util/fileio/AlignmentReader.java | 285 +++
.../darwin/prottest/util/fileio/ImportHelper.java | 573 +++++
.../darwin/prottest/util/fileio/NexusExporter.java | 248 ++
.../darwin/prottest/util/fileio/NexusImporter.java | 686 ++++++
.../prottest/util/fileio/NexusTreeReader.java | 71 +
.../util/fileio/SimpleNewickTreeReader.java | 135 ++
.../darwin/prottest/util/fileio/TreeReader.java | 43 +
.../util/logging/ProtTestLogFormatter.java | 47 +
.../prottest/util/logging/ProtTestLogger.java | 361 +++
.../es/uvigo/darwin/prottest/util/package.html | 21 +
.../util/printer/ProtTestFormattedOutput.java | 182 ++
.../prottest/util/printer/ProtTestPrinter.java | 200 ++
.../java/es/uvigo/darwin/xprottest/CreditsBox.java | 80 +
.../es/uvigo/darwin/xprottest/PreferencesView.java | 197 ++
.../uvigo/darwin/xprottest/XProtTestAboutBox.java | 229 ++
.../es/uvigo/darwin/xprottest/XProtTestApp.java | 97 +
.../es/uvigo/darwin/xprottest/XProtTestView.java | 1138 +++++++++
.../darwin/xprottest/analysis/FrequenciesView.java | 128 +
.../uvigo/darwin/xprottest/analysis/TreeView.java | 282 +++
.../darwin/xprottest/analysis/TreeWrapper.java | 44 +
.../xprottest/analysis/consensus/Consensus.java | 690 ++++++
.../consensus/resources/Consensus.properties | 49 +
.../analysis/resources/FrequenciesView.properties | 4 +
.../analysis/resources/TreeView.properties | 28 +
.../darwin/xprottest/compute/OptionsView.java | 748 ++++++
.../darwin/xprottest/compute/RunningFrame.java | 261 ++
.../compute/resources/OptionsView.properties | 62 +
.../compute/resources/RunningFrame.properties | 12 +
.../xprottest/resources/CreditsBox.properties | 16 +
.../xprottest/resources/PreferencesView.properties | 24 +
.../resources/XProtTestAboutBox.properties | 19 +
.../xprottest/resources/XProtTestApp.properties | 38 +
.../xprottest/resources/XProtTestView.properties | 91 +
.../es/uvigo/darwin/xprottest/resources/about.png | Bin 0 -> 8187 bytes
.../xprottest/resources/busyicons/busy-icon0.png | Bin 0 -> 3588 bytes
.../xprottest/resources/busyicons/busy-icon1.png | Bin 0 -> 3585 bytes
.../xprottest/resources/busyicons/busy-icon10.png | Bin 0 -> 3568 bytes
.../xprottest/resources/busyicons/busy-icon11.png | Bin 0 -> 3581 bytes
.../xprottest/resources/busyicons/busy-icon12.png | Bin 0 -> 3589 bytes
.../xprottest/resources/busyicons/busy-icon13.png | Bin 0 -> 3586 bytes
.../xprottest/resources/busyicons/busy-icon14.png | Bin 0 -> 3586 bytes
.../xprottest/resources/busyicons/busy-icon2.png | Bin 0 -> 3585 bytes
.../xprottest/resources/busyicons/busy-icon3.png | Bin 0 -> 3572 bytes
.../xprottest/resources/busyicons/busy-icon4.png | Bin 0 -> 3576 bytes
.../xprottest/resources/busyicons/busy-icon5.png | Bin 0 -> 3580 bytes
.../xprottest/resources/busyicons/busy-icon6.png | Bin 0 -> 3581 bytes
.../xprottest/resources/busyicons/busy-icon7.png | Bin 0 -> 3598 bytes
.../xprottest/resources/busyicons/busy-icon8.png | Bin 0 -> 3594 bytes
.../xprottest/resources/busyicons/busy-icon9.png | Bin 0 -> 3581 bytes
.../xprottest/resources/busyicons/idle-icon.png | Bin 0 -> 3360 bytes
.../darwin/xprottest/resources/prottestlogo.gif | Bin 0 -> 11850 bytes
.../es/uvigo/darwin/xprottest/resources/splash.png | Bin 0 -> 21747 bytes
.../darwin/xprottest/results/Bundle.properties | 19 +
.../darwin/xprottest/results/ErrorLogView.java | 101 +
.../darwin/xprottest/results/ResultsView.java | 2483 ++++++++++++++++++++
.../results/resources/ErrorLogView.properties | 6 +
.../results/resources/ResultsView.properties | 78 +
.../darwin/xprottest/util/BrowserLauncher.java | 583 +++++
.../util/OptimizationStrategyWrapper.java | 46 +
.../darwin/xprottest/util/TextAreaAppender.java | 31 +
.../darwin/xprottest/util/TextAreaWriter.java | 31 +
src/main/resources/CHANGELOG | 40 +
src/main/resources/COPYING | 340 +++
src/main/resources/README | 311 +++
src/main/resources/THIRDPARTYLICENSES | 576 +++++
src/main/resources/examples/COX2_PF0016/alignment | 30 +
src/main/resources/examples/COX2_PF0016/tree | 1 +
src/main/resources/examples/HIV1.2008.pol.nex | 37 +
.../examples/Ribosomal_L5_PF00673/alignment | 23 +
.../resources/examples/Ribosomal_L5_PF00673/tree | 9 +
src/main/resources/filecluster8.conf.template | 8 +
src/main/resources/machines | 1 +
src/main/resources/models/FLU | 22 +
src/main/resources/mpj.tar.gz | Bin 0 -> 3293593 bytes
src/main/resources/prottest.properties | 102 +
src/main/resources/runProtTestHPC.sh | 4 +
src/main/resources/runXProtTestHPC.bat | 1 +
src/main/resources/runXProtTestHPC.sh | 1 +
src/test/resources/VertCOII.trees | 8 +
src/test/resources/VertCOII.trprobs | 26 +
src/test/resources/testConsensus.sh | 6 +
src/test/resources/treeweights | 25 +
210 files changed, 28987 insertions(+)
diff --git a/COPYING b/COPYING
new file mode 100755
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <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 Library General
+Public License instead of this License.
diff --git a/INSTALL b/INSTALL
new file mode 100755
index 0000000..0300dbb
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,16 @@
+Basic Installation
+==================
+
+1. Requirements:
+
+* Apache ant
+ http://ant.apache.org/manual/install.html
+* Java JDK 1.6
+ http://www.java.com/en/download
+
+2. In a command-line window type:
+
+$ cd $PROTTEST_HOME
+$ ant jar
+
+3. The distribution will be built in $PROTTEST_HOME/dist/
diff --git a/THIRDPARTYLICENSES b/THIRDPARTYLICENSES
new file mode 100755
index 0000000..e725d98
--- /dev/null
+++ b/THIRDPARTYLICENSES
@@ -0,0 +1,576 @@
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'MPJ Express'
+http://mpj-express.org
++++++++++++++++++++++++++++++++++++++++++++
+
+1. The license statement
+
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2007)
+ 3. Bryan Carpenter (2005 - 2007)
+ 4. Mark Baker (2005 - 2007)
+
+ The bulk of code in this distribution was developed by the Distributed Systems
+ Group at the University of Portsmouth. Some sections of the code like
+ the buffering API and derived datatypes include contributions developed at
+ the Community Grids Lab at Indiana University.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+2. MPJ uses two third party softwares: Jetty and Java Service Wrapper project.
+ The licenses for these two projects can be seen in
+ $MPJ_HOME/THIRDPARTYLICENSES file.
+
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'PAL' Library
+http://www.cebl.auckland.ac.nz/pal-project/
++++++++++++++++++++++++++++++++++++++++++++
+
+Copyright (c) 1999-2002 by the PAL Development Core Team
+This package may be distributed under the terms of the
+GNU Lesser General Public License (LGPL):
+http://www.cebl.auckland.ac.nz/pal-project/license.html
+
+PAL Development Core Team:
+
+Alexei Drummond, School of Biological Sciences, University of Auckland
+Korbinian Strimmer, Department of Zoology, University of Oxford
+Ed Buckler, Department of Genetics, North Carolina State University
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'PhyML' Library
+http://code.google.com/p/phyml/
++++++++++++++++++++++++++++++++++++++++++++
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <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 Library General
+Public License instead of this License.
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'Alter' Library
+http://sing.ei.uvigo.es/ALTER
++++++++++++++++++++++++++++++++++++++++++++
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/build.xml b/build.xml
new file mode 100755
index 0000000..3c418a9
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<project name="ProtTest" default="default" basedir=".">
+ <description>Builds, tests, and runs the project ProtTest.</description>
+ <import file="buildconf/build-impl.xml"/>
+
+ <property name="src.resources.dir" value="src/main/resources"/>
+ <property name="prottest.lib" value="lib"/>
+
+ <target name="-post-jar">
+ <mkdir dir="${dist.dir}/bin"/>
+ <copy todir="${dist.dir}/bin">
+ <fileset dir="${dist.dir}/bin">
+ <include name="**/*"/>
+ </fileset>
+ </copy>
+ <copy todir="${dist.dir}">
+ <fileset dir="${src.resources.dir}">
+ <include name="**/*"/>
+ </fileset>
+ </copy>
+ <mkdir dir="${dist.dir}/lib"/>
+ <copy todir="${dist.dir}/lib">
+ <fileset dir="${prottest.lib}">
+ <include name="**/*"/>
+ </fileset>
+ </copy>
+ <chmod perm="755" dir="${dist.dir}/bin" includes="*"/>
+ <chmod perm="755" dir="${dist.dir}" includes="runProtTestHPC.sh"/>
+ <chmod perm="755" dir="${dist.dir}" includes="runXProtTestHPC.sh"/>
+
+ <delete file="${dist.dir}/README.TXT"/>
+ </target>
+</project>
diff --git a/buildconf/build-impl.xml b/buildconf/build-impl.xml
new file mode 100755
index 0000000..87cdf6d
--- /dev/null
+++ b/buildconf/build-impl.xml
@@ -0,0 +1,707 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT ***
+*** EDIT ../build.xml INSTEAD ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+ - initialization
+ - compilation
+ - jar
+ - execution
+ - debugging
+ - javadoc
+ - junit compilation
+ - junit execution
+ - junit debugging
+ - applet
+ - cleanup
+
+ -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="ProtTest-HPC-impl">
+ <fail message="Please build using Ant 1.7.1 or higher.">
+ <condition>
+ <not>
+ <antversion atleast="1.7.1"/>
+ </not>
+ </condition>
+ </fail>
+ <target depends="jar,javadoc" description="Build and test whole project." name="default"/>
+ <!--
+ ======================
+ INITIALIZATION SECTION
+ ======================
+ -->
+ <target name="-pre-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init" name="-init-user">
+ <property file="${user.properties.file}"/>
+ <!-- The two properties below are usually overridden -->
+ <!-- by the active platform. Just a fallback. -->
+ <property name="default.javac.source" value="1.4"/>
+ <property name="default.javac.target" value="1.4"/>
+ </target>
+ <target depends="-pre-init,-init-user" name="-init-project">
+ <property file="buildconf/configs/${config}.properties"/>
+ <property file="buildconf/project.properties"/>
+ </target>
+ <target depends="-pre-init,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+ <available file="${manifest.file}" property="manifest.available"/>
+ <available file="${application.splash}" property="splashscreen.available"/>
+ <condition property="main.class.available">
+ <and>
+ <isset property="main.class"/>
+ <not>
+ <equals arg1="${main.class}" arg2="" trim="true"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="manifest.available+main.class">
+ <and>
+ <isset property="manifest.available"/>
+ <isset property="main.class.available"/>
+ </and>
+ </condition>
+ <condition property="do.mkdist">
+ <and>
+ <isset property="libs.CopyLibs.classpath"/>
+ <not>
+ <istrue value="${mkdist.disabled}"/>
+ </not>
+ </and>
+ </condition>
+ <condition property="manifest.available+main.class+mkdist.available">
+ <and>
+ <istrue value="${manifest.available+main.class}"/>
+ <isset property="do.mkdist"/>
+ </and>
+ </condition>
+ <condition property="manifest.available+main.class+mkdist.available+splashscreen.available">
+ <and>
+ <istrue value="${manifest.available+main.class+mkdist.available}"/>
+ <istrue value="${splashscreen.available}"/>
+ </and>
+ </condition>
+ <condition property="do.archive">
+ <not>
+ <istrue value="${jar.archive.disabled}"/>
+ </not>
+ </condition>
+ <condition property="do.archive+manifest.available">
+ <and>
+ <isset property="manifest.available"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available+main.class">
+ <and>
+ <istrue value="${manifest.available+main.class}"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available+main.class+mkdist.available">
+ <and>
+ <istrue value="${manifest.available+main.class+mkdist.available}"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available">
+ <and>
+ <istrue value="${manifest.available+main.class+mkdist.available+splashscreen.available}"/>
+ <istrue value="${do.archive}"/>
+ </and>
+ </condition>
+ <condition property="have.tests">
+ <or/>
+ </condition>
+ <condition property="have.sources">
+ <or>
+ <available file="${src.java.dir}"/>
+ </or>
+ </condition>
+ <condition property="netbeans.home+have.tests">
+ <and>
+ <isset property="netbeans.home"/>
+ <isset property="have.tests"/>
+ </and>
+ </condition>
+ <condition property="no.javadoc.preview">
+ <and>
+ <isset property="javadoc.preview"/>
+ <isfalse value="${javadoc.preview}"/>
+ </and>
+ </condition>
+ <property name="run.jvmargs" value=""/>
+ <property name="javac.compilerargs" value=""/>
+ <property name="work.dir" value="${basedir}"/>
+ <condition property="no.deps">
+ <and>
+ <istrue value="${no.dependencies}"/>
+ </and>
+ </condition>
+ <property name="javac.debug" value="true"/>
+ <property name="javadoc.preview" value="true"/>
+ <property name="application.args" value=""/>
+ <property name="source.encoding" value="${file.encoding}"/>
+ <property name="runtime.encoding" value="${source.encoding}"/>
+ <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+ <and>
+ <isset property="javadoc.encoding"/>
+ <not>
+ <equals arg1="${javadoc.encoding}" arg2=""/>
+ </not>
+ </and>
+ </condition>
+ <property name="javadoc.encoding.used" value="${source.encoding}"/>
+ <property name="includes" value="**"/>
+ <property name="excludes" value=""/>
+ <property name="do.depend" value="false"/>
+ <condition property="do.depend.true">
+ <istrue value="${do.depend}"/>
+ </condition>
+ <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+ <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+ <length length="0" string="${endorsed.classpath}" when="greater"/>
+ </condition>
+ <property name="javac.fork" value="false"/>
+ <property name="jar.index" value="false"/>
+ <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+ </target>
+ <target name="-post-init">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="-pre-init,-init-user,-init-project,-do-init" name="-init-check">
+ <fail unless="src.java.dir">Must set src.java.dir</fail>
+ <fail unless="build.dir">Must set build.dir</fail>
+ <fail unless="dist.dir">Must set dist.dir</fail>
+ <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+ <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+ <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+ <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+ <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+ <fail unless="dist.jar">Must set dist.jar</fail>
+ </target>
+ <target name="-init-macrodef-property">
+ <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute name="name"/>
+ <attribute name="value"/>
+ <sequential>
+ <property name="@{name}" value="${@{value}}"/>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.java.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <mkdir dir="@{apgeneratedsrcdir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <compilerarg value="-processorpath"/>
+ <compilerarg path="@{processorpath}:${empty.dir}"/>
+ <compilerarg line="${ap.processors.internal}"/>
+ <compilerarg line="${annotation.processing.processor.options}"/>
+ <compilerarg value="-s"/>
+ <compilerarg path="@{apgeneratedsrcdir}"/>
+ <compilerarg line="${ap.proc.none.internal}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+ <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.java.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <attribute default="${javac.processorpath}" name="processorpath"/>
+ <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="${javac.debug}" name="debug"/>
+ <attribute default="${empty.dir}" name="sourcepath"/>
+ <attribute default="${empty.dir}" name="gensrcdir"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.dir}/empty" name="empty.dir"/>
+ <mkdir dir="${empty.dir}"/>
+ <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+ <src>
+ <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </src>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <compilerarg line="${javac.compilerargs}"/>
+ <customize/>
+ </javac>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+ <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${src.java.dir}" name="srcdir"/>
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <attribute default="${javac.classpath}" name="classpath"/>
+ <sequential>
+ <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </depend>
+ </sequential>
+ </macrodef>
+ <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${build.classes.dir}" name="destdir"/>
+ <sequential>
+ <fail unless="javac.includes">Must set javac.includes</fail>
+ <pathconvert pathsep="," property="javac.includes.binary">
+ <path>
+ <filelist dir="@{destdir}" files="${javac.includes}"/>
+ </path>
+ <globmapper from="*.java" to="*.class"/>
+ </pathconvert>
+ <delete>
+ <files includes="${javac.includes.binary}"/>
+ </delete>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-junit">
+ <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${includes}" name="includes"/>
+ <attribute default="${excludes}" name="excludes"/>
+ <attribute default="**" name="testincludes"/>
+ <sequential>
+ <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" showoutput="true" tempdir="${build.dir}">
+ <batchtest todir="${build.test.results.dir}"/>
+ <classpath>
+ <path path="${run.test.classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="test-sys-prop."/>
+ <mapper from="test-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <formatter type="brief" usefile="false"/>
+ <formatter type="xml"/>
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ </junit>
+ </sequential>
+ </macrodef>
+ </target>
+ <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+ <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="name"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <attribute default="" name="stopclassname"/>
+ <sequential>
+ <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ </nbjpdastart>
+ </sequential>
+ </macrodef>
+ <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${build.classes.dir}" name="dir"/>
+ <sequential>
+ <nbjpdareload>
+ <fileset dir="@{dir}" includes="${fix.classes}">
+ <include name="${fix.includes}*.class"/>
+ </fileset>
+ </nbjpdareload>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-debug-args">
+ <property name="version-output" value="java version "${ant.java.version}"/>
+ <condition property="have-jdk-older-than-1.4">
+ <or>
+ <contains string="${version-output}" substring="java version "1.0"/>
+ <contains string="${version-output}" substring="java version "1.1"/>
+ <contains string="${version-output}" substring="java version "1.2"/>
+ <contains string="${version-output}" substring="java version "1.3"/>
+ </or>
+ </condition>
+ <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+ <istrue value="${have-jdk-older-than-1.4}"/>
+ </condition>
+ <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+ <os family="windows"/>
+ </condition>
+ <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+ <isset property="debug.transport"/>
+ </condition>
+ </target>
+ <target depends="-init-debug-args" name="-init-macrodef-debug">
+ <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${debug.classpath}" name="classpath"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg line="${debug-args-line}"/>
+ <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-java">
+ <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <attribute default="${main.class}" name="classname"/>
+ <attribute default="${run.classpath}" name="classpath"/>
+ <element name="customize" optional="true"/>
+ <sequential>
+ <java classname="@{classname}" dir="${work.dir}" fork="true">
+ <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+ <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+ <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+ <jvmarg line="${run.jvmargs}"/>
+ <classpath>
+ <path path="@{classpath}"/>
+ </classpath>
+ <syspropertyset>
+ <propertyref prefix="run-sys-prop."/>
+ <mapper from="run-sys-prop.*" to="*" type="glob"/>
+ </syspropertyset>
+ <customize/>
+ </java>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-macrodef-copylibs">
+ <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+ <element name="customize" optional="true"/>
+ <sequential>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <pathconvert property="run.classpath.without.build.classes.dir">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to=""/>
+ </pathconvert>
+ <pathconvert pathsep=" " property="jar.classpath">
+ <path path="${run.classpath.without.build.classes.dir}"/>
+ <chainedmapper>
+ <flattenmapper/>
+ <globmapper from="*" to="lib/*"/>
+ </chainedmapper>
+ </pathconvert>
+ <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+ <copylibs compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifest="${manifest.file}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+ <fileset dir="${build.classes.dir}"/>
+ <manifest>
+ <attribute name="Class-Path" value="${jar.classpath}"/>
+ <customize/>
+ </manifest>
+ </copylibs>
+ </sequential>
+ </macrodef>
+ </target>
+ <target name="-init-presetdef-jar">
+ <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+ <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}">
+ <j2seproject1:fileset dir="${build.classes.dir}"/>
+ </jar>
+ </presetdef>
+ </target>
+ <target name="-init-ap-cmdline-properties">
+ <property name="annotation.processing.enabled" value="true"/>
+ <property name="annotation.processing.processors.list" value=""/>
+ <property name="annotation.processing.processor.options" value=""/>
+ <property name="annotation.processing.run.all.processors" value="true"/>
+ <property name="javac.processorpath" value="${javac.classpath}"/>
+ <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+ <condition property="ap.supported.internal" value="true">
+ <not>
+ <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+ <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+ <isfalse value="${annotation.processing.run.all.processors}"/>
+ </condition>
+ <condition else="" property="ap.proc.none.internal" value="-proc:none">
+ <isfalse value="${annotation.processing.enabled}"/>
+ </condition>
+ </target>
+ <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+ <property name="ap.cmd.line.internal" value=""/>
+ </target>
+ <target depends="-pre-init,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-junit,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+ <!--
+ ===================
+ COMPILATION SECTION
+ ===================
+ -->
+ <target name="-deps-jar-init" unless="built-jar.properties">
+ <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+ <delete file="${built-jar.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+ <echo level="warn" message="Cycle detected: ProtTest-HPC was already built"/>
+ </target>
+ <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-jar.properties}" verbose="false"/>
+ <property file="${built-jar.properties}" prefix="already.built.jar."/>
+ <antcall target="-warn-already-built-jar"/>
+ <propertyfile file="${built-jar.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+ <target depends="init" name="-check-automatic-build">
+ <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+ </target>
+ <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+ <antcall target="clean"/>
+ </target>
+ <target depends="init,deps-jar" name="-pre-pre-compile">
+ <mkdir dir="${build.classes.dir}"/>
+ </target>
+ <target name="-pre-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target if="do.depend.true" name="-compile-depend">
+ <pathconvert property="build.generated.subdirs">
+ <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="*"/>
+ </dirset>
+ </pathconvert>
+ <j2seproject3:depend srcdir="${src.java.dir}:${build.generated.subdirs}"/>
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+ <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+ <copy todir="${build.classes.dir}">
+ <fileset dir="${src.java.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+ </copy>
+ </target>
+ <target if="has.persistence.xml" name="-copy-persistence-xml">
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy todir="${build.classes.dir}/META-INF">
+ <fileset dir="${meta.inf.dir}" includes="persistence.xml"/>
+ </copy>
+ </target>
+ <target name="-post-compile">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+ <target name="-pre-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+ <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+ <j2seproject3:force-recompile/>
+ <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.java.dir}"/>
+ </target>
+ <target name="-post-compile-single">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+ <!--
+ ====================
+ JAR BUILDING SECTION
+ ====================
+ -->
+ <target depends="init" name="-pre-pre-jar">
+ <dirname file="${dist.jar}" property="dist.jar.dir"/>
+ <mkdir dir="${dist.jar.dir}"/>
+ </target>
+ <target name="-pre-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive" name="-do-jar-without-manifest" unless="manifest.available">
+ <j2seproject1:jar/>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available" name="-do-jar-with-manifest" unless="manifest.available+main.class">
+ <j2seproject1:jar manifest="${manifest.file}"/>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar" if="do.archive+manifest.available+main.class" name="-do-jar-with-mainclass" unless="manifest.available+main.class+mkdist.available">
+ <j2seproject1:jar manifest="${manifest.file}">
+ <j2seproject1:manifest>
+ <j2seproject1:attribute name="Main-Class" value="${main.class}"/>
+ </j2seproject1:manifest>
+ </j2seproject1:jar>
+ <echo>To run this application from the command line without Ant, try:</echo>
+ <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <pathconvert property="run.classpath.with.dist.jar">
+ <path path="${run.classpath}"/>
+ <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+ </pathconvert>
+ <echo>java -cp "${run.classpath.with.dist.jar}" ${main.class}</echo>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available+splashscreen.available" name="-do-jar-with-libraries-and-splashscreen">
+ <basename file="${application.splash}" property="splashscreen.basename"/>
+ <mkdir dir="${build.classes.dir}/META-INF"/>
+ <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+ <j2seproject3:copylibs>
+ <customize>
+ <attribute name="Main-Class" value="${main.class}"/>
+ <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+ </customize>
+ </j2seproject3:copylibs>
+ <echo>To run this application from the command line without Ant, try:</echo>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <echo>java -jar "${dist.jar.resolved}"</echo>
+ </target>
+ <target depends="init,compile,-pre-pre-jar,-pre-jar,-init-macrodef-copylibs" if="do.archive+manifest.available+main.class+mkdist.available" name="-do-jar-with-libraries" unless="splashscreen.available">
+ <j2seproject3:copylibs>
+ <customize>
+ <attribute name="Main-Class" value="${main.class}"/>
+ </customize>
+ </j2seproject3:copylibs>
+ <echo>To run this application from the command line without Ant, try:</echo>
+ <property location="${dist.jar}" name="dist.jar.resolved"/>
+ <echo>java -jar "${dist.jar.resolved}"</echo>
+ </target>
+ <target name="-post-jar">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries-and-splashscreen,-do-jar-with-libraries,-post-jar" description="Build JAR." name="jar"/>
+ <!--
+ =================
+ EXECUTION SECTION
+ =================
+ -->
+ <target depends="init,compile" description="Run a main class." name="run">
+ <j2seproject1:java>
+ <customize>
+ <arg line="${application.args}"/>
+ </customize>
+ </j2seproject1:java>
+ </target>
+ <target name="-do-not-recompile">
+ <property name="javac.includes.binary" value=""/>
+ </target>
+ <target depends="init,compile-single" name="run-single">
+ <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+ <j2seproject1:java classname="${run.class}"/>
+ </target>
+
+ <!--
+ ===============
+ JAVADOC SECTION
+ ===============
+ -->
+ <target depends="init" if="have.sources" name="-javadoc-build">
+ <mkdir dir="${dist.javadoc.dir}"/>
+ <javadoc additionalparam="${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+ <classpath>
+ <path path="${javac.classpath}"/>
+ </classpath>
+ <fileset dir="${src.java.dir}" excludes="${excludes}" includes="${includes}">
+ <filename name="**/*.java"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/*.java"/>
+ </fileset>
+ </javadoc>
+ <copy todir="${dist.javadoc.dir}">
+ <fileset dir="${src.java.dir}" excludes="${excludes}" includes="${includes}">
+ <filename name="**/doc-files/**"/>
+ </fileset>
+ <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+ <include name="**/doc-files/**"/>
+ </fileset>
+ </copy>
+ </target>
+ <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+ <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+ </target>
+ <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+
+ <!--
+ ===============
+ CLEANUP SECTION
+ ===============
+ -->
+ <target name="-deps-clean-init" unless="built-clean.properties">
+ <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+ <delete file="${built-clean.properties}" quiet="true"/>
+ </target>
+ <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+ <echo level="warn" message="Cycle detected: ProtTest-HPC was already built"/>
+ </target>
+ <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+ <mkdir dir="${build.dir}"/>
+ <touch file="${built-clean.properties}" verbose="false"/>
+ <property file="${built-clean.properties}" prefix="already.built.clean."/>
+ <antcall target="-warn-already-built-clean"/>
+ <propertyfile file="${built-clean.properties}">
+ <entry key="${basedir}" value=""/>
+ </propertyfile>
+ </target>
+ <target depends="init" name="-do-clean">
+ <delete dir="${build.dir}"/>
+ <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+ </target>
+ <target name="-post-clean">
+ <!-- Empty placeholder for easier customization. -->
+ <!-- You can override this target in the ../build.xml file. -->
+ </target>
+ <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+ <target name="-check-call-dep">
+ <property file="${call.built.properties}" prefix="already.built."/>
+ <condition property="should.call.dep">
+ <not>
+ <isset property="already.built.${call.subproject}"/>
+ </not>
+ </condition>
+ </target>
+ <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+ <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+ <propertyset>
+ <propertyref prefix="transfer."/>
+ <mapper from="transfer.*" to="*" type="glob"/>
+ </propertyset>
+ </ant>
+ </target>
+</project>
diff --git a/buildconf/project.properties b/buildconf/project.properties
new file mode 100755
index 0000000..1434886
--- /dev/null
+++ b/buildconf/project.properties
@@ -0,0 +1,79 @@
+application.homepage=http://darwin.uvigo.es
+application.title=ProtTest
+application.vendor=Diego Darriba
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+debug.classpath=\
+ ${run.classpath}
+debug.test.classpath=\
+ ${run.test.classpath}
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/prottest-3.4.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=
+file.reference.AbsoluteLayout.jar=lib/AbsoluteLayout.jar
+file.reference.appframework-1.0.3.jar=lib/appframework-1.0.3.jar
+file.reference.alter.jar=lib/alter.jar
+file.reference.mpj.jar=lib/mpj.jar
+file.reference.pal.jar=lib/pal.jar
+file.reference.ProtTest-HPC-src=src
+file.reference.swing-worker-1.1.jar=lib/swing-worker-1.1.jar
+includes=**
+jar.compress=false
+javac.classpath=\
+ ${file.reference.AbsoluteLayout.jar}:\
+ ${file.reference.appframework-1.0.3.jar}:\
+ ${file.reference.mpj.jar}:\
+ ${file.reference.pal.jar}:\
+ ${file.reference.alter.jar}:\
+ ${file.reference.swing-worker-1.1.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=true
+javac.source=1.5
+javac.target=1.6
+javac.test.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}:\
+ ${libs.junit_4.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+# Property libs.absolutelayout.classpath is set here just to make sharing of project simpler.
+# The library definition has always preference over this property.
+libs.absolutelayout.classpath=lib/AbsoluteLayout.jar
+#libs.CopyLibs.classpath=lib/org-netbeans-modules-java-j2seproject-copylibstask.jar
+libs.CopyLibs.classpath=lib/copylibs.jar
+main.class=es.uvigo.darwin.prottest.ProtTest
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+platform.active=default_platform
+run.classpath=\
+ ${javac.classpath}:\
+ ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project
+# (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
+# or test-sys-prop.name=value to set system properties for unit tests):
+run.jvmargs=
+run.test.classpath=\
+ ${javac.test.classpath}:\
+ ${build.test.classes.dir}
+source.encoding=UTF-8
+src.java.dir=src/main/java
+test.java.dir=src/test/java
diff --git a/lib/AbsoluteLayout.jar b/lib/AbsoluteLayout.jar
new file mode 100755
index 0000000..2cd68a5
Binary files /dev/null and b/lib/AbsoluteLayout.jar differ
diff --git a/lib/copylibs.jar b/lib/copylibs.jar
new file mode 100755
index 0000000..47dcc3b
Binary files /dev/null and b/lib/copylibs.jar differ
diff --git a/lib/swing-worker-1.1.jar b/lib/swing-worker-1.1.jar
new file mode 100755
index 0000000..bcdd9d9
Binary files /dev/null and b/lib/swing-worker-1.1.jar differ
diff --git a/manifest.mf b/manifest.mf
new file mode 100755
index 0000000..cd51d93
--- /dev/null
+++ b/manifest.mf
@@ -0,0 +1,8 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.7.1
+Created-By: 19.0-b09 (Sun Microsystems Inc.)
+Main-Class: es.uvigo.darwin.prottest.ProtTest
+Class-Path: lib/AbsoluteLayout.jar lib/appframework-1.0.3.jar lib/mpj.
+ jar lib/pal.jar lib/alter.jar lib/swing-worker-1.1.jar
+X-COMMENT: Main-Class will be added automatically by build
+
diff --git a/src/main/java/META-INF/services/org.jdesktop.application.Application b/src/main/java/META-INF/services/org.jdesktop.application.Application
new file mode 100755
index 0000000..b104306
--- /dev/null
+++ b/src/main/java/META-INF/services/org.jdesktop.application.Application
@@ -0,0 +1 @@
+xprottest.XProtTestApp
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/ProtTest.java b/src/main/java/es/uvigo/darwin/prottest/ProtTest.java
new file mode 100755
index 0000000..0077f8b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/ProtTest.java
@@ -0,0 +1,363 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.prottest;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import es.uvigo.darwin.prottest.consensus.Consensus;
+import mpi.MPI;
+import es.uvigo.darwin.prottest.facade.ProtTestFacade;
+import es.uvigo.darwin.prottest.facade.ProtTestFacadeMPJ;
+import es.uvigo.darwin.prottest.facade.ProtTestFacadeSequential;
+import es.uvigo.darwin.prottest.facade.ProtTestFacadeThread;
+import es.uvigo.darwin.prottest.facade.TreeFacade;
+import es.uvigo.darwin.prottest.facade.TreeFacadeImpl;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.selection.AIC;
+import es.uvigo.darwin.prottest.selection.AICc;
+import es.uvigo.darwin.prottest.selection.BIC;
+import es.uvigo.darwin.prottest.selection.DT;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.LNL;
+import es.uvigo.darwin.prottest.selection.printer.PrintFramework;
+import es.uvigo.darwin.prottest.util.FixedBitSet;
+import es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import es.uvigo.darwin.prottest.util.printer.ProtTestPrinter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import pal.misc.Identifier;
+import pal.tree.Tree;
+
+/**
+ * This is the main class of ProtTest. It calls the methods in the
+ * concrete facade to interact with the model layer of the application.
+ *
+ * @author Diego Darriba
+ */
+public class ProtTest {
+
+ /** The Constant versionNumber. */
+ public static final String versionNumber = "3.4";
+ /** The Constant versionDate. */
+ public static final String versionDate = "23th January 2014";
+ /** The MPJ rank of the process. It is only useful if MPJ is running.*/
+ public static int MPJ_ME;
+ /** The MPJ size of the communicator. It is only useful if MPJ is running.*/
+ public static int MPJ_SIZE;
+ /** The MPJ running state. */
+ public static boolean MPJ_RUN;
+ /** The ProtTest factory. */
+ private static ProtTestFactory factory;
+
+ /**
+ * The main method. It initializes the MPJ runtime environment, parses
+ * the application arguments, initializes the application options and
+ * starts the analysis of the substitution models.
+ *
+ * @param args the arguments
+ */
+ public static void main(String[] args) {
+
+ try {
+ args = ProtTestFactory.initialize(args);
+ } catch (IllegalArgumentException e) {
+ System.out.println("Illegal argument: " + e.getMessage());
+ finalize(1);
+ }
+ factory = ProtTestFactory.getInstance();
+
+ // initializing MPJ environment (if available)
+ try {
+ String[] argsApp = MPI.Init(args);
+ MPJ_ME = MPI.COMM_WORLD.Rank();
+ MPJ_SIZE = MPI.COMM_WORLD.Size();
+ MPJ_RUN = true;
+ args = argsApp;
+ } catch (Exception e) {
+ MPJ_ME = 0;
+ MPJ_SIZE = 1;
+ MPJ_RUN = false;
+ }
+
+ ProtTestLogger logger = ProtTestLogger.getDefaultLogger();
+ logger.setStdHandlerLevel(Level.INFO);
+
+ // parse arguments
+ ApplicationOptions opts = new ApplicationOptions();
+
+ int numThreads = 1;
+ try {
+ // check arguments and get application options
+ numThreads = Integer.parseInt(
+ factory.createProtTestArgumentParser(args, opts).
+ getValue(ProtTestArgumentParser.PARAM_NUM_THREADS));
+ } catch (IllegalArgumentException e) {
+ if (MPJ_ME == 0) {
+ System.err.println("\n" + e.getMessage() + "\n");
+ ApplicationOptions.usage();
+ }
+ finalize(1);
+ } catch (ProtTestInternalException e) {
+ if (MPJ_ME == 0) {
+ System.err.println(e.getMessage());
+ }
+ finalize(1);
+ } catch (ExceptionInInitializerError e) {
+ if (MPJ_ME == 0) {
+ System.err.println("An error has occurred while initializing. Check your prottest.properties file.");
+ }
+ finalize(1);
+ }
+
+ if (MPJ_ME == 0) {
+ try {
+ if (opts.isLogEnabled()) {
+ Handler logHandler = factory.createLogHandler();
+ if (logHandler != null) {
+ logger.addHandler(logHandler);
+ }
+ }
+ } catch (IOException ex) {
+ logger.severeln(ex.getMessage());
+ }
+ }
+
+ // get the facade instance
+ TreeFacade treeFacade = new TreeFacadeImpl();
+ ProtTestFacade facade;
+ if (MPJ_RUN) {
+ facade = new ProtTestFacadeMPJ(MPJ_RUN, MPJ_ME, MPJ_SIZE);
+ } else if (numThreads > 1) {
+ facade = new ProtTestFacadeThread(numThreads);
+ } else {
+ facade = new ProtTestFacadeSequential();
+ }
+
+ /* if multiple models are optimized together, the execution will be
+ monitorized */
+ if (MPJ_RUN || numThreads > 1) {
+ facade.addObserver(new ModelUpdaterObserver() {
+
+ @Override
+ public void update(ObservableModelUpdater o, Model model,
+ ApplicationOptions options) {
+ if (model.isComputed() && options != null) {
+ System.out.println("Computed: " + model.getModelName() + " (" + model.getLk() + ")");
+ } else {
+ System.out.println("Computing " + model.getModelName() + "...");
+ }
+
+ }
+ });
+ }
+
+ if (opts.isDebug()) {
+ logger.setStdHandlerLevel(Level.ALL);
+ }
+
+ if (MPJ_ME == 0) {
+ ProtTestPrinter.printHeader();
+ opts.reportComplete();
+ }
+
+ Model[] models;
+ try {
+
+ // model optimization
+ models = facade.startAnalysis(opts);
+
+ // analyze results
+ if (MPJ_ME == 0) {
+ ModelCollection allModelsList =
+ new SingleModelCollection(models, opts.getAlignment());
+
+ InformationCriterion aic, aicc, bic, dt, lnc;
+ if (opts.isAIC()) {
+ printCriterion(
+ "AIC", new AIC(allModelsList, 1.0, opts.getSampleSize()),
+ logger, opts, facade, treeFacade);
+ }
+ if (opts.isBIC()) {
+ printCriterion(
+ "BIC", new BIC(allModelsList, 1.0, opts.getSampleSize()),
+ logger, opts, facade, treeFacade);
+ }
+ if (opts.isAICc()) {
+ printCriterion(
+ "AICc", new AICc(allModelsList, 1.0, opts.getSampleSize()),
+ logger, opts, facade, treeFacade);
+ }
+ if (opts.isDT()) {
+ printCriterion(
+ "DT", new DT(allModelsList, 1.0, opts.getSampleSize()),
+ logger, opts, facade, treeFacade);
+ }
+ if (!(opts.isAIC() | opts.isDT() | opts.isAICc() | opts.isDT())) {
+ printCriterion(
+ "lnL", new LNL(allModelsList, 1.0, opts.getSampleSize()),
+ logger, opts, facade, treeFacade);
+ }
+
+ // display 7-framework comparison
+ if (opts.isAll()) {
+ PrintFramework.printFrameworksComparison(allModelsList);
+ }
+
+ }
+
+ } catch (ProtTestInternalException e) {
+ logger.severeln(e.getMessage());
+ finalize(-1);
+ } catch (UnsupportedOperationException e) {
+ logger.severeln(e.getMessage());
+ finalize(-1);
+ }
+
+ // finalize execution
+
+ finalize(0);
+
+ if (MPJ_RUN) {
+ MPI.Finalize();
+ }
+ }
+
+ private static void printCriterion(String name, InformationCriterion ic, ProtTestLogger logger, ApplicationOptions opts,
+ ProtTestFacade facade, TreeFacade treeFacade) {
+ // let's print results:
+ facade.printModelsSorted(ic);
+
+ // display best model tree in ASCII
+ if (opts.isDisplayASCIITree()) {
+ ProtTestPrinter.printTreeHeader(ic.getBestModel().getModelName());
+ logger.infoln(treeFacade.toASCII(ic.getBestModel().getTree()));
+ }
+
+ // display best model tree in Newick
+ if (opts.isDisplayNewickTree()) {
+ if (!opts.isDisplayASCIITree()) {
+ ProtTestPrinter.printTreeHeader(ic.getBestModel().getModelName());
+ }
+ logger.infoln(treeFacade.toNewick(ic.getBestModel().getTree(), true, true, false));
+ }
+
+ // display consensus tree data
+ if (opts.isDisplayConsensusTree()) {
+
+ ProtTestPrinter.printTreeHeader("MODEL AVERAGED PHYLOGENY");
+ Consensus consensus = treeFacade.createConsensus(ic, opts.getConsensusThreshold());
+
+ logger.infoln("----------------------------------------");
+ logger.infoln("Selection criterion: . . . . " + name);
+ logger.infoln("Confidence interval: . . . . " + ic.getConfidenceInterval());
+ logger.infoln("Sample size: . . . . . . . . " + opts.getSampleSize());
+ logger.infoln("Consensus support threshold: " + opts.getConsensusThreshold());
+ logger.infoln("----------------------------------------");
+ logger.infoln("");
+
+ Set<FixedBitSet> keySet = consensus.getCladeSupport().keySet();
+ List<FixedBitSet> splitsInConsensus = new ArrayList<FixedBitSet>();
+ List<FixedBitSet> splitsOutFromConsensus = new ArrayList<FixedBitSet>();
+
+ for (FixedBitSet fbs : keySet) {
+ if (fbs.cardinality() > 1) {
+ double psupport = (1.0 * consensus.getCladeSupport().get(fbs)) / 1.0;
+ if (psupport < opts.getConsensusThreshold()) {
+ splitsOutFromConsensus.add(fbs);
+ } else {
+ splitsInConsensus.add(fbs);
+ }
+ }
+ }
+
+ logger.infoln("# # # # # # # # # # # # # # # #");
+ logger.infoln(" ");
+ logger.infoln("Species in order:");
+ logger.infoln(" ");
+
+ for (int i = 0; i < consensus.getIdGroup().getIdCount(); i++) {
+ Identifier id = consensus.getIdGroup().getIdentifier(i);
+ logger.infoln(" " + (i + 1) + ". " + id.getName());
+ }
+ logger.infoln(" ");
+ logger.infoln("# # # # # # # # # # # # # # # #");
+ logger.infoln(" ");
+ logger.infoln("Sets included in the consensus tree");
+ logger.infoln(" ");
+
+ int numTaxa = consensus.getIdGroup().getIdCount();
+ logger.infoln(consensus.getSetsIncluded());
+
+ logger.infoln(" ");
+ logger.infoln("Sets NOT included in consensus tree");
+ logger.infoln(" ");
+
+ logger.infoln(consensus.getSetsNotIncluded());
+
+ logger.infoln(" ");
+ logger.infoln("# # # # # # # # # # # # # # # #");
+ logger.infoln(" ");
+ Tree consensusTree = consensus.getConsensusTree();
+ String newickTree = treeFacade.toNewick(consensusTree, true, true, true);
+ logger.infoln(newickTree);
+ logger.infoln(" ");
+ logger.infoln("# # # # # # # # # # # # # # # #");
+ logger.infoln(" ");
+ logger.infoln(treeFacade.toASCII(consensusTree));
+ logger.infoln("");
+ logger.infoln(treeFacade.branchInfo(consensusTree));
+ logger.infoln("");
+ logger.infoln(treeFacade.heightInfo(consensusTree));
+
+ }
+ }
+
+ /**
+ * Finalizes the MPJ runtime environment. When an error occurs, it
+ * aborts the execution of every other processes.
+ *
+ * @param status the finalization status
+ */
+ public static void finalize(int status) {
+
+ if (status != 0) {
+ if (MPJ_RUN) {
+ MPI.COMM_WORLD.Abort(status);
+ }
+ }
+
+ if (MPJ_RUN) {
+ MPI.Finalize();
+ }
+
+ System.exit(status);
+
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/consensus/Consensus.java b/src/main/java/es/uvigo/darwin/prottest/consensus/Consensus.java
new file mode 100755
index 0000000..de886d7
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/consensus/Consensus.java
@@ -0,0 +1,911 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.consensus;
+
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+import es.uvigo.darwin.prottest.util.fileio.SimpleNewickTreeReader;
+import es.uvigo.darwin.prottest.util.fileio.NexusTreeReader;
+import es.uvigo.darwin.prottest.util.fileio.TreeReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.PriorityQueue;
+
+import pal.misc.IdGroup;
+import pal.tree.Node;
+import pal.tree.NodeFactory;
+import pal.tree.SimpleTree;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.tree.TreeUtils;
+import es.uvigo.darwin.prottest.util.FixedBitSet;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.exception.ImportException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.fileio.NexusExporter;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Set;
+import pal.misc.Identifier;
+
+/**
+ * Phylogenetic consensus tree builder.
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public class Consensus {
+
+ /** Display branch suport as percent. */
+ final static public boolean SUPPORT_AS_PERCENT = false;
+ /** Calculate branch lengths as weighted average. */
+ final static public int BRANCH_LENGTHS_AVERAGE = 1;
+ /** Calculate branch lengths as weighted median. */
+ final static public int BRANCH_LENGTHS_MEDIAN = 2;
+ /** Default branch lengths algorithm */
+ private static final BranchDistances DEFAULT_BRANCH_DISTANCES =
+ BranchDistances.WeightedMedian;
+ /** The Constant FIRST (just for source code visibility). */
+ private static final int FIRST = 0;
+ /** The weighted trees in consensus. */
+ private List<WeightedTree> trees;
+ /** The cummulative weight. */
+ private double cumWeight = 0.0;
+ /** The number of taxa. */
+ private int numTaxa;
+ /** The common id group of the tree set. */
+ private IdGroup idGroup;
+ /** The set of clade supports. */
+ private Map<FixedBitSet, Support> support =
+ new HashMap<FixedBitSet, Support>();
+ /** The set of clade supports to get from outside this class. */
+ private Map<FixedBitSet, Double> cladeSupport;
+ /** The inner consensus tree. */
+ private Tree consensusTree;
+ /** The splits included in consensus tree */
+ private List<FixedBitSet> splitsInConsensus = new ArrayList<FixedBitSet>();
+ /** The splits not included in consensus tree */
+ private List<FixedBitSet> splitsOutFromConsensus = new ArrayList<FixedBitSet>();
+
+ /**
+ * Gets the clade support, with Support instances
+ *
+ * @return the map of the support for each bitSet
+ */
+ private Map<FixedBitSet, Support> getSupport() {
+ return support;
+ }
+
+ /**
+ * Gets the double precision clade support
+ *
+ * @return the map of the support for each bitSet
+ */
+ public Map<FixedBitSet, Double> getCladeSupport() {
+
+ if (cladeSupport == null) {
+ cladeSupport = new HashMap<FixedBitSet, Double>(support.size());
+ FixedBitSet[] keys = support.keySet().toArray(new FixedBitSet[0]);
+ Arrays.sort(keys);
+
+ for (FixedBitSet fbs : keys) {
+ cladeSupport.put(fbs, support.get(fbs).treesWeightWithClade / cumWeight);
+ }
+ }
+ return cladeSupport;
+ }
+
+ /**
+ * Gets the Id Group of the set of trees
+ *
+ * @return the id group
+ */
+ public IdGroup getIdGroup() {
+ return idGroup;
+ }
+
+ /**
+ * Gets the consensus tree
+ *
+ * @return the consensus tree
+ */
+ public Tree getConsensusTree() {
+ return consensusTree;
+ }
+
+ /**
+ * Gets the set of trees included in the consensus.
+ *
+ * @return the trees
+ */
+ public Collection<WeightedTree> getTrees() {
+ return trees;
+ }
+
+ /**
+ * Adds a weighted tree to the set.
+ *
+ * @param wTree the weighted tree
+ *
+ * @return true, if successful
+ */
+ private boolean addTree(WeightedTree wTree) {
+ //check integrity
+ if (wTree.getTree() == null || wTree.getWeight() < 0.0) {
+ throw new ProtTestInternalException();
+ }
+ //check compatibility
+ if (trees.isEmpty()) {
+ trees.add(wTree);
+ numTaxa = wTree.getTree().getIdCount();
+ idGroup = pal.tree.TreeUtils.getLeafIdGroup(wTree.getTree());
+ } else {
+ if (wTree.getTree().getIdCount() != numTaxa) {
+ return false;
+ }
+ Tree pTree = trees.get(FIRST).getTree();
+ for (int i = 0; i < numTaxa; i++) {
+ boolean found = false;
+ for (int j = 0; j < numTaxa; j++) {
+ if (wTree.getTree().getIdentifier(i).equals(pTree.getIdentifier(j))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ System.out.println("NOT COMPATIBLE TREES");
+ return false;
+ }
+ }
+ trees.add(wTree);
+ }
+ cumWeight += wTree.getWeight();
+ return true;
+ }
+
+ /**
+ * Instantiates a new consensus tree builder.
+ *
+ * @param ic the information criterion to build the weighted trees
+ * @param supportThreshold the minimum support for a clade
+ */
+ public Consensus(InformationCriterion ic, double supportThreshold) {
+ this(ic, supportThreshold, 0);
+ }
+
+ /**
+ * Instantiates a new consensus tree builder.
+ *
+ * @param ic the information criterion to build the weighted trees
+ * @param supportThreshold the minimum support for a clade
+ * @param branchDistances the method to get the consensus branch lengths
+ */
+ public Consensus(InformationCriterion ic, double supportThreshold, int branchDistances) {
+ this.trees = new ArrayList<WeightedTree>();
+ for (SelectionModel model : ic.getConfidenceModels()) {
+ WeightedTree wTree = new WeightedTree(
+ model.getModel().getTree(),
+ model.getWeightValue());
+ this.addTree(wTree);
+ }
+ consensusTree = buildTree(supportThreshold, getBranchDistances(branchDistances));
+ }
+
+ /**
+ * Instantiates a new unweighted consensus builder.
+ *
+ * @param trees the trees
+ * @param supportThreshold the minimum support for a clade
+ * @param branchDistances the method to get the consensus branch lengths
+ */
+ public Consensus(List<WeightedTree> trees, double supportThreshold, int branchDistances) {
+ this.trees = new ArrayList<WeightedTree>();
+ for (WeightedTree tree : trees) {
+ this.addTree(tree);
+ }
+
+ consensusTree = buildTree(supportThreshold, getBranchDistances(branchDistances));
+ }
+
+ /**
+ * Instantiates a new unweighted consensus builder.
+ *
+ * @param treesFile the file with the set of trees in Newick format
+ * @param supportThreshold the minimum support for a clade
+ * @throws IOException
+ */
+ public Consensus(File treesFile, double supportThreshold)
+ throws ProtTestInternalException, IOException {
+
+ this(treesFile, supportThreshold, 0);
+
+ }
+
+ /**
+ * Instantiates a new unweighted consensus builder.
+ *
+ * @param treesFile the file with the set of trees in Newick format
+ * @param supportThreshold the minimum support for a clade
+ * @param branchDistances the method to get the consensus branch lengths
+ * @throws IOException
+ */
+ public Consensus(File treesFile, double supportThreshold, int branchDistances)
+ throws ProtTestInternalException, IOException {
+
+ TreeReader treeReader;
+
+ try {
+ treeReader = new NexusTreeReader(treesFile);
+ } catch (ImportException ex) {
+ treeReader = new SimpleNewickTreeReader(treesFile);
+ }
+
+ this.trees = treeReader.getWeightedTreeList();
+ this.cumWeight = treeReader.getCumWeight();
+ this.numTaxa = treeReader.getNumTaxa();
+ this.idGroup = treeReader.getIdGroup();
+
+ consensusTree = buildTree(supportThreshold, getBranchDistances(branchDistances));
+
+ String fileName = treesFile.getName();
+ if (fileName.contains(".")) {
+ fileName = fileName.substring(0, fileName.lastIndexOf("."));
+ }
+
+ File resultDir = new File("results");
+ if (!resultDir.exists()) {
+ resultDir.mkdir();
+ }
+ File outFile = File.createTempFile(fileName, ".con", resultDir);
+
+ NexusExporter nw = new NexusExporter(outFile);
+ nw.printConsensusBlock(consensusTree, ((NexusTreeReader) treeReader).getNexusId());
+ nw.close();
+
+ }
+
+ /**
+ * Calculates rooted support.
+ *
+ * @param wTree the weighted tree instance
+ * @param node the node
+ * @param support the support
+ *
+ * @return the fixed bit set
+ */
+ private FixedBitSet rootedSupport(WeightedTree wTree, Node node, Map<FixedBitSet, Support> support) {
+ FixedBitSet clade = new FixedBitSet(numTaxa);
+ if (node.isLeaf()) {
+ clade.set(idGroup.whichIdNumber(node.getIdentifier().getName()));
+ } else {
+ for (int i = 0; i < node.getChildCount(); i++) {
+ Node n = node.getChild(i);
+ FixedBitSet childClade = rootedSupport(wTree, n, support);
+ clade.union(childClade);
+ }
+ }
+
+ Support s = support.get(clade);
+ if (s == null) {
+ s = new Support();
+ support.put(clade, s);
+ }
+ s.add(wTree.getWeight(), TreeUtils.safeNodeHeight(wTree.getTree(), node), node.getBranchLength());
+ return clade;
+ }
+
+ /**
+ * Detach the children of a tree.
+ *
+ * @param tree the tree
+ * @param node the node to detach
+ * @param split the split
+ *
+ * @return the node
+ */
+ public Node detachChildren(Tree tree, Node node, List<Integer> split) {
+ assert (split.size() > 1);
+
+ List<Node> detached = new ArrayList<Node>();
+
+ for (int n : split) {
+ detached.add(node.getChild(n));
+ }
+
+ Node saveRoot = tree.getRoot();
+
+ List<Integer> toRemove = new ArrayList<Integer>();
+ for (int i = 0; i < node.getChildCount(); i++) {
+ Node n = node.getChild(i);
+ if (detached.contains(n)) {
+ toRemove.add(0, i);
+ }
+ }
+ for (int i : toRemove) {
+ node.removeChild(i);
+ }
+
+ Node dnode = NodeFactory.createNode(detached.toArray(new Node[0]));
+ node.addChild(dnode);
+
+ tree.setRoot(saveRoot);
+
+ return dnode;
+ }
+
+ /**
+ * Builds the consensus tree over a set of weighted trees.
+ *
+ * @param supportThreshold the minimum support to consider a split into the consensus tree
+ *
+ * @return the consensus tree
+ */
+ private Tree buildTree(double supportThreshold, BranchDistances branchDistances) {
+
+ if (trees.isEmpty()) {
+ throw new ProtTestInternalException("There are no trees to consense");
+ }
+
+ if (supportThreshold < 0.5 || supportThreshold > 1.0) {
+ throw new ProtTestInternalException("Invalid threshold value: " + supportThreshold);
+ }
+
+ double effectiveThreshold = supportThreshold;
+ if (supportThreshold == 0.5) {
+ effectiveThreshold += 1.0/(numTaxa+1);
+ } else if (supportThreshold == 1.0) {
+ effectiveThreshold -= 1.0/(numTaxa+1);
+ }
+
+ // establish support
+ support = new HashMap<FixedBitSet, Support>();
+ int k = 0;
+ for (WeightedTree wTree : trees) {
+ rootedSupport(wTree, wTree.getTree().getRoot(), support);
+
+ ++k;
+
+ }
+
+ Tree cons = new SimpleTree();
+
+ // Contains all internal nodes in the tree so far, ordered so descendants
+ // appear later than ancestors
+ List<Node> internalNodes = new ArrayList<Node>(numTaxa);
+
+ // For each internal node, a bit-set with the complete set of tips for it's clade
+ List<FixedBitSet> internalNodesTips = new ArrayList<FixedBitSet>(numTaxa);
+ assert idGroup.getIdCount() == numTaxa;
+
+ // establish a tree with one root having all tips as descendants
+ internalNodesTips.add(new FixedBitSet(numTaxa));
+ FixedBitSet rooNode = internalNodesTips.get(0);
+ Node[] nodes = new Node[numTaxa];
+ for (int nt = 0; nt < numTaxa; ++nt) {
+ nodes[nt] = NodeFactory.createNode(idGroup.getIdentifier(nt));
+ rooNode.set(nt);
+ }
+
+ Node rootNode = NodeFactory.createNode(nodes);
+ internalNodes.add(rootNode);
+ cons.setRoot(rootNode);
+ // sorts support from largest to smallest
+ final Comparator<Map.Entry<FixedBitSet, Support>> comparator = new Comparator<Map.Entry<FixedBitSet, Support>>() {
+
+ @Override
+ public int compare(Map.Entry<FixedBitSet, Support> o1, Map.Entry<FixedBitSet, Support> o2) {
+ double diff = o2.getValue().treesWeightWithClade - o1.getValue().treesWeightWithClade;
+ if (diff > 0.0) {
+ return 1;
+ } else if (diff < 0.0) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+ };
+
+ // add everything to queue
+ PriorityQueue<Map.Entry<FixedBitSet, Support>> queue =
+ new PriorityQueue<Map.Entry<FixedBitSet, Support>>(support.size(), comparator);
+
+ for (Map.Entry<FixedBitSet, Support> se : support.entrySet()) {
+ Support s = se.getValue();
+ FixedBitSet clade = se.getKey();
+ final int cladeSize = clade.cardinality();
+ if (cladeSize == numTaxa) {
+ // root
+ cons.getRoot().setNodeHeight(s.sumBranches / trees.size());
+ cons.getRoot().setBranchLength(branchDistances.build(s.branchLengths));
+ continue;
+ }
+
+ if (Math.abs(s.treesWeightWithClade - this.cumWeight) < 1e-5 && cladeSize == 1) {
+ // leaf/external node
+ final int nt = clade.nextOnBit(FIRST);
+ final Node leaf = cons.getExternalNode(nt);
+ leaf.setNodeHeight(s.sumBranches / trees.size());
+ leaf.setBranchLength(branchDistances.build(s.branchLengths));
+ } else {
+ queue.add(se);
+ }
+ }
+
+ while (queue.peek() != null) {
+ Map.Entry<FixedBitSet, Support> e = queue.poll();
+ final Support s = e.getValue();
+
+ final double psupport = (1.0 * s.treesWeightWithClade) / cumWeight;
+ if (psupport < effectiveThreshold) {
+ break;
+ }
+
+ final FixedBitSet cladeTips = e.getKey();
+
+ boolean found = false;
+
+ /* locate the node containing the clade. going in reverse order
+ ensures the lowest one is hit first */
+ for (int nsub = internalNodesTips.size() - 1; nsub >= 0; --nsub) {
+
+ FixedBitSet allNodeTips = internalNodesTips.get(nsub);
+
+ // size of intersection between tips & split
+ final int nSplit = allNodeTips.intersectCardinality(cladeTips);
+
+ if (nSplit == cladeTips.cardinality()) {
+ // node contains all of clade
+
+ // Locate node descendants containing the split
+ found = true;
+ List<Integer> split = new ArrayList<Integer>();
+
+ Node n = internalNodes.get(nsub);
+ int l = 0;
+
+ for (int j = 0; j < n.getChildCount(); j++) {
+ Node ch = n.getChild(j);
+
+ if (ch.isLeaf()) {
+ if (cladeTips.contains(idGroup.whichIdNumber(ch.getIdentifier().getName()))) {
+ split.add(l);
+ }
+ } else {
+ // internal
+ final int o = internalNodes.indexOf(ch);
+ final int i = internalNodesTips.get(o).intersectCardinality(cladeTips);
+ if (i == internalNodesTips.get(o).cardinality()) {
+ split.add(l);
+ } else if (i > 0) {
+ // Non compatible
+ found = false;
+ break;
+ }
+ }
+ ++l;
+ }
+
+
+ if (!(found && split.size() < n.getChildCount())) {
+ found = false;
+ break;
+ }
+
+ if (split.isEmpty()) {
+ System.err.println("Bug??");
+ assert (false);
+ }
+
+ final Node detached = detachChildren(cons, n, split);
+
+ final double height = s.sumBranches / s.nTreesWithClade;
+ detached.setNodeHeight(height);
+ detached.setBranchLength(branchDistances.build(s.branchLengths));
+
+ cons.setAttribute(detached, TreeUtils.TREE_CLADE_SUPPORT_ATTRIBUTE, SUPPORT_AS_PERCENT ? 100 * psupport : psupport);
+
+ // insert just after parent, so before any descendants
+ internalNodes.add(nsub + 1, detached);
+ internalNodesTips.add(nsub + 1, new FixedBitSet(cladeTips));
+
+ break;
+ }
+ }
+ }
+
+ TreeUtils.insureConsistency(cons, cons.getRoot());
+
+ String thresholdAsPercent = String.valueOf(supportThreshold * 100);
+ cons.setAttribute(cons.getRoot(), TreeUtils.TREE_NAME_ATTRIBUTE,
+ "cons_" + thresholdAsPercent + "_majRule");
+
+ Set<FixedBitSet> keySet = getSupport().keySet();
+ FixedBitSet[] keys = keySet.toArray(new FixedBitSet[0]);
+ Arrays.sort(keys);
+
+ for (FixedBitSet fbs : keys) {
+ if (fbs.cardinality() > 1) {
+ double psupport = (1.0 * getSupport().get(fbs).getTreesWeightWithClade()) / cumWeight;
+ if (psupport < effectiveThreshold) {
+ splitsOutFromConsensus.add(fbs);
+ } else {
+ splitsInConsensus.add(fbs);
+ }
+ }
+ }
+
+ return cons;
+
+ }
+
+ /**
+ * Enum to calculate the branch lengths
+ */
+ private enum BranchDistances {
+
+ WeightedAverage {
+
+ /**
+ * Calculates the weighted average.
+ *
+ * @param values the weighted values
+ * @param cumWeight the sum of weights
+ *
+ * @return the weighted average of the set
+ */
+ @Override
+ public double build(List<WeightLengthPair> values) {
+ double avg = 0.0;
+ double cumWeight = 0.0;
+ for (WeightLengthPair pair : values) {
+ avg += pair.branchLength * pair.weight;
+ cumWeight += pair.weight;
+ }
+ avg /= cumWeight;
+ return avg;
+ }
+ },
+ WeightedMedian {
+
+ /**
+ * Calculates the weighted median.
+ *
+ * @param values the weighted values
+ * @param cumWeight the sum of weights
+ *
+ * @return the weighted median of the set
+ */
+ @Override
+ public double build(List<WeightLengthPair> values) {
+ Collections.sort(values);
+ double median = -1;
+ double cumWeight = 0.0;
+ for (WeightLengthPair pair : values) {
+ cumWeight += pair.weight;
+ }
+ double halfWeight = cumWeight / 2.0;
+ double cumValue = 0.0;
+ for (WeightLengthPair pair : values) {
+ cumValue += pair.weight;
+ if (cumValue >= halfWeight) {
+ median = pair.branchLength;
+ break;
+ }
+ }
+ return median;
+ }
+ };
+
+ public abstract double build(List<WeightLengthPair> values);
+ }
+
+ /**
+ * One clade support.
+ */
+ static final class Support {
+
+ /** number of trees containing the clade. */
+ private int nTreesWithClade;
+ /** The trees weight with clade. */
+ private double treesWeightWithClade;
+ /** The branch lengths. */
+ private ArrayList<WeightLengthPair> branchLengths;
+ /** Sum of node heights of trees containing the clade. */
+ private double sumBranches;
+
+ public double getTreesWeightWithClade() {
+ return treesWeightWithClade;
+ }
+
+ /**
+ * Instantiates a new support.
+ */
+ Support() {
+ sumBranches = 0.0;
+ treesWeightWithClade = 0.0;
+ nTreesWithClade = 0;
+ branchLengths = new ArrayList<WeightLengthPair>();
+ }
+
+ /**
+ * Adds the branch to the map of branch lengths.
+ *
+ * @param weight the weight
+ * @param height the height
+ * @param branchLength the branch length
+ */
+ public final void add(double weight, double height, double branchLength) {
+ sumBranches += height;
+ branchLengths.add(new WeightLengthPair(weight, branchLength));
+ treesWeightWithClade += weight;
+ ++nTreesWithClade;
+
+ double testW = 0.0;
+ for (WeightLengthPair wlp : branchLengths) {
+ testW += wlp.weight;
+ }
+ }
+ }
+
+ static class WeightLengthPair implements Comparable<WeightLengthPair> {
+
+ private double weight;
+ private double branchLength;
+
+ WeightLengthPair(double weight, double branchLength) {
+ this.weight = weight;
+ this.branchLength = branchLength;
+ }
+
+ @Override
+ public int compareTo(WeightLengthPair o) {
+ if (branchLength < o.branchLength) {
+ return -1;
+ } else if (branchLength > o.branchLength) {
+ return 1;
+ }
+ return 0;
+ }
+ }
+
+ /**
+ * A extension of Weighted tree but every tree
+ * has the same weight.
+ */
+ static class UnweightedTree extends WeightedTree {
+
+ /**
+ * Instantiates a new unweighted tree.
+ *
+ * @param tree the tree
+ */
+ UnweightedTree(Tree tree) {
+ super(tree, 1.0);
+ }
+ }
+
+ /**
+ * The main method. This method allows testing of consensus tree
+ * building. It requires at least 2 arguments.
+ *
+ * @param args Tree set filename (Newick's), threshold, [avg | median]
+ */
+ public static void main(String[] args) {
+
+ PrintWriter out = new PrintWriter(System.out);
+
+ if (args.length < 2 || args[0].contains("help")) {
+ out.println("This class requires at least 2 arguments: Tree set filename, Threshold value" + " and optionally the branch length calculation method [avg (default), median]");
+ out.println("The file format should be:");
+ out.println(" · (Newick's tree)[Weight];");
+ out.println(" · Nexus format tree set");
+ out.flush();
+ System.exit(-1);
+ }
+
+ String filename = args[0];
+ Double threshold = Double.parseDouble(args[1]);
+ File f = new File(filename);
+ try {
+ Consensus consensus;
+ if (args.length >= 3) {
+ if (args[2].equalsIgnoreCase("median")) {
+ consensus = new Consensus(f, threshold, BRANCH_LENGTHS_MEDIAN);
+ } else if (args[2].equalsIgnoreCase("avg")) {
+ consensus = new Consensus(f, threshold, BRANCH_LENGTHS_AVERAGE);
+ } else {
+ consensus = new Consensus(f, threshold);
+ }
+ } else {
+ consensus = new Consensus(f, threshold);
+ }
+ Tree consensusTree = consensus.getConsensusTree();
+ out.println("");
+
+ Set<FixedBitSet> keySet = consensus.getSupport().keySet();
+ FixedBitSet[] keys = keySet.toArray(new FixedBitSet[0]);
+ List<FixedBitSet> splitsInConsensus = new ArrayList<FixedBitSet>();
+ List<FixedBitSet> splitsOutFromConsensus = new ArrayList<FixedBitSet>();
+
+ Arrays.sort(keys);
+
+ for (FixedBitSet fbs : keys) {
+ if (fbs.cardinality() > 1) {
+ double psupport = (1.0 * consensus.getSupport().get(fbs).getTreesWeightWithClade()) / consensus.cumWeight;
+ if (psupport < threshold) {
+ splitsOutFromConsensus.add(fbs);
+ } else {
+ splitsInConsensus.add(fbs);
+ }
+ }
+ }
+
+ out.println("# # # # # # # # # # # # # # # #");
+ out.println(" ");
+ out.println("Species in order:");
+ out.println(" ");
+
+ for (int i = 0; i < consensus.getIdGroup().getIdCount(); i++) {
+ Identifier id = consensus.getIdGroup().getIdentifier(i);
+ out.println(" " + (i + 1) + ". " + id.getName());
+ }
+ out.println(" ");
+ out.println("# # # # # # # # # # # # # # # #");
+ out.println(" ");
+ out.println("Sets included in the consensus tree");
+ out.println(" ");
+ out.print(" ");
+
+ int numTaxa = consensus.getIdGroup().getIdCount();
+ for (int i = 0; i < consensus.getIdGroup().getIdCount(); i++) {
+ out.print(String.valueOf(i + 1).charAt(0));
+ }
+ out.println(" ");
+ if (numTaxa >= 10) {
+ ProtTestFormattedOutput.space(4 + 9, ' ');
+ for (int i = 9; i < consensus.getIdGroup().getIdCount(); i++) {
+ out.print(String.valueOf(i + 1).charAt(1));
+ }
+ }
+ out.println(" ");
+ for (FixedBitSet fbs : splitsInConsensus) {
+ out.println(" " + fbs.splitRepresentation() + " ( " + Utilities.round(consensus.getSupport().get(fbs).getTreesWeightWithClade(), 3) + " )");
+ }
+ out.println(" ");
+ out.println("Sets NOT included in consensus tree");
+ out.println(" ");
+ out.print(" ");
+ for (int i = 0; i < consensus.getIdGroup().getIdCount(); i++) {
+ out.print(i + 1);
+ }
+ out.println(" ");
+ for (FixedBitSet fbs : splitsOutFromConsensus) {
+ out.println(" " + fbs.splitRepresentation() + " ( " + Utilities.round(consensus.getSupport().get(fbs).getTreesWeightWithClade(), 3) + " )");
+ }
+ out.println(" ");
+ out.println("# # # # # # # # # # # # # # # #");
+
+ TreeUtils.printASCII(consensusTree, out);
+ out.println(" ");
+ TreeUtils.printBranchInfo(consensusTree, out);
+ out.println(" ");
+ TreeUtils.heightInfo(consensusTree, out);
+ out.println(" ");
+ out.println("# # # # # # # # # # # # # # # #");
+ out.println(" ");
+ out.println(TreeUtils.toNewick(consensusTree, true, true, true));
+ out.println(" ");
+ out.println("# # # # # # # # # # # # # # # #");
+ out.println(" ");
+ } catch (FileNotFoundException e) {
+ out.println("File not found: " + filename);
+ } catch (IOException e1) {
+ out.println("IO Error: " + e1.getMessage());
+ }
+ out.flush();
+ }
+
+ public String getTaxaHeader() {
+ StringBuilder taxaHeader = new StringBuilder();
+ for (int i = 0; i < numTaxa; i++) {
+ taxaHeader.append(String.valueOf(i + 1).charAt(0));
+ }
+ if (numTaxa >= 10) {
+ taxaHeader.append('\n');
+ taxaHeader.append(ProtTestFormattedOutput.space(4 + 9, ' '));
+ for (int i = 9; i < numTaxa; i++) {
+ taxaHeader.append(String.valueOf(i + 1).charAt(1));
+ }
+ }
+ if (numTaxa >= 100) {
+ taxaHeader.append('\n');
+ taxaHeader.append(ProtTestFormattedOutput.space(4 + 99, ' '));
+ for (int i = 99; i < numTaxa; i++) {
+ taxaHeader.append(String.valueOf(i + 1).charAt(2));
+ }
+ }
+ if (numTaxa >= 1000) {
+ taxaHeader.append('\n');
+ taxaHeader.append(ProtTestFormattedOutput.space(4 + 999, ' '));
+ for (int i = 999; i < numTaxa; i++) {
+ taxaHeader.append(String.valueOf(i + 1).charAt(3));
+ }
+ }
+
+ return taxaHeader.toString();
+ }
+
+ public String getSetsIncluded() {
+ StringBuilder setsIncluded = new StringBuilder();
+ setsIncluded.append(" ");
+ setsIncluded.append(getTaxaHeader());
+
+ setsIncluded.append('\n');
+ for (FixedBitSet fbs : splitsInConsensus) {
+ setsIncluded.append(" ")
+ .append(fbs.splitRepresentation())
+ .append(" ( ")
+ .append(Utilities.round(getCladeSupport().get(fbs), 5))
+ .append(" )")
+ .append('\n');
+ }
+ return setsIncluded.toString();
+ }
+
+ public String getSetsNotIncluded() {
+ StringBuilder setsIncluded = new StringBuilder();
+ setsIncluded.append(" ");
+ setsIncluded.append(getTaxaHeader());
+
+ setsIncluded.append('\n');
+ for (FixedBitSet fbs : splitsOutFromConsensus) {
+ setsIncluded.append(" ")
+ .append(fbs.splitRepresentation())
+ .append(" ( ")
+ .append(Utilities.round(getCladeSupport().get(fbs), 5))
+ .append(" )")
+ .append('\n');
+ }
+ return setsIncluded.toString();
+ }
+
+ private BranchDistances getBranchDistances(int value) {
+ BranchDistances bd;
+ switch (value) {
+ case BRANCH_LENGTHS_AVERAGE:
+ bd = BranchDistances.WeightedAverage;
+ break;
+ case BRANCH_LENGTHS_MEDIAN:
+ bd = BranchDistances.WeightedMedian;
+ break;
+ default:
+ // Weighted average
+ bd = DEFAULT_BRANCH_DISTANCES;
+ }
+ return bd;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/consensus/package.html b/src/main/java/es/uvigo/darwin/prottest/consensus/package.html
new file mode 100755
index 0000000..00ab6e5
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/consensus/package.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Provides the classes to build consensus trees.
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/AminoAcidRunEstimator.java b/src/main/java/es/uvigo/darwin/prottest/exe/AminoAcidRunEstimator.java
new file mode 100755
index 0000000..18621e1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/AminoAcidRunEstimator.java
@@ -0,0 +1,66 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+
+/**
+ * A generic optimizer for amino-acid models
+ *
+ * @author Federico Abascal
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public abstract class AminoAcidRunEstimator extends RunEstimatorImpl {
+
+ /**
+ * Instantiates a new generic optimizer for amino-acid models.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ */
+ public AminoAcidRunEstimator(ApplicationOptions options, Model model) {
+ super(options, model);
+ }
+
+ /**
+ * Instantiates a new generic optimizer for amino-acid models.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ * @param numberOfThreads the number of threads to use in the optimization
+ */
+ public AminoAcidRunEstimator(ApplicationOptions options, Model model, int numberOfThreads) {
+ super(options, model, numberOfThreads);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#report()
+ */
+ public void printReport () {
+ model.printReport();
+ if (time != null)
+ ProtTestLogger.getDefaultLogger().info(" (" + time + ")\n");
+ ProtTestLogger.getDefaultLogger().info("\n");
+ ProtTestLogger.getDefaultLogger().flush();
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutionManager.java b/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutionManager.java
new file mode 100755
index 0000000..8f40fb2
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutionManager.java
@@ -0,0 +1,108 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * A thrid-party applications manager to control proccesses running on
+ * the machine and kill them when necessary.
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public class ExternalExecutionManager {
+
+ /** Unique instance of the manager */
+ private static ExternalExecutionManager instance;
+ /** Collection of running processes */
+ private final Collection<Process> processes;
+
+ /**
+ * Instantiates a new execution manager
+ */
+ private ExternalExecutionManager() {
+ this.processes = new ArrayList<Process>();
+ }
+
+ /**
+ * Gets the unique instance of the class
+ *
+ * @return the ExternalExecutionManager instance
+ */
+ public static ExternalExecutionManager getInstance() {
+ if (instance == null) {
+ instance = new ExternalExecutionManager();
+ }
+ return instance;
+ }
+
+ /**
+ * Adds a process in execution to the collection
+ *
+ * @param proc the running process
+ *
+ * @return true, if succesfully added the process
+ */
+ public boolean addProcess(Process proc) {
+ boolean result = false;
+ if (!processes.contains(proc)) {
+ result = processes.add(proc);
+ }
+ return result;
+ }
+
+ /**
+ * Removes a process from the collection
+ *
+ * @param proc the process to remove
+ *
+ * @return true, if succesfully removed the process
+ */
+ public boolean removeProcess(Process proc) {
+ boolean result = false;
+ if (processes.contains(proc)) {
+ result = processes.remove(proc);
+ }
+ return result;
+ }
+
+ /**
+ * Kills all running processes in the collection
+ */
+ public void killProcesses() {
+ for (final Process proc : processes) {
+ if (proc != null) {
+ try {
+ proc.exitValue();
+ } catch (IllegalThreadStateException e) {
+ // The process is executing, so we should kill it
+ Runtime.getRuntime().addShutdownHook(
+ new Thread(new Runnable() {
+
+ public void run() {
+ proc.destroy();
+ }
+ }));
+ }
+ }
+ }
+ processes.clear();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutor.java b/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutor.java
new file mode 100755
index 0000000..6629754
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/ExternalExecutor.java
@@ -0,0 +1,97 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package es.uvigo.darwin.prottest.exe;
+
+import es.uvigo.darwin.prottest.exe.util.TemporaryFileManager;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.ExternalExecutionException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+
+/**
+ *
+ * @author diego
+ */
+public class ExternalExecutor {
+
+ private static final int STATE_NULL = 0;
+ private static final int STATE_INITIALIZED = 1;
+ private static final int STATE_EXECUTED = 2;
+
+ private static final int OUTPUT_STANDARD = 1;
+ private static final int OUTPUT_TEMPORARY = 2;
+
+ private String command;
+ private Process proc = null;
+ private OutputStream logOutput;
+
+ private int internal_state = STATE_NULL;
+
+ public ExternalExecutor(String command, int outLogFormat)
+ throws ExternalExecutionException {
+ try {
+ this.command = command;
+
+ switch (outLogFormat) {
+ case OUTPUT_STANDARD:
+ logOutput = System.out;
+ break;
+ case OUTPUT_TEMPORARY:
+ logOutput = new FileOutputStream(TemporaryFileManager.getInstance().
+ getLogFilename(Thread.currentThread()));
+ }
+ this.internal_state = STATE_INITIALIZED;
+ } catch (FileNotFoundException ex) {
+ throw new ExternalExecutionException("I/O error: " + ex.getMessage());
+ }
+ }
+
+ public void run() throws ExternalExecutionException {
+
+ if (!checkState(STATE_INITIALIZED) || checkState(STATE_EXECUTED)) {
+ throw new ProtTestInternalException("Invalid executor internal state");
+ }
+
+ try {
+ Runtime runtime = Runtime.getRuntime();
+ proc = runtime.exec(command);
+
+ ExternalExecutionManager.getInstance().addProcess(proc);
+ } catch (IOException ex) {
+ throw new ProtTestInternalException(ex.getMessage());
+ }
+
+ try {
+ int exitVal = proc.waitFor();
+ } catch (InterruptedException ex) {
+ throw new ExternalExecutionException("Interrupted execution: " + ex.getMessage());
+ }
+ }
+
+ private boolean checkState(int state) {
+ return internal_state >= state;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/ParallelModelEstimator.java b/src/main/java/es/uvigo/darwin/prottest/exe/ParallelModelEstimator.java
new file mode 100755
index 0000000..7a3b130
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/ParallelModelEstimator.java
@@ -0,0 +1,154 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package es.uvigo.darwin.prottest.exe;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import pal.alignment.Alignment;
+
+/**
+ * Allows the execution of many model optimizations in a thread pool
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public class ParallelModelEstimator extends ObservableModelUpdater
+ implements ModelUpdaterObserver {
+
+ /** The runtime **/
+ private Runtime runtime = Runtime.getRuntime();
+ /** The size of parallel tasks **/
+ private int maxNumberOfTasks;
+ /** The list of model estimators **/
+ private List<RunEstimator> estimatorList;
+ /** The pool of threads **/
+ private ExecutorService threadPool;
+ /** Collection of callable objects (tasks) **/
+ private Collection<Callable<Object>> c = new ArrayList<Callable<Object>>();
+
+ /**
+ * Instantiates a new ParallelModelEstimator with no models to optimize.
+ * The size of the thread pool is equal to the number of available cores in the machine.
+ *
+ * @param alignment the common alignment of the models
+ */
+ public ParallelModelEstimator(Alignment alignment) {
+
+ this(-1, alignment);
+
+ }
+
+ /**
+ * Instantiates a new ParallelModelEstimator with a set of models to optimize
+ * The size of the thread pool is equal to the number of available cores in the machine.
+ *
+ * @param modelCollection the collection of models to optimize in the pool
+ */
+ public ParallelModelEstimator(ModelCollection modelCollection) {
+
+ this(-1, modelCollection);
+
+ }
+
+ /**
+ * Instantiates a new ParallelModelEstimator with no models to optimize and
+ * a fixed size of the thread pool
+ *
+ * @param availableThreads the size of the thread pool
+ * @param alignment the common alignment of the models
+ */
+ public ParallelModelEstimator(int availableThreads, Alignment alignment) {
+
+ if (availableThreads < 0) {
+ availableThreads = runtime.availableProcessors();
+ }
+ this.maxNumberOfTasks = availableThreads;
+ this.estimatorList = new ArrayList<RunEstimator>(maxNumberOfTasks);
+ this.threadPool = Executors.newFixedThreadPool(maxNumberOfTasks);
+ }
+
+ /**
+ * Instantiates a new ParallelModelEstimator with a set of models to optimize and
+ * a fixed size of the thread pool
+ *
+ * @param availableThreads the size of the thread pool
+ * @param modelCollection the collection of models to optimize in the pool
+ */
+ public ParallelModelEstimator(int availableThreads, ModelCollection modelCollection) {
+
+ if (availableThreads < 0) {
+ availableThreads = runtime.availableProcessors();
+ }
+ this.estimatorList = new ArrayList<RunEstimator>(maxNumberOfTasks);
+
+ }
+
+ /**
+ * Executes the model optimization
+ *
+ * @param estimator the model estimator to execute
+ *
+ * @return if succesfully added the task
+ */
+ public boolean execute(RunEstimator estimator) {
+ estimator.addObserver(this);
+
+ boolean added = estimatorList.add(estimator);
+ c.add(Executors.callable(estimator));
+ Collection<Future<Object>> futures = null;
+
+ threadPool.execute(estimator);
+
+ return added;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.observer.ModelUpdaterObserver#update(es.uvigo.darwin.prottest.observer.ObservableModelUpdater, es.uvigo.darwin.prottest.model.Model, es.uvigo.darwin.prottest, es.uvigo.darwin.prottest.global.options.ApplicationOptions)
+ */
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+ notifyObservers(model, options);
+ }
+
+ /**
+ * Checks if exist more tasks in the task queue
+ *
+ * @return true, if exist more tasks to execute
+ */
+ public boolean hasMoreTasks() {
+ for (RunEstimator estimator : estimatorList) {
+ if (!estimator.getModel().isComputed()) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/PhyMLv3AminoAcidRunEstimator.java b/src/main/java/es/uvigo/darwin/prottest/exe/PhyMLv3AminoAcidRunEstimator.java
new file mode 100755
index 0000000..7967ace
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/PhyMLv3AminoAcidRunEstimator.java
@@ -0,0 +1,464 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.APPLICATION_PROPERTIES;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.OPTIMIZE_BIONJ;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.OPTIMIZE_FIXED_BIONJ;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.OPTIMIZE_ML;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.OPTIMIZE_USER;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+
+import pal.tree.ReadTree;
+import pal.tree.TreeParseException;
+import es.uvigo.darwin.prottest.exe.util.TemporaryFileManager;
+import es.uvigo.darwin.prottest.global.ApplicationGlobals;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.AminoAcidModel;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.ModelNotFoundException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.OSNotSupportedException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.PhyMLExecutionException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.StatsFileFormatException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+
+/**
+ * The Class PhyMLAminoAcidRunEstimator. It optimizes Amino-Acid
+ * model parameters using PhyML 3.0.
+ *
+ * @author Federico Abascal
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public class PhyMLv3AminoAcidRunEstimator extends AminoAcidRunEstimator {
+
+ /** The PhyML implemented matrices. */
+ public static String[] IMPLEMENTED_MATRICES = {
+ "JTT",
+ "LG",
+ "DCMut",
+ "MtREV",
+ "MtMam",
+ "MtArt",
+ "Dayhoff",
+ "WAG",
+ "RtREV",
+ "CpREV",
+ "Blosum62",
+ "VT",
+ "HIVb",
+ "HIVw"
+ };
+ /** Suffix for temporary statistic files. */
+ private static final String STATS_FILE_SUFFIX = "_phyml_stats.txt";
+ /** Suffix for temporary tree files. */
+ private static final String TREE_FILE_SUFFIX = "_phyml_tree.txt";
+ /** Alignment filename. */
+ private String workAlignment;
+ /** Custom model substitution matrix file**/
+ private File modelFile;
+
+ /**
+ * Instantiates a new optimizer for amino-acid models
+ * using PhyML.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ */
+ public PhyMLv3AminoAcidRunEstimator(ApplicationOptions options, Model model) {
+ this(options, model, 1);
+ }
+
+ /**
+ * Instantiates a new optimizer for amino-acid models
+ * using PhyML.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ * @param numberOfThreads the number of threads to use in the optimization
+ */
+ public PhyMLv3AminoAcidRunEstimator(ApplicationOptions options, Model model, int numberOfThreads) {
+ super(options, model, numberOfThreads);
+ this.numberOfCategories = options.ncat;
+
+ try {
+ this.model = (AminoAcidModel) model;
+ // check if there is any matrix file
+ modelFile = new File(ApplicationGlobals.PATH + File.separator + "models" + File.separator + model.getMatrix());
+
+ } catch (ClassCastException cce) {
+ throw new ProtTestInternalException("Wrong model type");
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#optimizeModel(es.uvigo.darwin.prottest.global.options.ApplicationOptions)
+ */
+ @Override
+ public boolean runEstimator()
+ throws ModelOptimizationException {
+ //let's call Phyml with the proper command line
+
+ this.workAlignment = TemporaryFileManager.getInstance().getAlignmentFilename(Thread.currentThread());
+
+ String inv = "0.0";
+ if (model.isInv()) {
+ inv = "e";
+ }
+
+ String rateCathegories = "1";
+
+ String alpha = "";
+ if (model.isGamma()) {
+ rateCathegories = "" + model.getNumberOfTransitionCategories();//options.ncat;
+ alpha = "e";
+ }
+ String tr = "BIONJ";
+
+ String F = "d";
+ if (model.isPlusF()) {
+ F = "e";
+ }
+ String topo = "lr";
+ switch (options.strategyMode) {
+ case OPTIMIZE_BIONJ:
+ tr = "BIONJ";
+ topo = "lr";
+ break;
+ case OPTIMIZE_FIXED_BIONJ:
+ if (TemporaryFileManager.getInstance().getTreeFilename(Thread.currentThread()) != null) {
+ tr = TemporaryFileManager.getInstance().getTreeFilename(Thread.currentThread());
+ topo = "lr";
+ } else {
+ topo = "r";
+ }
+ break;
+ case OPTIMIZE_ML:
+ topo = "tlr";
+ break;
+ case OPTIMIZE_USER:
+ tr = TemporaryFileManager.getInstance().getTreeFilename(Thread.currentThread());
+ topo = "lr";
+ }
+ try {
+ Runtime runtime = Runtime.getRuntime();
+
+ String str[] = new String[31];
+ for (int i = 0; i < str.length; i++) {
+ str[i] = "";
+ }
+
+ boolean phymlGlobal = APPLICATION_PROPERTIES.getProperty("global-phyml-exe", "false").equalsIgnoreCase("true");
+
+ File exeFilesDir = new File(APPLICATION_PROPERTIES.getProperty("exe-dir", ApplicationGlobals.PATH));
+ if (!exeFilesDir.isAbsolute()) {
+ exeFilesDir = new File(ApplicationGlobals.PATH + File.separator + APPLICATION_PROPERTIES.getProperty("exe-dir", "bin"));
+ }
+
+ File phymlBin;
+
+ phymlBin = new File(exeFilesDir.getAbsolutePath() + File.separator + "phyml");
+
+ String phymlBinName;
+ if (phymlGlobal) {
+ phymlBinName = "phyml";
+ } else {
+ if (phymlBin.exists() && phymlBin.canExecute()) {
+ phymlBinName = phymlBin.getAbsolutePath();
+ } else {
+ phymlBinName = exeFilesDir.getAbsolutePath() + File.separator + getPhymlVersion();
+ }
+ }
+
+ if (phymlBinName != null) {
+
+ // phyml -i seq_file_name -d aa ¿-q? -f d/e (d para -F y e para +F) -v 0/e (para -I o +I) -a e (para estimar alpha)
+ // -c 0/4/8 (num rate categories) -u user_tree_file (opcional)
+ // -o tlr/lr (dependiendo de si optimizamos la topología o no)
+ // -m WAG (default) | JTT | MtREV | Dayhoff | DCMut | RtREV | CpREV | VT | Blosum62 | MtMam | MtArt | HIVw | HIVb | custom
+
+ str[0] = phymlBinName;
+
+ // input alignment
+ str[4] = "-i";
+ str[5] = workAlignment;
+
+ // number of rate categories
+ str[6] = "-c";
+ str[7] = rateCathegories;
+
+ // the model
+ str[8] = "-m";
+ if (!Arrays.asList(IMPLEMENTED_MATRICES).contains(model.getMatrix())) {
+ // check matrix file
+ if (!modelFile.exists()) {
+ throw new ModelNotFoundException(model.getMatrix());
+ }
+ str[9] = "custom";
+ str[27] = "--aa_rate_file";
+ str[28] = modelFile.getAbsolutePath();
+ } else {
+ str[9] = model.getMatrix();
+ }
+
+ // proportion of invariable sites
+ str[10] = "-v";
+ str[11] = inv;
+
+ // value of the gamma shape parameter (if gamma distribution)
+ if (!alpha.equals("")) {
+ str[12] = "-a";
+ str[13] = alpha;
+ }
+
+ // topology optimization
+ str[14] = "-o";
+ str[15] = topo;
+
+ // amino-acid frequencies
+ str[16] = "-f";
+ str[17] = F;
+
+ // starting tree file
+ if (!tr.equals("BIONJ")) {
+ str[18] = "-u";
+ str[19] = tr;
+ }
+
+ // data type
+ str[20] = "-d";
+ str[21] = "aa";
+
+ // bootstrapping
+ str[22] = "-b";
+ str[23] = "0";
+
+ if (APPLICATION_PROPERTIES.getProperty("phyml_thread_scheduling", "false").equalsIgnoreCase("true")) {
+ str[24] = "--num_threads";
+ str[25] = String.valueOf(numberOfThreads);
+ }
+ if (APPLICATION_PROPERTIES.getProperty("no-memory-check", "no").equalsIgnoreCase("yes")) {
+ str[26] = "--no_memory_check";
+ }
+
+ if (options.strategyMode == OPTIMIZE_ML) {
+ str[29] = "-s";
+ str[30] = options.getTreeSearchOperation();
+ } else {
+ str[29] = str[30] = "";
+ }
+ model.setCommandLine(str);
+ proc = runtime.exec(str);
+ proc.getOutputStream().write(modelFile.getPath().getBytes());
+ ExternalExecutionManager.getInstance().addProcess(proc);
+
+ } else {
+ OSNotSupportedException e =
+ new OSNotSupportedException("PhyML");
+ throw e;
+ }
+ proc.getOutputStream().close();
+
+ StreamGobbler errorGobbler = new PhymlStreamGobbler(new InputStreamReader(proc.getErrorStream()), "Phyml-Error", true, RunEstimator.class);
+ StreamGobbler outputGobbler = new PhymlStreamGobbler(new InputStreamReader(proc.getInputStream()), "Phyml-Output", true, RunEstimator.class);
+ errorGobbler.start();
+ outputGobbler.start();
+ int exitVal = proc.waitFor();
+ ExternalExecutionManager.getInstance().removeProcess(proc);
+
+ pfine("Phyml's command-line: ");
+ for (int i = 0; i < str.length; i++) {
+ pfine(str[i] + " ");
+ }
+ pfineln("");
+
+ if (exitVal != 0) {
+ errorln("Phyml's exit value: " + exitVal + " (there was probably some error)");
+ error("Phyml's command-line: ");
+ for (int i = 0; i < str.length; i++) {
+ error(str[i] + " ");
+ }
+ errorln("");
+
+ errorln("Please, take a look at the Phyml's log below:");
+ String line;
+ try {
+ FileReader input = new FileReader(TemporaryFileManager.getInstance().getLogFilename(Thread.currentThread()));
+ BufferedReader br = new BufferedReader(input);
+ while ((line = br.readLine()) != null) {
+ errorln(line);
+ }
+ } catch (IOException e) {
+ errorln("Unable to read the log file: " + TemporaryFileManager.getInstance().getLogFilename(Thread.currentThread()));
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new PhyMLExecutionException("Interrupted execution: " + e.getMessage());
+ } catch (IOException e) {
+ throw new PhyMLExecutionException("I/O error: " + e.getMessage());
+ }
+
+
+ if (!(readStatsFile() && readTreeFile())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Read the temporary statistics file.
+ *
+ * @return true, if successful
+ */
+ private boolean readStatsFile()
+ throws ModelOptimizationException {
+
+ String line;
+
+ try {
+ FileReader input = new FileReader(workAlignment + STATS_FILE_SUFFIX);
+ BufferedReader br = new BufferedReader(input);
+ while ((line = br.readLine()) != null) {
+ pfinerln("[DEBUG] PHYML: " + line);
+
+ if (line.length() > 0) {
+ if (line.startsWith(". Model of amino acids substitution")) {
+ String matrixName = Utilities.lastToken(line);
+
+ //TODO: This line exists due to a bug in the phyml latest versions
+ // where the HIVw matrix is shown as HIVb in the stats file
+ if (!model.getMatrix().equals("HIVw"))
+ if (!(model.getMatrix().equals(matrixName) || (modelFile.exists() &&
+ !Arrays.asList(IMPLEMENTED_MATRICES).contains(model.getMatrix())))) {
+ String errorMsg = "Matrix names doesn't match";
+ errorln("PHYML: " + line);
+ errorln("Last token: " + Utilities.lastToken(line));
+ errorln("It should be: " + model.getMatrix());
+ errorln(errorMsg);
+ throw new ModelNotFoundException(model.getMatrix());
+ }
+ } else if (line.startsWith(". Log-likelihood")) {
+ model.setLk(Double.parseDouble(Utilities.lastToken(line)));
+ } else if (line.startsWith(". Discrete gamma model")) {
+ if (Utilities.lastToken(line).equals("Yes")) {
+ line = br.readLine();
+
+ pfinerln("[DEBUG] PHYML: " + line);
+
+ if (model.getNumberOfTransitionCategories() != Integer.parseInt(Utilities.lastToken(line))) {
+ String errorMsg = "There were errors in the number of transition categories: " + model.getNumberOfTransitionCategories() + " vs " + Integer.parseInt(Utilities.lastToken(line));
+ errorln(errorMsg);
+
+ throw new StatsFileFormatException("PhyML", errorMsg);
+ //prottest.setCurrentModel(-2);
+ }
+ line = br.readLine();
+
+ pfinerln("[DEBUG] PHYML: " + line);
+
+ model.setAlpha(Double.parseDouble(Utilities.lastToken(line)));
+ }
+ } else if (line.startsWith(". Proportion of invariant:")) {
+ model.setInv(Double.parseDouble(Utilities.lastToken(line)));
+ } else if (line.startsWith(". Time used")) {
+ time = Utilities.lastToken(line);
+ }
+ }
+ }
+ } catch (IOException e) {
+ throw new StatsFileFormatException("PhyML", e.getMessage());
+ }
+ return true;
+ }
+
+ /**
+ * Read the temporary tree file.
+ *
+ * @return true, if successful
+ *
+ * @throws TreeFormatException the tree format exception
+ */
+ private boolean readTreeFile()
+ throws TreeFormatException {
+
+ try {
+ model.setTree(new ReadTree(workAlignment + TREE_FILE_SUFFIX));
+ } catch (TreeParseException e) {
+ String errorMsg = "ProtTest: wrong tree format, exiting...";
+ throw new TreeFormatException(errorMsg);
+ } catch (IOException e) {
+ String errorMsg = "Error: File not found (IO error), exiting...";
+ throw new TreeFormatException(errorMsg);
+ }
+ return true;
+ }
+
+ /**
+ * Delete temporary files.
+ *
+ * @return true, if successful
+ */
+ @Override
+ protected boolean deleteTemporaryFiles() {
+ File f;
+ f = new File(workAlignment + STATS_FILE_SUFFIX);
+ f.delete();
+ f = new File(workAlignment + TREE_FILE_SUFFIX);
+ f.delete();
+ f = new File(TemporaryFileManager.getInstance().getLogFilename(Thread.currentThread()));
+ f.delete();
+ return true;
+ }
+
+ /**
+ * Gets the PhyML executable name for the current Operating System.
+ *
+ * @return the PhyML executable name
+ */
+ private String getPhymlVersion() {
+ String os = System.getProperty("os.name");
+ String oa = System.getProperty("os.arch");
+ if (os.startsWith("Mac")) {
+ if (oa.startsWith("ppc")) {
+ return "phyml-prottest-macppc";
+ } else {
+ return "phyml-prottest-macintel";
+ }
+ } else if (os.startsWith("Linux")) {
+ if (oa.contains("md64")) {
+ return "phyml-prottest-linux64";
+ } else {
+ return "phyml-prottest-linux";
+ }
+ } else if (os.startsWith("Window")) {
+ return "phyml-prottest-windows.exe";
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/PhymlStreamGobbler.java b/src/main/java/es/uvigo/darwin/prottest/exe/PhymlStreamGobbler.java
new file mode 100755
index 0000000..c2b8f5d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/PhymlStreamGobbler.java
@@ -0,0 +1,65 @@
+/*
+Copyright (C) 2004 Federico Abascal
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Allows the asynchronous logging of an input stream.
+ *
+ * @author Federico Abascal
+ */
+public class PhymlStreamGobbler extends StreamGobbler {
+
+ /**
+ * Instantiates a new StreamGobbler
+ *
+ * @param isr the input stream reader to evaluate
+ * @param type the prefix of the output lines
+ * @param printIt true, if the errors should be logged
+ * @param caller the caller
+ */
+ public PhymlStreamGobbler(InputStreamReader isr, String type, boolean printIt, Class caller) {
+ super(isr,type,printIt,caller);
+ }
+
+ @Override
+ /* (non-Javadoc)
+ * @see java.lang.Thread#run()
+ */
+ public void run() {
+ try {
+ //InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ ProtTestLogger.lowLevelLog(line);
+ if (printIt && line.startsWith(". Err")) {
+ ProtTestLogger.severeln(type + ">" + line, caller);
+ } else {
+ ProtTestLogger.finestln(type + ">" + line, caller);
+ }
+ }
+ } catch (IOException ioe) {
+
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLAminoAcidRunEstimator.java b/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLAminoAcidRunEstimator.java
new file mode 100755
index 0000000..bc6f6cb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLAminoAcidRunEstimator.java
@@ -0,0 +1,341 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import static es.uvigo.darwin.prottest.global.RaxmlAminoAcidApplicationGlobals.*;
+import es.uvigo.darwin.prottest.exe.util.TemporaryFileManager;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.AminoAcidModel;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.ModelNotFoundException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.OSNotSupportedException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.PhyMLExecutionException;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException.StatsFileFormatException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import pal.tree.ReadTree;
+import pal.tree.TreeParseException;
+
+
+/**
+ * The Class RAxMLAminoAcidRunEstimator. It optimizes Amino-Acid
+ * model parameters using RAxML.
+ *
+ * This implementation fits with RAxML 7.0.4.
+ */
+public class RaxMLAminoAcidRunEstimator extends AminoAcidRunEstimator {
+
+ public static final String PARSIMONY_TREE_PREFIX = "RAxML_parsimonyTree.";
+ public static final String FINAL_TREE_PREFIX = "RAxML_result.";
+ public static final String STATS_PREFIX = "RAxML_info.";
+ public static final String LOG_PREFIX = "RAxML_log.";
+
+ /** Alignment filename. */
+ private String workAlignment;
+ /** Custom model substitution matrix file**/
+ private File modelFile;
+
+ private String outputAppend;
+
+ /**
+ * Instantiates a new optimizer for amino-acid models
+ * using RaxML.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ */
+ public RaxMLAminoAcidRunEstimator(ApplicationOptions options, Model model) {
+ this(options, model, 1);
+ }
+
+ /**
+ * Instantiates a new optimizer for amino-acid models
+ * using RaxML.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ * @param numberOfThreads the number of threads to use in the optimization
+ */
+ public RaxMLAminoAcidRunEstimator(ApplicationOptions options, Model model, int numberOfThreads) {
+ super(options, model, numberOfThreads);
+
+ this.numberOfCategories = options.ncat;
+
+ try {
+ this.model = (AminoAcidModel) model;
+ // check if there is any matrix file
+ modelFile = new File("models" + File.separator + model.getMatrix());
+
+ } catch (ClassCastException cce) {
+ throw new ProtTestInternalException("Wrong model type");
+ }
+
+ this.outputAppend = model.getModelName().replace('+', 'P');
+ System.out.println(" MODEL, OUTPUT " + model.getModelName() + " " + outputAppend);
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#optimizeModel(es.uvigo.darwin.prottest.global.options.ApplicationOptions)
+ */
+ @Override
+ public boolean runEstimator() throws ModelOptimizationException {
+
+ //let's call Phyml with the proper command line
+
+ this.workAlignment = TemporaryFileManager.getInstance().getAlignmentFilename(Thread.currentThread());
+
+
+ switch (options.strategyMode) {
+ case OPTIMIZE_BIONJ:
+ break;
+ case OPTIMIZE_FIXED_BIONJ:
+ if (TemporaryFileManager.getInstance().getTreeFilename(Thread.currentThread()) != null) {
+ } else {
+ }
+ break;
+ case OPTIMIZE_ML:
+ break;
+ case OPTIMIZE_USER:
+ }
+ try {
+ Runtime runtime = Runtime.getRuntime();
+
+ String str[] = new String[26];
+ for (int i = 0; i < str.length; i++) {
+ str[i] = "";
+ }
+
+ String raxmlBinName = "raxmlHPC";
+
+ if (raxmlBinName != null) {
+
+ // raxml -s seq_file_name -n output -m model d/e (d para -F y e para +F) -v 0/e (para -I o +I) -a e (para estimar alpha)
+ // -c 0/4/8 (num rate categories) -u user_tree_file (opcional)
+ // -o tlr/lr (dependiendo de si optimizamos la topología o no)
+ // -m WAG (default) | JTT | MtREV | Dayhoff | DCMut | RtREV | CpREV | VT | Blosum62 | MtMam | MtArt | HIVw | HIVb | custom
+
+ str[0] = raxmlBinName;
+
+ // input alignment
+ str[1] = "-s";
+ str[2] = workAlignment;
+ File f = new File(workAlignment);
+
+ str[5] = "-n";
+ str[6] = outputAppend;
+
+ StringBuilder modelName = new StringBuilder("PROT");
+ if (model.isGamma())
+ modelName.append("GAMMA");
+ else {
+ modelName.append("MIX");
+ }
+ if (model.isInv())
+ modelName.append("I");
+
+ modelName.append(model.getMatrix().toUpperCase());
+
+ if (model.isPlusF())
+ modelName.append("F");
+
+ // the model
+ str[3] = "-m";
+// if (!Arrays.asList(RAXML_MATRICES).contains(model.getMatrix())) {
+// // check matrix file
+// if (!modelFile.exists()) {
+// throw new ModelNotFoundException(model.getMatrix());
+// }
+// str[9] = "custom";
+// } else {
+ str[4] = modelName.toString();
+// }
+
+// if (APPLICATION_PROPERTIES.getProperty("phyml_thread_scheduling", "false").equalsIgnoreCase("true")) {
+// str[24] = "-t";
+// str[25] = String.valueOf(numberOfThreads);
+// }
+ System.out.print("COMMAND: ");
+ for (String tok : str)
+ System.out.print(tok + " ");
+ System.out.println(" ");
+ model.setCommandLine(str);
+ proc = runtime.exec(str);
+ proc.getOutputStream().write(modelFile.getPath().getBytes());
+ ExternalExecutionManager.getInstance().addProcess(proc);
+
+ } else {
+ OSNotSupportedException e =
+ new OSNotSupportedException("PhyML");
+ throw e;
+ }
+ proc.getOutputStream().close();
+
+ StreamGobbler errorGobbler = new RaxMLStreamGobbler(new InputStreamReader(proc.getErrorStream()), "RAxML-Error", true, RunEstimator.class);
+ StreamGobbler outputGobbler = new RaxMLStreamGobbler(new InputStreamReader(proc.getInputStream()), "RAxML-Output", true, RunEstimator.class);
+ errorGobbler.start();
+ outputGobbler.start();
+ int exitVal = proc.waitFor();
+ ExternalExecutionManager.getInstance().removeProcess(proc);
+
+ pfine("RAxML command-line: ");
+ for (int i = 0; i < str.length; i++) {
+ pfine(str[i] + " ");
+ }
+ pfineln("");
+
+ if (exitVal != 0) {
+ errorln("RAxML exit value: " + exitVal + " (there was probably some error)");
+ error("RAxML command-line: ");
+ for (int i = 0; i < str.length; i++) {
+ error(str[i] + " ");
+ }
+ errorln("");
+
+ errorln("Please, take a look at the RAxML log below:");
+ String line;
+ try {
+ FileReader input = new FileReader(TemporaryFileManager.getInstance().getLogFilename(Thread.currentThread()));
+ BufferedReader br = new BufferedReader(input);
+ while ((line = br.readLine()) != null) {
+ errorln(line);
+ }
+ } catch (IOException e) {
+ errorln("Unable to read the log file: " + TemporaryFileManager.getInstance().getLogFilename(Thread.currentThread()));
+ }
+ }
+ } catch (InterruptedException e) {
+ throw new PhyMLExecutionException("Interrupted execution: " + e.getMessage());
+ } catch (IOException e) {
+ throw new PhyMLExecutionException("I/O error: " + e.getMessage());
+ }
+
+
+ if (!(readStatsFile() && readTreeFile())) {
+ return false;
+ }
+
+ return true;
+
+ }
+
+ /**
+ * Delete temporary files.
+ *
+ * @return true, if successful
+ */
+ @Override
+ protected boolean deleteTemporaryFiles() {
+ return true;
+ //throw new UnsupportedOperationException("RAxML is not supported yet. Sorry.");
+ }
+
+ /**
+ * Read the temporary statistics file.
+ *
+ * @return true, if successful
+ */
+ private boolean readStatsFile()
+ throws ModelOptimizationException {
+
+ //Output files:
+ //
+ // Extension given by the -n argument
+ //
+ // RAxML_parsimonyTree.* Parsimony input tree
+ // RAxML_result.* Final tree
+ // RAxML_info.* Results
+ // RAxML_log.* Log
+ String line;
+
+ String alpha, inv, logLK;
+ alpha = inv = logLK = null;
+ try {
+ FileReader input = new FileReader(STATS_PREFIX + outputAppend);
+ BufferedReader br = new BufferedReader(input);
+ while ((line = br.readLine()) != null) {
+ pfinerln("[DEBUG] RAXML: " + line);
+
+ if (line.length() > 0) {
+ if (line.startsWith("Substitution Matrix:")) {
+ String matrixName = Utilities.lastToken(line);
+ if (!model.getMatrix().equalsIgnoreCase(matrixName)) {
+ String errorMsg = "Matrix names doesn't match";
+ errorln("RAXML: " + line);
+ errorln("Last token: " + Utilities.lastToken(line));
+ errorln("It should be: " + model.getMatrix());
+ errorln(errorMsg);
+ throw new ModelNotFoundException(model.getMatrix());
+ }
+ } else if (line.startsWith("Likelihood :")) {
+ logLK = Utilities.lastToken(line);
+ } else if (line.startsWith("Inference[0]")) {
+ alpha = Utilities.nextToken(line, "alpha[0]:");
+ inv = Utilities.nextToken(line, "invar[0]:");
+
+ pfinerln("[DEBUG] RAXML: " + line);
+
+ } else if (line.startsWith("Overall Time")) {
+ time = Utilities.lastToken(line);
+ }
+ }
+ }
+
+ model.setLk(Double.parseDouble(logLK));
+ if (alpha != null) {
+ model.setAlpha(Double.parseDouble(alpha));
+ }
+ if (inv != null) {
+ model.setInv(Double.parseDouble(inv));
+ }
+
+ } catch (IOException e) {
+ throw new StatsFileFormatException("RAxML", e.getMessage());
+ }
+ return true;
+ }
+
+ /**
+ * Read the temporary tree file.
+ *
+ * @return true, if successful
+ *
+ * @throws TreeFormatException the tree format exception
+ */
+ private boolean readTreeFile()
+ throws TreeFormatException {
+
+ try {
+ model.setTree(new ReadTree(FINAL_TREE_PREFIX + outputAppend));
+ } catch (TreeParseException e) {
+ String errorMsg = "ProtTest: wrong tree format, exiting...";
+ throw new TreeFormatException(errorMsg);
+ } catch (IOException e) {
+ String errorMsg = "Error: File not found (IO error), exiting...";
+ throw new TreeFormatException(errorMsg);
+ }
+ return true;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLStreamGobbler.java b/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLStreamGobbler.java
new file mode 100755
index 0000000..3ac7793
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/RaxMLStreamGobbler.java
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 2004 Federico Abascal
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Allows the asynchronous logging of an input stream.
+ *
+ * @author Federico Abascal
+ */
+public class RaxMLStreamGobbler extends StreamGobbler {
+
+ /**
+ * Instantiates a new StreamGobbler
+ *
+ * @param isr the input stream reader to evaluate
+ * @param type the prefix of the output lines
+ * @param printIt true, if the errors should be logged
+ * @param caller the caller
+ */
+ public RaxMLStreamGobbler(InputStreamReader isr, String type, boolean printIt, Class caller) {
+ super(isr,type,printIt,caller);
+ }
+
+ @Override
+ /* (non-Javadoc)
+ * @see java.lang.Thread#run()
+ */
+ public void run() {
+ try {
+ //InputStreamReader isr = new InputStreamReader(is);
+ BufferedReader br = new BufferedReader(isr);
+ String line = null;
+ while ((line = br.readLine()) != null) {
+ ProtTestLogger.finestln(type + ">" + line, caller);
+ }
+ } catch (IOException ioe) {
+
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimator.java b/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimator.java
new file mode 100755
index 0000000..5a26786
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimator.java
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+
+/**
+ * The Interface RunEstimator. Should be implemented by any class which launches
+ * an external likelihood calculator or directly calculates likelihood for any
+ * kind of model.
+ *
+ * @author Federico Abascal
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public interface RunEstimator extends Runnable {
+
+ /**
+ * Gets the inner optimized model.
+ *
+ * @return the model
+ */
+ public Model getModel();
+
+ /**
+ * Optimizes the parameters of the model.
+ *
+ * @return true, if there is no error in the execution of the optimizer
+ */
+ public boolean optimizeModel();
+
+ /**
+ * Reports out the result of the optimization into the application loggers:
+ * the optimized parameters of the model.
+ */
+ public void report();
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.observer.ObservableModelUpdater#addObserver(es.uvigo.darwin.prottest.observer.ObservableModelUpdater)
+ */
+ public void addObserver(ModelUpdaterObserver o);
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimatorImpl.java b/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimatorImpl.java
new file mode 100755
index 0000000..f1137e2
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/RunEstimatorImpl.java
@@ -0,0 +1,212 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.exception.ModelOptimizationException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.*;
+
+/**
+ * Template implementation for every subclass applying the
+ * observer pattern into the analyzers.
+ *
+ * @author Federico Abascal
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public abstract class RunEstimatorImpl
+ extends ObservableModelUpdater
+ implements RunEstimator {
+
+ /** The application options instance. */
+ protected ApplicationOptions options;
+ /** The inner model to optimize. */
+ protected Model model;
+ /** Indicates if the inner model is yet optimized. */
+ private boolean optimized;
+ /** The time taken for the optimization. */
+ protected String time;
+ /** The number of rate categories. */
+ protected int numberOfCategories;
+ /** The independent process. */
+ protected Process proc = null;
+ /** The number of threads for parallel execution **/
+ protected int numberOfThreads = 1;
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#getModel()
+ */
+ public Model getModel() {
+ return model;
+ }
+
+ /**
+ * Gets the thread pool size.
+ *
+ * @return the thread pool size
+ */
+ protected int getPoolSize() {
+ return 1;
+ }
+
+ /**
+ * Gets the time taken to compute.
+ *
+ * @return the time
+ */
+ public String getTime() {
+ if (optimized) {
+ return time;
+ } else {
+ throw new ProtTestInternalException("The model is not optimized");
+ }
+ }
+
+ /**
+ * Instantiates a new generic optimizer.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ */
+ public RunEstimatorImpl(ApplicationOptions options, Model model) {
+ this(options, model, 1);
+ }
+
+ /**
+ * Instantiates a new generic optimizer.
+ *
+ * @param options the application options instance
+ * @param model the amino-acid model to optimize
+ * @param numberOfThreads the number of threads to use in the optimization
+ */
+ public RunEstimatorImpl(ApplicationOptions options, Model model, int numberOfThreads) {
+ this.options = options;
+ this.model = model;
+ this.optimized = model.isComputed();
+ this.numberOfThreads = numberOfThreads;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#optimizeModel(es.uvigo.darwin.prottest.global.options.ApplicationOptions)
+ */
+ public boolean optimizeModel() {
+
+ // notify task computation
+ notifyObservers(getModel(),null);
+
+ boolean result = true;
+ try {
+ if (!optimized) {
+ result = runEstimator();
+ }
+ } catch (ModelOptimizationException ex) {
+
+ severeln(ex.getMessage(), RunEstimator.class);
+
+ } finally {
+ // notify results
+ notifyObservers(getModel(), options);
+ deleteTemporaryFiles();
+ }
+
+ optimized = result;
+
+ return result;
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.exe.RunEstimator#report()
+ */
+ public void report() {
+
+ if (optimized) {
+ printReport();
+ } else {
+ throw new ProtTestInternalException("The model is not optimized");
+ }
+
+ }
+
+ /**
+ * Runs the estimator.
+ *
+ * @return true, if successful
+ */
+ public abstract boolean runEstimator()
+ throws ModelOptimizationException;
+
+ /**
+ * Prints a report of the execution.
+ */
+ public abstract void printReport();
+
+ /**
+ * Deletes temporary files of the execution.
+ *
+ * @return true, if successful
+ */
+ protected abstract boolean deleteTemporaryFiles();
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+
+ if (!this.optimizeModel()) {
+ throw new ProtTestInternalException("Optimization error");
+ }
+ }
+
+ protected void print(String message) {
+ info(message, RunEstimator.class);
+ }
+
+ protected void println(String message) {
+ infoln(message, RunEstimator.class);
+ }
+
+ protected void error(String message) {
+ severe(message, RunEstimator.class);
+ }
+
+ protected void errorln(String message) {
+ severeln(message, RunEstimator.class);
+ }
+
+ protected void pfine(String message) {
+ fine(message, RunEstimator.class);
+ }
+
+ protected void pfineln(String message) {
+ fineln(message, RunEstimator.class);
+ }
+
+ protected void pfiner(String message) {
+ finer(message, RunEstimator.class);
+ }
+
+ protected void pfinerln(String message) {
+ finerln(message, RunEstimator.class);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/StreamGobbler.java b/src/main/java/es/uvigo/darwin/prottest/exe/StreamGobbler.java
new file mode 100755
index 0000000..f3a553a
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/StreamGobbler.java
@@ -0,0 +1,53 @@
+/*
+Copyright (C) 2004 Federico Abascal
+
+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
+*/
+package es.uvigo.darwin.prottest.exe;
+
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Allows the asynchronous logging of an input stream.
+ *
+ * @author Federico Abascal
+ */
+public abstract class StreamGobbler extends Thread {
+
+ protected InputStreamReader isr;
+ protected String type;
+ protected boolean printIt;
+ protected Class caller;
+
+ /**
+ * Instantiates a new StreamGobbler
+ *
+ * @param isr the input stream reader to evaluate
+ * @param type the prefix of the output lines
+ * @param printIt true, if the errors should be logged
+ * @param caller the caller
+ */
+ public StreamGobbler(InputStreamReader isr, String type, boolean printIt, Class caller) {
+ this.isr = isr;
+ this.type = type;
+ this.printIt = printIt;
+ this.caller = caller;
+ }
+
+}
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/package.html b/src/main/java/es/uvigo/darwin/prottest/exe/package.html
new file mode 100755
index 0000000..6029212
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/package.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+<p>
+Contains all classes related to model optimization. The <code>RunEstimator</code> interface
+contains the method signatures which every optimizer must implement. There is a generic
+class with common method implementations: <code>RunEstimatorImpl</code>, but every specific
+strategy to optimize the models should extend this class or at least implement the interface.
+</p>
+<p>
+For example, <code>PhyML</code> optimizer has his own implementation <code>PhyMLv3AminoAcidRunEstimator</code>.
+In future versions this vertical hierarchy, which could allow extension to support Nucleotide models,
+should be transformed following a Bridge Pattern.
+</p>
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/util/TemporaryFileManager.java b/src/main/java/es/uvigo/darwin/prottest/exe/util/TemporaryFileManager.java
new file mode 100755
index 0000000..4db5dcb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/util/TemporaryFileManager.java
@@ -0,0 +1,256 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.exe.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import pal.alignment.Alignment;
+import pal.alignment.AlignmentUtils;
+import pal.tree.Tree;
+import pal.tree.TreeUtils;
+import es.uvigo.darwin.prottest.facade.thread.ThreadPoolSynchronizer;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * A singleton class to manage the temporary files usage in the
+ * application. It should be accessible for every thread that gets
+ * part in the execution.
+ */
+public class TemporaryFileManager {
+
+ /** The Constant BASE_ALIGNMENT_FILE_NAME. */
+ private static final String BASE_ALIGNMENT_FILE_NAME = "prottest_alignment_";
+
+ /** The Constant BASE_TREE_FILE_NAME. */
+ private static final String BASE_TREE_FILE_NAME = "prottest_tree_";
+
+ /** The Constant BASE_LOG_FILE_NAME. */
+ private static final String BASE_LOG_FILE_NAME = "prottest_";
+
+ /** The unique instance. */
+ private static TemporaryFileManager instance;
+
+ /** The alignment temporary files. */
+ private File[] alignmentTempFile;
+
+ /** The log temporary files. */
+ private File[] logTempFile;
+
+ /** The tree temporary file. */
+ private File treeTempFile;
+
+ /** The thread pool synchronizer. */
+ private ThreadPoolSynchronizer synchronizer;
+
+ /** The alignment. */
+ private Alignment alignment;
+
+ /** The tree. */
+ private Tree tree;
+
+ /**
+ * Gets the alignment filename.
+ *
+ * @param thread the thread
+ *
+ * @return the alignment filename
+ */
+ public String getAlignmentFilename(Thread thread) {
+ int threadId = synchronizer.getThreadId(thread);
+ return alignmentTempFile[threadId].getAbsolutePath();
+ }
+
+ /**
+ * Gets the log filename.
+ *
+ * @param thread the thread
+ *
+ * @return the log filename
+ */
+ public String getLogFilename(Thread thread) {
+ int threadId = synchronizer.getThreadId(thread);
+ return logTempFile[threadId].getAbsolutePath();
+ }
+
+ /**
+ * Gets the tree filename for a thread.
+ *
+ * @param thread the thread
+ *
+ * @return the tree filename
+ */
+ public String getTreeFilename(Thread thread) {
+ if (tree == null)
+ return null;
+ return treeTempFile.getAbsolutePath();
+ }
+
+ /**
+ * Checks if is synchronized.
+ *
+ * @return true, if is synchronized
+ */
+ public static boolean isSynchronized() {
+ return instance != null;
+ }
+
+ /**
+ * Sets the input tree. For each manager sync, the input tree should be set just
+ * once, or all the trees must be the same (i.e., this method can be used to
+ * check consistency between processes)
+ *
+ * @param tree the new tree
+ *
+ * @throws ProtTestInternalException when attempting to set different trees
+ */
+ public void setTree(Tree tree) {
+ if (this.tree == null) {
+ convertTree(tree, treeTempFile);
+ this.tree = tree;
+ } else {
+ if (!tree.equals(this.tree)) {
+ throw new ProtTestInternalException("Attempting to set different trees");
+ }
+ }
+
+ }
+
+ /**
+ * Gets the input tree.
+ *
+ * @return the tree
+ */
+ public Tree getTree() {
+ return tree;
+ }
+
+ /**
+ * Gets the input alignment.
+ *
+ * @return the alignment
+ */
+ public Alignment getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Instantiates a new temporary file manager.
+ *
+ * @param path the path
+ * @param alignment the alignment
+ * @param tree the tree
+ * @param poolSize the pool size
+ */
+ private TemporaryFileManager(Alignment alignment, Tree tree, int poolSize) {
+
+ alignmentTempFile = new File[poolSize];
+ logTempFile = new File[poolSize];
+ this.alignment = alignment;
+ this.tree = tree;
+
+ try {
+ for (int i = 0; i < poolSize; i++) {
+ alignmentTempFile[i] = File.createTempFile(BASE_ALIGNMENT_FILE_NAME, null);
+ alignmentTempFile[i].deleteOnExit();
+ logTempFile[i] = File.createTempFile(BASE_LOG_FILE_NAME, null);
+ logTempFile[i].deleteOnExit();
+ convertAlignment(alignment, alignmentTempFile[i]);
+ }
+ treeTempFile = File.createTempFile(BASE_TREE_FILE_NAME, null);
+ treeTempFile.deleteOnExit();
+ if (tree != null)
+ convertTree(tree, treeTempFile);
+ } catch (IOException e) {
+ throw new ProtTestInternalException("Cannot create temporary files");
+ }
+ ThreadPoolSynchronizer.synchronize(poolSize);
+ synchronizer = ThreadPoolSynchronizer.getInstance();
+ }
+
+ /**
+ * Gets the single instance of TemporaryFileManager.
+ *
+ * @return single instance of TemporaryFileManager
+ */
+ public static TemporaryFileManager getInstance() {
+ if (instance == null) {
+ throw new ProtTestInternalException("TemporaryFileManager out of sync");
+ }
+ return instance;
+ }
+
+ /**
+ * Synchronizes this manager.
+ *
+ * @param alignment the input alignment
+ * @param tree the input tree
+ * @param poolSize the pool size
+ */
+ public static void synchronize(Alignment alignment, Tree tree, int poolSize) {
+ instance = new TemporaryFileManager(alignment, tree, poolSize);
+ }
+
+ /**
+ * Converts an alignment into a file.
+ *
+ * @param alignment the input alignment
+ * @param outputFile the output file
+ *
+ * @return true, if successful
+ */
+ private boolean convertAlignment(Alignment alignment, File outputFile) {
+ try {
+ FileOutputStream fo = new FileOutputStream(outputFile);
+ PrintWriter output = new PrintWriter(fo);
+ //AlignmentUtils.printSequential(alignment, output);
+ AlignmentUtils.printInterleaved(alignment, output);
+ output.flush();
+ output.close();
+ } catch (IOException e) {
+ throw new ProtTestInternalException();
+ }
+ return true;
+ }
+
+ /**
+ * Converts a tree into a file.
+ *
+ * @param tree the input tree
+ * @param outputFile the output file
+ *
+ * @return true, if successful
+ */
+ private boolean convertTree(Tree tree, File outputFile) {
+ if (tree != null) {
+ try {
+ FileOutputStream fo = new FileOutputStream(outputFile);
+ PrintWriter output = new PrintWriter(fo);
+ TreeUtils.printNH(tree, output);
+ output.flush();
+ output.close();
+ } catch (IOException e) {
+ throw new ProtTestInternalException();
+ }
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/exe/util/package.html b/src/main/java/es/uvigo/darwin/prottest/exe/util/package.html
new file mode 100755
index 0000000..4a1e447
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/exe/util/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains common utils related to model optimization.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacade.java b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacade.java
new file mode 100755
index 0000000..0e30b7a
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacade.java
@@ -0,0 +1,144 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.prottest.facade;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.facade.util.ProtTestParameterVO;
+import es.uvigo.darwin.prottest.facade.util.SelectionChunk;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import java.io.FileNotFoundException;
+
+/**
+ * Declaration of general services of ProtTest-HPC
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public interface ProtTestFacade extends ModelUpdaterObserver {
+
+ // **********************************************************
+ // ALIGNMENT ANALYSIS SERVICES
+ // **********************************************************
+ /**
+ * Starts the analysis of the alignment having the application options given
+ * in the command line. It will also print results as given in the
+ * application options.
+ *
+ * @param options
+ * the execution options
+ *
+ * @return set of optimized models
+ */
+ public Model[] startAnalysis(ApplicationOptions options);
+
+ // **********************************************************
+ // RESULT ANALYSIS SERVICES
+ // **********************************************************
+ /**
+ * Prints the models sorted according to the selected information criterion.
+ *
+ * @param informationCriterion
+ * the information criterion to sort the models
+ */
+ public void printModelsSorted(InformationCriterion informationCriterion);
+
+ /**
+ * Calculates a Information Criterion wrapped into a Selection chunk object,
+ * which is a value-object
+ *
+ * @param alignment
+ * the alignment.
+ * @param models
+ * the optimized models .
+ * @param criterion
+ * the Information Criterion Constant.
+ * @param confidenceInterval
+ * the confidence interval.
+ */
+ public SelectionChunk computeInformationCriterion(Alignment alignment,
+ Model[] models, int criterion, double confidenceInterval);
+
+ // **********************************************************
+ // INPUT SERVICES
+ // **********************************************************
+ /**
+ * Read alignment.
+ *
+ * @param filename
+ * the filename
+ * @param debug
+ * the debug
+ *
+ * @return the alignment
+ *
+ * @throws AlignmentParseException
+ * the alignment parse exception
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public Alignment readAlignment(String filename, boolean debug)
+ throws AlignmentParseException, FileNotFoundException, IOException;
+
+ /**
+ * Read alignment.
+ *
+ * @param out
+ * the out
+ * @param filename
+ * the filename
+ * @param debug
+ * the debug
+ *
+ * @return the alignment
+ *
+ * @throws AlignmentParseException
+ * the alignment parse exception
+ * @throws IOException
+ * Signals that an I/O exception has occurred.
+ */
+ public Tree readTree(PrintWriter out, String filename, boolean debug)
+ throws TreeFormatException, FileNotFoundException, IOException;
+
+ // **********************************************************
+ // MISC SERVICES
+ // **********************************************************
+ public ApplicationOptions configure(ProtTestParameterVO parameters)
+ throws IOException, AlignmentParseException,
+ ProtTestInternalException;
+
+ public void addObserver(ModelUpdaterObserver o);
+
+ public void update(ObservableModelUpdater o, Model model,
+ ApplicationOptions options);
+
+ public int getNumberOfThreads();
+
+ public void setNumberOfThreads(int numThreads);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeImpl.java b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeImpl.java
new file mode 100755
index 0000000..0605191
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeImpl.java
@@ -0,0 +1,276 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Properties;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.exe.util.TemporaryFileManager;
+import es.uvigo.darwin.prottest.facade.util.ProtTestParameterVO;
+import es.uvigo.darwin.prottest.facade.util.SelectionChunk;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.selection.AIC;
+import es.uvigo.darwin.prottest.selection.AICc;
+import es.uvigo.darwin.prottest.selection.BIC;
+import es.uvigo.darwin.prottest.selection.DT;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.LNL;
+import es.uvigo.darwin.prottest.selection.printer.AminoAcidPrintFramework;
+import es.uvigo.darwin.prottest.selection.printer.PrintFramework;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+import es.uvigo.darwin.prottest.util.fileio.AlignmentReader;
+
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.StringWriter;
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.*;
+
+/**
+ * An abstract implementation of the ProtTest facade.
+ */
+public abstract class ProtTestFacadeImpl
+ extends ObservableModelUpdater
+ implements ProtTestFacade {
+
+// /** The options. */
+// protected ApplicationOptions options;
+ /** The Constant AIC. */
+ public static final int AIC = SelectionChunk.AIC;
+ /** The Constant BIC. */
+ public static final int BIC = SelectionChunk.BIC;
+ /** The Constant AICC. */
+ public static final int AICC = SelectionChunk.AICC;
+ /** The Constant DT. */
+ public static final int DT = SelectionChunk.DT;
+ /** The Constant LK. */
+ public static final int LNL = SelectionChunk.LNL;
+
+ /**
+ * Instantiates a new prot test facade implementation.
+ */
+ public ProtTestFacadeImpl() {
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#printModelsSorted(es.uvigo.darwin.prottest.selection.InformationCriterion, java.io.PrintWriter)
+ */
+ public void printModelsSorted(InformationCriterion informationCriterion) {
+
+ PrintFramework printFramework = new AminoAcidPrintFramework();
+
+ printFramework.printModelsSorted(informationCriterion);
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#readAlignment(java.io.PrintWriter, java.lang.String, boolean)
+ */
+ public Alignment readAlignment(String filename, boolean debug)
+ throws AlignmentParseException, FileNotFoundException, IOException {
+
+ StringWriter sw = new StringWriter();
+ Alignment alignment = AlignmentReader.readAlignment(new PrintWriter(sw), filename, debug);
+
+ sw.flush();
+ ProtTestLogger.getDefaultLogger().infoln(sw.toString());
+
+ return alignment;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#readTree(java.io.PrintWriter, java.lang.String, boolean)
+ */
+ public Tree readTree(PrintWriter out, String filename, boolean debug)
+ throws TreeFormatException, FileNotFoundException, IOException {
+
+ return AlignmentReader.readTree(out, filename, debug);
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#update(es.uvigo.darwin.prottest.observer.Observable, java.lang.Object)
+ */
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+ notifyObservers(model, options);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#computeInformationCriterion(pal.alignment.Alignment, es.uvigo.darwin.prottest.model.Model[], int, int, double)
+ */
+ public SelectionChunk computeInformationCriterion(Alignment alignment, Model[] models,
+ int criterion,
+ double confidenceInterval) {
+
+ ModelCollection modelCollection = new SingleModelCollection(models, alignment);
+
+ InformationCriterion informationCriterion;
+
+ double calculatedSampleSize = ProtTestAlignment.calculateSampleSize(alignment);
+
+ switch (criterion) {
+ case AIC:
+ informationCriterion = new AIC(modelCollection, confidenceInterval, calculatedSampleSize);
+ break;
+ case BIC:
+ informationCriterion = new BIC(modelCollection, confidenceInterval, calculatedSampleSize);
+ break;
+ case AICC:
+ informationCriterion = new AICc(modelCollection, confidenceInterval, calculatedSampleSize);
+ break;
+ case DT:
+ informationCriterion = new DT(modelCollection, confidenceInterval, calculatedSampleSize);
+ break;
+ case LNL:
+ informationCriterion = new LNL(modelCollection, confidenceInterval, calculatedSampleSize);
+ break;
+ default:
+ throw new ProtTestInternalException("Unexistent information criterion");
+ }
+
+ return new SelectionChunk(informationCriterion);
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#getNumberOfThreads()
+ */
+ public int getNumberOfThreads() {
+ // single thread (default)
+ return 1;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#setNumberOfThreads(int)
+ */
+ public void setNumberOfThreads(int numThreads) {
+ throw new ProtTestInternalException("No threading support");
+ }
+
+ protected Tree calculateBionjJTT(ApplicationOptions options) {
+
+ Model jttModel = ProtTestFactory.getInstance().createModel("JTT", options.getDistribution("Uniform"), new Properties(),
+ options.getAlignment(), null, 0);
+ TemporaryFileManager.synchronize(
+ options.getAlignment(), null, 1);
+ RunEstimator treeEstimator = ProtTestFactory.getInstance().createRunEstimator(options, jttModel);
+ treeEstimator.run();
+
+ return jttModel.getTree();
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#startAnalysis(es.uvigo.darwin.prottest.util.printer.ProtTestPrinter)
+ */
+ public Model[] startAnalysis(ApplicationOptions options) {
+
+ if (options.getTreeFile() == null) {
+ // this way, the starting topology is the same for every model
+ if (options.strategyMode == OPTIMIZE_FIXED_BIONJ) {
+ // use JTT BIONJ Tree
+ Tree jttTree = calculateBionjJTT(options);
+
+ options.setTree(jttTree);
+ }
+ }
+ TemporaryFileManager.synchronize(options.getAlignment(), options.getTree(),
+ getNumberOfThreads());
+ Model[] models = analyze(options);
+
+ return models;
+ }
+
+ /**
+ * Analyze.
+ *
+ * @param options the execution options
+ *
+ * @return the set of optimized models
+ */
+ public abstract Model[] analyze(ApplicationOptions options);
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#configure(es.uvigo.darwin.prottest.facade.util.ProtTestParameterVO)
+ */
+ public ApplicationOptions configure(ProtTestParameterVO parameters)
+ throws IOException, AlignmentParseException, ProtTestInternalException {
+ ApplicationOptions options = new ApplicationOptions();
+ if (parameters.getAlignment() != null) {
+ options.setAlignment(parameters.getAlignment());
+ options.setAlignmentFilename(parameters.getAlignmentFilePath());
+ } else {
+ options.setAlignment(parameters.getAlignmentFilePath());
+ }
+ options.setNumberOfCategories(parameters.ncat);
+ for (String matrix : parameters.getMatrices()) {
+ options.addMatrix(matrix);
+ }
+ for (String distribution : parameters.getDistributions()) {
+ options.addDistribution(distribution);
+ }
+ options.setPlusF(parameters.isPlusF());
+ options.setTreeFile(parameters.getTreeFilePath());
+ options.setStrategyMode(parameters.getStrategyMode());
+ return options;
+ }
+
+ protected void print(String message) {
+ info(message, ProtTestFacade.class);
+ }
+
+ protected void println(String message) {
+ infoln(message, ProtTestFacade.class);
+ }
+
+ protected void error(String message) {
+ severe(message, ProtTestFacade.class);
+ }
+
+ protected void errorln(String message) {
+ severeln(message, ProtTestFacade.class);
+ }
+
+ protected void warnln(String message) {
+ warningln(message, ProtTestFacade.class);
+ }
+
+ protected void verbose(String message) {
+ fine(message, ProtTestFacade.class);
+ }
+
+ protected void verboseln(String message) {
+ fineln(message, ProtTestFacade.class);
+ }
+
+ protected void flush() {
+ ProtTestLogger.flush(ProtTestFacade.class);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeMPJ.java b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeMPJ.java
new file mode 100755
index 0000000..8789c40
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeMPJ.java
@@ -0,0 +1,210 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.APPLICATION_PROPERTIES;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Properties;
+
+import mpi.MPI;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.exe.util.TemporaryFileManager;
+import es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy;
+import es.uvigo.darwin.prottest.facade.strategy.DynamicDistributionStrategy;
+import es.uvigo.darwin.prottest.facade.strategy.HybridDistributionStrategy;
+import es.uvigo.darwin.prottest.facade.strategy.ImprovedDynamicDistributionStrategy;
+import es.uvigo.darwin.prottest.facade.strategy.StaticDistributionStrategy;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.checkpoint.status.ProtTestStatus;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.AminoAcidModelNaturalComparator;
+import es.uvigo.darwin.prottest.util.comparator.ModelDistributionHeuristic;
+
+/**
+ * A parallel implementation of the ProtTest facade.
+ */
+public class ProtTestFacadeMPJ extends ProtTestFacadeImpl {
+
+ /** The parallel distribution strategy. */
+ private DistributionStrategy strategy;
+ /** Boolean variable to show if MPJ environment is running. Some
+ * distribution strategies can be used even if the execution is
+ * sequential. */
+ private boolean mpjRun;
+ /** The MPJ rank of the process. It is only useful if MPJ is running. */
+ private int mpjMe;
+ /** The MPJ size of the communicator. It is only useful if MPJ is running. */
+ private int mpjSize;
+ /** The thread pool size. */
+ private int poolSize = 1;
+ private CheckPointManager cpManager;
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#getNumberOfThreads()
+ */
+ @Override
+ public int getNumberOfThreads() {
+ return poolSize;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#setNumberOfThreads(int)
+ */
+ @Override
+ public void setNumberOfThreads(int numThreads) {
+// options.setNumberOfThreads(numThreads);
+ this.poolSize = numThreads;
+ }
+
+ /**
+ * Instantiates a new parallel ProtTest facade.
+ *
+ * @param mpjRun the running state of MPJ
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ */
+ public ProtTestFacadeMPJ(boolean mpjRun, int mpjMe, int mpjSize) {
+ this.mpjRun = mpjRun;
+ this.mpjMe = mpjMe;
+ this.mpjSize = mpjSize;
+ }
+
+ @Override
+ protected Tree calculateBionjJTT(ApplicationOptions options) {
+ Tree[] t = new Tree[1];
+ if (mpjMe == 0) {
+ t[0] = super.calculateBionjJTT(options);
+ }
+ MPI.COMM_WORLD.Bcast(t, 0, 1, MPI.OBJECT, 0);
+ return t[0];
+ }
+
+ public Model[] analyze(ApplicationOptions options) {
+
+ ModelCollection arrayListModel = null;
+ if (mpjMe == 0) {
+ //Adding support for checkpointing
+ ProtTestStatus initialStatus = new ProtTestStatus(null, options);
+
+ cpManager = new CheckPointManager();
+ if (cpManager.loadStatus(initialStatus)) {
+ arrayListModel = new SingleModelCollection(
+ ((ProtTestStatus) cpManager.getLastCheckpoint()).getModels(),
+ options.getAlignment());
+ } else {
+ arrayListModel = new SingleModelCollection(options.getAlignment());
+ Properties modelProperties = new Properties();
+ if (options.isPlusF()) {
+ modelProperties.setProperty(Model.PROP_PLUS_F, "true");
+ }
+ arrayListModel.addModelCartesian(options.getMatrices(), options.getDistributions(), modelProperties,
+ options.getAlignment(), options.getTree(), options.ncat);
+ }
+ }
+ String strategyProp = APPLICATION_PROPERTIES.getProperty("parallel_strategy", "static");
+
+ if (strategyProp.equals("dynamic")) {
+ strategy = new DynamicDistributionStrategy(mpjMe, mpjSize, options, cpManager);
+ } else if (strategyProp.equals("dynamic_improved")) {
+ strategy = new ImprovedDynamicDistributionStrategy(mpjMe, mpjSize, options, cpManager);
+ } else if (strategyProp.equals("hybrid")) {
+ int numberOfThreads;
+ try {
+ numberOfThreads = Integer.parseInt(APPLICATION_PROPERTIES.getProperty("number_of_threads",
+ String.valueOf(Runtime.getRuntime().availableProcessors())));
+ } catch (NumberFormatException ex) {
+ numberOfThreads = Runtime.getRuntime().availableProcessors();
+ }
+ setNumberOfThreads(numberOfThreads);
+ strategy = new HybridDistributionStrategy(mpjMe, mpjSize, options, cpManager, getNumberOfThreads());
+ TemporaryFileManager.synchronize(options.getAlignment(), options.getTree(),
+ getNumberOfThreads());
+ } else {
+ strategy = new StaticDistributionStrategy(mpjMe, mpjSize, options);
+ }
+ strategy.addObserver(this);
+
+ Model[] allModels = null;
+
+ //For each model, for each distribution,... optimize the model and calculate some statistics:
+ if (mpjMe == 0) {
+ println("**********************************************************");
+ //this is only for doing output prettier
+ println("Observed number of invariant sites: " + ProtTestAlignment.calculateInvariableSites(options.getAlignment(), false));
+ StringWriter sw = new StringWriter();
+ ProtTestAlignment.printFrequencies(ProtTestAlignment.getFrequencies(options.getAlignment()), new PrintWriter(sw));
+ sw.flush();
+ println(sw.toString());
+ println("**********************************************************");
+ println("");
+
+ allModels = strategy.distribute(arrayListModel, new ModelDistributionHeuristic());
+ } else {
+ strategy.request();
+ }
+ long startTime = strategy.getStartTime();
+ long endTime = strategy.getEndTime();
+ if (mpjRun) {
+
+ long[] runtime = {endTime - startTime};
+ long[] runtimes = new long[mpjSize];
+ // gathering run times
+ MPI.COMM_WORLD.Gather(runtime, 0, 1, MPI.LONG,
+ runtimes, 0, 1, MPI.LONG, 0);
+ if (mpjMe == 0) {
+ List<Model> sortedModels = new SingleModelCollection(allModels, options.getAlignment());
+ Collections.sort(sortedModels, new AminoAcidModelNaturalComparator());
+ for (Model model : sortedModels) {
+ println("");
+ model.printReport();
+ println("");
+ }
+ println("************************************************************");
+ println("Date: " + (new Date()).toString());
+ for (int i = 0; i < mpjSize; i++) {
+ println("Runtime processor " + i + ": " + Utilities.arrangeRuntime(runtimes[i]));
+ }
+ println("Minimum runtime: " + Utilities.arrangeRuntime(Utilities.getMin(runtimes)));
+ println("Maximum runtime: " + Utilities.arrangeRuntime(Utilities.getMax(runtimes)));
+ println("Average runtime: " + Utilities.arrangeRuntime(Utilities.getAverage(runtimes)));
+ println("");
+ println("");
+ flush();
+ }
+ } else {
+ println("************************************************************");
+ String runtimeStr = Utilities.calculateRuntime(startTime, endTime);
+ println("Date : " + (new Date()).toString());
+ println("Runtime: " + runtimeStr);
+ println("");
+ println("");
+ }
+
+ return allModels;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeSequential.java b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeSequential.java
new file mode 100755
index 0000000..a9ce4b7
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeSequential.java
@@ -0,0 +1,135 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Date;
+import java.util.Properties;
+
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.checkpoint.status.ProtTestStatus;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+
+/**
+ * A sequential implementation of the ProtTest facade.
+ */
+public class ProtTestFacadeSequential extends ProtTestFacadeImpl {
+
+ private CheckPointManager cpManager;
+ private ModelCollection modelSet;
+ /** The ProtTest factory to instantiate some application objects. */
+ private ProtTestFactory factory = ProtTestFactory.getInstance();
+
+ public Model[] analyze(ApplicationOptions options) {
+
+ //For each model, for each distribution,... optimize the model and calculate some statistics:
+
+ println("**********************************************************");
+ //this is only for doing output prettier
+ println("Observed number of invariant sites: " + ProtTestAlignment.calculateInvariableSites(options.getAlignment(), false));
+ StringWriter sw = new StringWriter();
+ ProtTestAlignment.printFrequencies(ProtTestAlignment.getFrequencies(options.getAlignment()),
+ new PrintWriter(sw));
+ sw.flush();
+ println(sw.toString());
+ println("**********************************************************");
+ println("");
+
+ //TimeStamp timer = new TimeStamp();
+ Date startDate = new Date();
+ long startTime = startDate.getTime();
+
+ int numberOfModels = 0;
+
+ ModelCollection arrayListModel = new SingleModelCollection(options.getAlignment());
+
+ //Adding support for checkpointing
+ ProtTestStatus initialStatus = new ProtTestStatus(null, options);
+ cpManager = new CheckPointManager();
+
+ if (cpManager.loadStatus(initialStatus)) {
+ arrayListModel = new SingleModelCollection(
+ ((ProtTestStatus) cpManager.getLastCheckpoint()).getModels(),
+ options.getAlignment());
+ } else {
+ Properties modelProperties = new Properties();
+
+ if (options.isPlusF()) {
+ modelProperties.setProperty(Model.PROP_PLUS_F, "true");
+ }
+ arrayListModel.addModelCartesian(options.getMatrices(), options.getDistributions(), modelProperties,
+ options.getAlignment(), options.getTree(), options.ncat);
+ }
+ numberOfModels = arrayListModel.size();
+ modelSet = arrayListModel;
+
+ flush();
+
+ RunEstimator[] runenv = new RunEstimator[modelSet.size()];
+
+ int current = 0;
+ for (Model model : modelSet) {
+
+ runenv[current] = factory.createRunEstimator(options, model);
+ runenv[current].addObserver(this);
+ runenv[current].run();
+
+ runenv[current].report();
+ flush();
+ current++;
+
+ }
+
+ long endTime = System.currentTimeMillis();
+
+ Model[] allModels = new Model[numberOfModels];
+
+ println("************************************************************");
+ String runtimeStr = Utilities.calculateRuntime(startTime, endTime);
+ println("Date : " + (new Date()).toString());
+ println("Runtime: " + runtimeStr);
+ println("");
+ println("");
+ allModels = modelSet.toArray(new Model[0]);
+
+ cpManager.done();
+ return allModels;
+ }
+
+ @Override
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+
+ if (model.isComputed() && options != null) {
+ if (cpManager != null) {
+ ProtTestStatus newStatus = new ProtTestStatus(modelSet.toArray(new Model[0]), options);
+ cpManager.setStatus(newStatus);
+ }
+ }
+
+ super.update(o, model, options);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeThread.java b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeThread.java
new file mode 100755
index 0000000..0545ba7
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/ProtTestFacadeThread.java
@@ -0,0 +1,231 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.Utilities;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.checkpoint.status.ProtTestStatus;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.AminoAcidModelNaturalComparator;
+import es.uvigo.darwin.prottest.util.comparator.ModelDistributionHeuristic;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+
+/**
+ * A parallel implementation of the ProtTest facade.
+ */
+public class ProtTestFacadeThread
+ extends ProtTestFacadeImpl {
+
+ private CheckPointManager cpManager;
+ private ModelCollection modelSet;
+ /** The thread pool size. */
+ private int poolSize;
+ /** The ProtTest factory to instantiate some application objects. */
+ private ProtTestFactory factory = ProtTestFactory.getInstance();
+ private ExecutorService threadPool;
+
+ /**
+ * Instantiates a new parallel ProtTest facade.
+ *
+ * @param poolSize the number of parallel processes
+ */
+ public ProtTestFacadeThread(int poolSize) {
+ this.poolSize = poolSize;
+// options.setNumberOfThreads(poolSize);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#getNumberOfThreads()
+ */
+ @Override
+ public int getNumberOfThreads() {
+ return poolSize;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#setNumberOfThreads(int)
+ */
+ @Override
+ public void setNumberOfThreads(int numThreads) {
+// options.setNumberOfThreads(numThreads);
+ this.poolSize = numThreads;
+ }
+
+ public Model[] analyze(ApplicationOptions options) {
+
+ this.threadPool = Executors.newFixedThreadPool(this.poolSize);
+
+ //For each model, for each distribution,... optimize the model and calculate some statistics:
+
+ println("**********************************************************");
+ //this is only for doing output prettier
+ println("Observed number of invariant sites: " + ProtTestAlignment.calculateInvariableSites(options.getAlignment(), false));
+ StringWriter sw = new StringWriter();
+ ProtTestAlignment.printFrequencies(ProtTestAlignment.getFrequencies(options.getAlignment()), new PrintWriter(sw));
+ sw.flush();
+ println(sw.toString());
+ println("**********************************************************");
+ println("");
+
+ //TimeStamp timer = new TimeStamp();
+ Date startDate = new Date();
+ long startTime = startDate.getTime();
+
+ int numberOfModels = 0;
+
+ ModelCollection arrayListModel;
+ //Adding support for checkpointing
+ ProtTestStatus initialStatus = new ProtTestStatus(null, options);
+
+ cpManager = new CheckPointManager();
+ if (cpManager.loadStatus(initialStatus)) {
+ arrayListModel = new SingleModelCollection(
+ ((ProtTestStatus) cpManager.getLastCheckpoint()).getModels(),
+ options.getAlignment());
+ } else {
+ arrayListModel = new SingleModelCollection(options.getAlignment());
+ Properties modelProperties = new Properties();
+ if (options.isPlusF()) {
+ modelProperties.setProperty(Model.PROP_PLUS_F, "true");
+ }
+ arrayListModel.addModelCartesian(options.getMatrices(), options.getDistributions(), modelProperties,
+ options.getAlignment(), options.getTree(), options.ncat);
+ }
+
+ ModelWeightComparator comparator = new ModelDistributionHeuristic();
+ Collections.sort(arrayListModel, comparator);
+
+ numberOfModels = arrayListModel.size();
+ modelSet = arrayListModel;
+
+ flush();
+
+ RunEstimator[] runenv = new RunEstimator[modelSet.size()];
+ Collection<Callable<Object>> c = new ArrayList<Callable<Object>>();
+
+ int current = 0;
+ for (Model model : modelSet) {
+
+ runenv[current] = factory.createRunEstimator(options, model);
+ runenv[current].addObserver(this);
+
+ c.add(Executors.callable(runenv[current]));
+ current++;
+
+ }
+
+ boolean errorsFound = false;
+ Collection<Future<Object>> futures = null;
+ try {
+ futures = threadPool.invokeAll(c);
+ } catch (InterruptedException e) {
+ }
+ if (futures != null) {
+ for (Future<Object> f : futures) {
+ try {
+ f.get();
+ } catch (InterruptedException ex) {
+ errorsFound = true;
+ } catch (ExecutionException ex) {
+ // Internal exception while computing model.
+ // Let's continue with errors
+ errorsFound = true;
+ }
+ }
+ }
+
+ long endTime = System.currentTimeMillis();
+
+ //check all models and remove those with errors
+ for (current = 0; current < runenv.length; current++) {
+ Model model = runenv[current].getModel();
+ if (!model.isComputed()) {
+ arrayListModel.remove(model);
+ numberOfModels--;
+ warnln("There were errors computing model " + model.getModelName());
+ }
+ }
+
+ println("");
+ println("");
+
+ // print optimization reports sorted
+ Collections.sort(arrayListModel, new AminoAcidModelNaturalComparator());
+ for (Model model : arrayListModel) {
+ for (current = 0; current < runenv.length; current++) {
+ if (runenv[current].getModel().equals(model)) {
+ runenv[current].report();
+ break;
+ }
+ }
+ }
+ flush();
+
+ Model[] allModels = new Model[numberOfModels];
+
+ println("************************************************************");
+ String runtimeStr = Utilities.calculateRuntime(startTime, endTime);
+ println("Date : " + (new Date()).toString());
+ println("Runtime: " + runtimeStr);
+ println("");
+ println("");
+ allModels = arrayListModel.toArray(new Model[0]);
+
+ cpManager.done();
+ return allModels;
+ }
+
+// public ApplicationOptions configure(ProtTestParameterVO parameters)
+// throws IOException, AlignmentParseException, ProtTestInternalException {
+// ApplicationOptions.synchronize();
+//// options.setNumberOfThreads(poolSize);
+// return super.configure(parameters);
+// }
+ @Override
+ public synchronized void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+
+ if (model.isComputed() && options != null) {
+ if (cpManager != null) {
+ ProtTestStatus newStatus = new ProtTestStatus(modelSet.toArray(new Model[0]), options);
+ cpManager.setStatus(newStatus);
+ }
+ }
+
+ super.update(o, model, options);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacade.java b/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacade.java
new file mode 100755
index 0000000..cec3b29
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacade.java
@@ -0,0 +1,96 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import es.uvigo.darwin.prottest.consensus.Consensus;
+import java.util.List;
+
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+
+/**
+ * Declaration of services related to phylogenetic tree management.
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public interface TreeFacade {
+
+ // **********************************************************
+ // TREE SERVICES
+ //**********************************************************
+
+ /**
+ * Gets ASCII representation of a Tree instance.
+ *
+ * @param tree the tree
+ */
+ public String toASCII(Tree tree);
+
+ /**
+ * Gets branch information of a Tree instance.
+ *
+ * @param tree the tree
+ */
+ public String branchInfo(Tree tree);
+
+ /**
+ * Gets height information of a Tree instance.
+ *
+ * @param tree the tree
+ */
+ public String heightInfo(Tree tree);
+
+ /**
+ * Gets newick representation of a Tree instance.
+ *
+ * @param tree the tree
+ * @param printLengths if branch lengths should be included
+ * @param printInternalLabels if internal labels should be included
+ * @param printCladeSupport if clade support should be included
+ */
+ public String toNewick(Tree tree, boolean printLengths,
+ boolean printInternalLabels, boolean printCladeSupport);
+
+ /**
+ * Create a consensus tree from a list of trees.
+ *
+ * @param treeCollection the trees and its weights to build consensus
+ * @param threshold the minimum clade support
+ */
+ public Tree createConsensusTree(List<WeightedTree> treeCollection, double threshold);
+
+ /**
+ * Create a weighted consensus tree from an information criterion.
+ *
+ * @param ic the weighted models with the trees to build consensus
+ * @param threshold the minimum clade support
+ */
+ public Tree createConsensusTree(InformationCriterion ic, double threshold);
+
+ /**
+ * Create a weighted consensus instance from an information criterion.
+ *
+ * @param ic the weighted models with the trees to build consensus
+ * @param threshold the minimum clade support
+ */
+ public Consensus createConsensus(InformationCriterion ic, double threshold);
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacadeImpl.java b/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacadeImpl.java
new file mode 100755
index 0000000..f555f51
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/TreeFacadeImpl.java
@@ -0,0 +1,93 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.consensus.Consensus;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.tree.TreeUtils;
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import java.io.StringWriter;
+
+/**
+ * Generic implementation of the Tree Facade services
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class TreeFacadeImpl implements TreeFacade {
+
+ public String toASCII(Tree tree) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ TreeUtils.printASCII(tree, pw);
+ pw.flush();
+ return sw.toString();
+ }
+
+ public String branchInfo(Tree tree) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ TreeUtils.printBranchInfo(tree, pw);
+ pw.flush();
+ return sw.toString();
+ }
+
+ public String heightInfo(Tree tree) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ TreeUtils.heightInfo(tree, pw);
+ pw.flush();
+ return sw.toString();
+ }
+
+ public String toNewick(Tree tree, boolean printLengths,
+ boolean printInternalLabels, boolean printCladeSupport) {
+ return TreeUtils.toNewick(tree, printLengths, printInternalLabels, printCladeSupport);
+ }
+
+ public Tree createConsensusTree(List<WeightedTree> treeColection,
+ double threshold) {
+
+ if (threshold < 0.5 || threshold > 1.0) {
+ throw new ProtTestInternalException("Invalid threshold value: " + threshold);
+ }
+ Consensus consensus = new Consensus(treeColection, threshold, Consensus.BRANCH_LENGTHS_MEDIAN);
+ Tree cons = consensus.getConsensusTree();
+ return cons;
+ }
+
+ public Tree createConsensusTree(InformationCriterion ic, double threshold) {
+ Consensus consensus = createConsensus(ic, threshold);
+ Tree cons = consensus.getConsensusTree();
+ return cons;
+ }
+
+ public Consensus createConsensus(InformationCriterion ic, double threshold) {
+ if (threshold < 0.5 || threshold > 1.0) {
+ throw new ProtTestInternalException("Invalid threshold value: " + threshold);
+ }
+ Consensus consensus = new Consensus(ic, threshold);
+ return consensus;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/package.html b/src/main/java/es/uvigo/darwin/prottest/facade/package.html
new file mode 100755
index 0000000..7a3069e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/package.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the facade definitions and implementations. This classes contains
+all service definitions and one or more implementations. For instance, the
+main facade, <code>ProtTestFacade</code>, has three concrete implementations,
+one for each execution strategy: sequential execution, threaded execution on
+shared memory, taking advantage of a thread pool, and one more for the
+distributed memory strategy within MPJ Express.
+
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DistributionStrategy.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DistributionStrategy.java
new file mode 100755
index 0000000..4c451c1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DistributionStrategy.java
@@ -0,0 +1,147 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.checkpoint.status.ProtTestStatus;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+
+/**
+ * This class provides the strategy template for distribute the models amongst processors,
+ * the concrete classes should both distribute models and compute likelihood values.
+ */
+public abstract class DistributionStrategy extends ObservableModelUpdater implements ModelUpdaterObserver {
+
+ /** The application options instance. */
+ protected ApplicationOptions options;
+
+ /** The model set to compute. */
+ protected ModelCollection modelSet;
+
+ /** The number of models to compute. */
+ protected int numberOfModels;
+
+ /** The number of models per processor. It will be necessary
+ * by the root process to do the non-uniform gathering */
+ protected int[] itemsPerProc;
+
+ /** The array of displacements after the distribution.
+ * It will be necessary by the root process to do the non-uniform gathering */
+ protected int[] displs;
+
+ /** The ProtTest factory instance. */
+ protected ProtTestFactory factory = ProtTestFactory.getInstance();
+
+ /** MPJ Rank of the processor. */
+ protected int mpjMe;
+
+ /** MPJ Size of the communicator. */
+ protected int mpjSize;
+
+ /** The absolute start time of the main computation in milliseconds. It should be filled by
+ * the classes which extends this one
+ * @see System#currentTimeMillis()
+ * */
+ protected long startTime;
+
+ /** The absolute end time of the main computation in milliseconds. It should be filled by
+ * the classes which extends this one
+ * @see System#currentTimeMillis()
+ * */
+ protected long endTime;
+
+ private CheckPointManager cpManager;
+
+ /**
+ * Instantiates a new distribution strategy with Checkpointing support.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ * @param cpManager the checkpoint manager, it can be null if checkpointing is not supported
+ */
+ public DistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options,
+ CheckPointManager cpManager) {
+ this.options = options;
+ this.mpjMe = mpjMe;
+ this.mpjSize = mpjSize;
+ this.cpManager = cpManager;
+ }
+
+ /**
+ * Method called by the root process in order to distribute the models
+ * amongst processors.
+ *
+ * @param modelSet the models to distribute
+ * @param comparator implementation of the heuristic algorithm for sort and distribute models
+ *
+ * @return the array of models after computing likelihood
+ */
+ public abstract Model[] distribute(ModelCollection modelSet, ModelWeightComparator comparator);
+
+ /**
+ * Method called by non-root processors in order to request and compute
+ * their assigned models.
+ */
+ public abstract void request();
+
+ /**
+ * Gets the absolute start time of computing in milliseconds.
+ *
+ * @return the start time in milliseconds
+ */
+ public long getStartTime() { return startTime; }
+
+ /**
+ * Gets the absolute end time of computing in milliseconds.
+ *
+ * @return the end time in milliseconds
+ */
+ public long getEndTime() { return endTime; }
+
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+
+ notifyObservers(model, options);
+
+ }
+
+ protected void setCheckpoint(ModelCollection modelSet) {
+
+ if (mpjMe > 0)
+ throw new ProtTestInternalException("Only root process can set checkpoints");
+
+ if (cpManager != null) {
+ ProtTestStatus newStatus = new ProtTestStatus(modelSet.toArray(new Model[0]), options);
+ cpManager.setStatus(newStatus);
+ }
+ }
+
+ protected void computationDone() {
+ if (mpjMe > 0)
+ throw new ProtTestInternalException("Only root process can set checkpoints");
+
+ cpManager.done();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/Distributor.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/Distributor.java
new file mode 100755
index 0000000..5652bb3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/Distributor.java
@@ -0,0 +1,203 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import java.util.Collections;
+
+import mpi.MPI;
+import mpi.Request;
+import mpi.Status;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * This class distributes wrok load in an MPJ-Express environment.
+ * Its behavior is inherently coupled to
+ * ImprovedDynamicDistributionStrategy's, providing the root process with
+ * the possibility of distribute the models and also computing likelihood
+ * values asynchronously.
+ *
+ * @see ImprovedDynamicDistributionStrategy
+ */
+public class Distributor implements Runnable {
+
+ /** MPJ Tag for requesting a new model. */
+ private static final int TAG_SEND_REQUEST = 1;
+
+ /** MPJ Tag for sending a new model. */
+ private static final int TAG_SEND_MODEL = 2;
+
+ /** MPJ Rank of the processor. */
+ private int mpjMe;
+
+ /** MPJ Size of the communicator. */
+ private int mpjSize;
+
+ /** The improved dynamic distribution strategy who calls this instance. */
+ private ImprovedDynamicDistributionStrategy caller;
+
+ /** The collection of all models to distribute. */
+ private ModelCollection modelCollection;
+
+ /** The heuristic algorithm to compare models. */
+ private ModelWeightComparator comparator;
+
+ /** The number of models per processor. It will be necessary
+ * by the root process to do the non-uniform gathering */
+ private int[] itemsPerProc;
+
+ /** The array of displacements after the distribution.
+ * It will be necessary by the root process to do the non-uniform gathering */
+ private int[] displs;
+
+/**
+ * Gets the array of items per processor.
+ *
+ * @return the array of items per processor
+ */
+public int[] getItemsPerProc() { return itemsPerProc; }
+
+ /**
+ * Gets the array of displacements. The root process needs this attribute
+ * in order to do the non-uniform gathering.
+ *
+ * @return the array of displacements
+ */
+ public int[] getDispls() { return displs; }
+
+ /**
+ * Instantiates a new distributor. The root process needs this attribute
+ * in order to do the non-uniform gathering.
+ *
+ * @param caller the ImprovedDynamicDistributionStrategy instance which calls this constructor
+ * @param modelCollection the models to distribute amongst processors
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ */
+ public Distributor(ImprovedDynamicDistributionStrategy caller,
+ ModelCollection modelCollection, ModelWeightComparator comparator,
+ int mpjMe, int mpjSize) {
+ this.comparator = comparator;
+ this.modelCollection = modelCollection;
+ this.mpjMe = mpjMe;
+ this.mpjSize = mpjSize;
+ this.caller = caller;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+
+ distribute(modelCollection, comparator);
+
+ }
+
+ /**
+ * Distributes the whole model collection amongst the processors in
+ * the communicator. This method should be synchronized with the
+ * request method in the Improved Dynamic Distribution Strategy.
+ *
+ * @see es.uvigo.darwin.prottest.facade.strategy.ImprovedDynamicDistributionStrategy#request()
+ *
+ * @param modelSet the model collection to distribute amongst processors
+ * @param comparator implementation of the heuristic algorithm for sort and distribute models
+ */
+ private void distribute(ModelCollection modelSet, ModelWeightComparator comparator) {
+
+ itemsPerProc = new int[mpjSize];
+ displs = new int[mpjSize];
+
+ Collections.sort(modelSet, comparator);
+
+ for (Model model : modelSet) {
+ // check root processor
+ //
+ // This strategy is an easy way to avoid the problem of thread-safety
+ // in MPJ-Express. It works correctly, but it also causes to introduce
+ // coupling between this class and ImprovedDynamicDistributionStrategy,
+ // having to define two public attributes: rootModelRequest and rootModel.
+ //
+ if (caller.rootModelRequest) {
+ if (caller.rootModel != null) {
+ caller.setCheckpoint(modelSet);
+ }
+ caller.rootModel = model;
+ caller.rootModelRequest = false;
+ itemsPerProc[mpjMe]++;
+ } else {
+ Model[] computedModel = new Model[1];
+ // getModel request
+ Request modelRequest = MPI.COMM_WORLD.Irecv(computedModel, 0, 1, MPI.OBJECT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ // prepare model
+ Model[] modelToSend = new Model[1];
+ modelToSend[0] = model;
+ // wait for request
+ Status requestStatus = modelRequest.Wait();
+ if (computedModel[0] != null) {
+ // set checkpoint
+ int index = modelSet.indexOf(computedModel[0]);
+ modelSet.set(index, computedModel[0]);
+ caller.setCheckpoint(modelSet);
+ }
+ // send model
+ Request modelSend = MPI.COMM_WORLD.Isend(modelToSend, 0, 1, MPI.OBJECT, requestStatus.source, TAG_SEND_MODEL);
+ // update structures
+ itemsPerProc[requestStatus.source]++;
+ // wait for send
+ modelSend.Wait();
+ }
+ }
+ displs[0] = 0;
+ for (int i = 1; i < mpjSize; i++)
+ displs[i] = displs[i-1] + itemsPerProc[i-1];
+
+ // finalize
+ for (int i = 1; i < mpjSize; i++) {
+ Model[] computedModel = new Model[1];
+ // getModel request
+ Request modelRequest = MPI.COMM_WORLD.Irecv(computedModel, 0, 1, MPI.OBJECT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ Model[] modelToSend = { null };
+ // wait for request
+ Status requestStatus = modelRequest.Wait();
+ if (computedModel[0] != null) {
+ // set checkpoint
+ int index = modelSet.indexOf(computedModel[0]);
+ modelSet.set(index, computedModel[0]);
+ caller.setCheckpoint(modelSet);
+ }
+ // send null model
+ Request modelSend = MPI.COMM_WORLD.Isend(modelToSend, 0, 1, MPI.OBJECT, requestStatus.source, TAG_SEND_MODEL);
+
+ modelSend.Wait();
+ }
+ // check root
+ while (!caller.rootModelRequest) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+ caller.rootModel = null;
+ caller.rootModelRequest = false;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DynamicDistributionStrategy.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DynamicDistributionStrategy.java
new file mode 100755
index 0000000..1e31bbe
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/DynamicDistributionStrategy.java
@@ -0,0 +1,162 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import mpi.MPI;
+import mpi.Request;
+import mpi.Status;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * This strategy distributes the workload in a dynamic way.
+ */
+public class DynamicDistributionStrategy extends DistributionStrategy {
+
+ /** MPJ Tag for requesting a new model. */
+ private static final int TAG_SEND_REQUEST = 1;
+
+ /** MPJ Tag for sending a new model. */
+ private static final int TAG_SEND_MODEL = 2;
+
+ /**
+ * Instantiates a new dynamic distribution strategy.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ * @param cpManager the checkpoint manager, it can be null if checkpointing is not supported
+ */
+ public DynamicDistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options, CheckPointManager cpManager) {
+ super(mpjMe, mpjSize, options, cpManager);
+ if (mpjSize == 1) {
+ throw new ProtTestInternalException("Dynamic Distribution Strategy" +
+ " requires at least 2 processors");
+ }
+ itemsPerProc = new int[mpjSize];
+ displs = new int[mpjSize];
+ modelSet = new SingleModelCollection(options.getAlignment());
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#distribute(es.uvigo.darwin.prottest.util.collection.ModelCollection)
+ */
+ public Model[] distribute(ModelCollection arrayListModel, ModelWeightComparator comparator) {
+
+ numberOfModels = arrayListModel.size();
+ Collections.sort(arrayListModel, comparator);
+ for (Model model : arrayListModel) {
+ Model[] computedModel = new Model[1];
+ // getModel request
+ Request modelRequest = MPI.COMM_WORLD.Irecv(computedModel, 0, 1, MPI.OBJECT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ // prepare model
+ Model[] modelToSend = new Model[1];
+ modelToSend[0] = model;
+ // wait for request
+ Status requestStatus = modelRequest.Wait();
+ if (computedModel[0] != null) {
+ // set checkpoint
+ int index = arrayListModel.indexOf(computedModel[0]);
+ arrayListModel.set(index, computedModel[0]);
+ setCheckpoint(arrayListModel);
+ }
+ // send model
+ Request modelSend = MPI.COMM_WORLD.Isend(modelToSend, 0, 1, MPI.OBJECT, requestStatus.source, TAG_SEND_MODEL);
+ // update structures
+ itemsPerProc[requestStatus.source]++;
+ // wait for send
+ modelSend.Wait();
+ }
+ itemsPerProc[0] = modelSet.size();
+ displs[0] = 0;
+ for (int i = 1; i < mpjSize; i++)
+ displs[i] = displs[i-1] + itemsPerProc[i-1];
+
+ // finalize
+ for (int i = 1; i < mpjSize; i++) {
+ Model[] computedModel = new Model[1];
+ Request modelRequest = MPI.COMM_WORLD.Irecv(computedModel, 0, 1, MPI.OBJECT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ Model[] modelToSend = { null };
+ // wait for request
+ Status requestStatus = modelRequest.Wait();
+ if (computedModel[0] != null) {
+ // set checkpoint
+ int index = arrayListModel.indexOf(computedModel[0]);
+ arrayListModel.set(index, computedModel[0]);
+ setCheckpoint(arrayListModel);
+ }
+ // send null model
+ Request modelSend = MPI.COMM_WORLD.Isend(modelToSend, 0, 1, MPI.OBJECT, requestStatus.source, TAG_SEND_MODEL);
+
+ modelSend.Wait();
+ }
+
+ computationDone();
+ return arrayListModel.toArray(new Model[0]);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#request()
+ */
+ public void request() {
+
+ startTime = System.currentTimeMillis();
+
+ List<RunEstimator> runenvList = new ArrayList<RunEstimator>();
+
+ Model[] lastComputedModel = new Model[1];
+ while (true) {
+ // send request to root
+ Request modelRequest = MPI.COMM_WORLD.Isend(lastComputedModel, 0, 1, MPI.OBJECT, 0, TAG_SEND_REQUEST);
+ // prepare reception
+ Model[] modelToReceive = new Model[1];
+ // wait for request
+ modelRequest.Wait();
+ // receive model
+ Request modelReceive = MPI.COMM_WORLD.Irecv(modelToReceive, 0, 1, MPI.OBJECT, 0, TAG_SEND_MODEL);
+ modelReceive.Wait();
+ Model model = modelToReceive[0];
+ if (model == null)
+ break;
+ else {
+ // compute
+ modelSet.add(model);
+ RunEstimator runenv =
+ factory.createRunEstimator(options, model);
+ runenv.addObserver(this);
+
+ if(!runenv.optimizeModel())
+ throw new ProtTestInternalException("Optimization error");
+ runenvList.add(runenv);
+ lastComputedModel[0] = runenv.getModel();
+ }
+ }
+
+ endTime = System.currentTimeMillis();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/HybridDistributionStrategy.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/HybridDistributionStrategy.java
new file mode 100755
index 0000000..e28cf5d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/HybridDistributionStrategy.java
@@ -0,0 +1,230 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import es.uvigo.darwin.prottest.exe.ParallelModelEstimator;
+
+import mpi.MPI;
+import mpi.Request;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * The Class ImprovedDynamicDistributionStrategy.
+ */
+public class HybridDistributionStrategy extends DistributionStrategy {
+
+ /** The Constant TAG_SEND_REQUEST. */
+ private static final int TAG_SEND_REQUEST = 1;
+ /** MPJ Tag for sending a new model. */
+ private static final int TAG_EXIST_MORE_MODELS = 2;
+ /** The Constant TAG_SEND_MODEL. */
+ private static final int TAG_SEND_MODEL = 3;
+ private int maxPEs;
+ /** The number of available PEs. */
+ int availablePEs;
+ /** The root model request. */
+ boolean rootModelRequest;
+ /** The root model. */
+ Model rootModel;
+ private ParallelModelEstimator pme;
+ private Model[] computedModels;
+ private MultipleDistributor distributor;
+
+ /**
+ * Instantiates a new improved dynamic distribution strategy.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ * @param cpManager the checkpoint manager, it can be null if checkpointing is not supported
+ */
+ public HybridDistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options, CheckPointManager cpManager) {
+ this(mpjMe, mpjSize, options, cpManager, Runtime.getRuntime().availableProcessors());
+ }
+
+ /**
+ * Instantiates a new improved dynamic distribution strategy.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ * @param cpManager the checkpoint manager, it can be null if checkpointing is not supported
+ */
+ public HybridDistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options, CheckPointManager cpManager, int numberOfThreads) {
+ super(mpjMe, mpjSize, options, cpManager);
+ if (mpjSize == 1) {
+ throw new ProtTestInternalException("Dynamic Distribution Strategy" + " requires at least 2 processors");
+ }
+ itemsPerProc = new int[mpjSize];
+ displs = new int[mpjSize];
+ modelSet = new SingleModelCollection(options.getAlignment());
+ maxPEs = numberOfThreads;
+ availablePEs = maxPEs;
+ pme = new ParallelModelEstimator(maxPEs, options.getAlignment());
+ pme.addObserver(this);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#distribute(es.uvigo.darwin.prottest.util.collection.ModelCollection)
+ */
+ public Model[] distribute(ModelCollection arrayListModel, ModelWeightComparator comparator) {
+
+ distributor = new MultipleDistributor(this, arrayListModel, comparator, mpjMe, mpjSize);
+ Thread distributorThread = new Thread(distributor);
+ distributorThread.start();
+ numberOfModels = arrayListModel.size();
+ request();
+
+ computationDone();
+
+ return computedModels;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#request()
+ */
+ public void request() {
+
+ startTime = System.currentTimeMillis();
+
+// List<RunEstimator> runenvList = new ArrayList<RunEstimator>();
+
+ while (true) {
+ // send request to root
+ Model[] modelToReceive = null;
+ Model model = null;
+ if (mpjMe > 0) {
+ int[] sendMessage = {availablePEs};
+ Request modelRequest = MPI.COMM_WORLD.Isend(sendMessage, 0, 1, MPI.INT, 0, TAG_SEND_REQUEST);
+ // prepare reception
+ modelToReceive = new Model[1];
+ boolean[] notification = new boolean[1];
+ // wait for request
+ modelRequest.Wait();
+
+ Request notifyRecv = MPI.COMM_WORLD.Irecv(notification, 0, 1, MPI.BOOLEAN, 0, TAG_EXIST_MORE_MODELS);
+ notifyRecv.Wait();
+
+ if (notification[0]) {
+ // receive model
+ Request modelReceive = MPI.COMM_WORLD.Irecv(modelToReceive, 0, 1, MPI.OBJECT, 0, TAG_SEND_MODEL);
+ modelReceive.Wait();
+ model = modelToReceive[0];
+ } else {
+ break;
+ }
+ } else {
+ // This strategy is an easy way to avoid the problem of thread-safety
+ // in MPJ-Express. It works correctly, but it also causes to introduce
+ // coupling amongst this class and Distributor, having to define two
+ // public attributes: rootModelRequest and rootModel.
+ rootModelRequest = true;
+ while (rootModelRequest) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+ model = rootModel;
+ if (model == null) {
+ break;
+ }
+ }
+
+ if (model != null) {
+ availablePEs -= MultipleDistributor.getPEs(model, maxPEs);
+ // compute
+ modelSet.add(model);
+ RunEstimator runenv =
+ factory.createRunEstimator(options, model, MultipleDistributor.getPEs(model, maxPEs));
+// runenv.addObserver(this);
+ pme.execute(runenv);
+
+ while (availablePEs <= 0) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+ }
+ }
+
+ endTime = System.currentTimeMillis();
+
+ while (pme.hasMoreTasks()) {
+ try {
+ Thread.sleep(400);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+
+ if (mpjMe > 0) {
+ gather();
+ } else {
+ computedModels = gather();
+ }
+
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.ProtTestFacade#update(es.uvigo.darwin.prottest.observer.Observable, java.lang.Object)
+ */
+ @Override
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+ if (options != null && model.isComputed()) {
+ availablePEs += MultipleDistributor.getPEs(model, maxPEs);
+ }
+ super.update(o, model, options);
+ }
+
+ /**
+ * Gathers the models of all processors into the root one. This method should
+ * be called by every processor after computing likelihood value of whole model set.
+ *
+ * This method will return an empty array of models for every non-root processor
+ *
+ * @return the array of gathered models
+ */
+ private Model[] gather() {
+
+ Model[] allModels = new Model[numberOfModels];
+ if (distributor != null) {
+ itemsPerProc = distributor.getItemsPerProc();
+ displs = distributor.getDispls();
+ }
+
+ MPI.COMM_WORLD.Bcast(itemsPerProc, 0, mpjSize, MPI.INT, 0);
+
+ // gathering optimized models
+ MPI.COMM_WORLD.Gatherv(modelSet.toArray(new Model[0]), 0, modelSet.size(), MPI.OBJECT,
+ allModels, 0, itemsPerProc, displs, MPI.OBJECT, 0);
+
+ return allModels;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/ImprovedDynamicDistributionStrategy.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/ImprovedDynamicDistributionStrategy.java
new file mode 100755
index 0000000..2fc7ebc
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/ImprovedDynamicDistributionStrategy.java
@@ -0,0 +1,147 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mpi.MPI;
+import mpi.Request;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.checkpoint.CheckPointManager;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * This class improves the dynamic behaviour adding a distributor
+ * thread.
+ */
+public class ImprovedDynamicDistributionStrategy extends DistributionStrategy {
+
+ /** The Constant TAG_SEND_REQUEST. */
+ private static final int TAG_SEND_REQUEST = 1;
+
+ /** The Constant TAG_SEND_MODEL. */
+ private static final int TAG_SEND_MODEL = 2;
+
+ /** The root model request. */
+ boolean rootModelRequest;
+
+ /** The root model. */
+ Model rootModel;
+
+ /**
+ * Instantiates a new improved dynamic distribution strategy.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ * @param cpManager the checkpoint manager, it can be null if checkpointing is not supported
+ */
+ public ImprovedDynamicDistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options, CheckPointManager cpManager) {
+ super(mpjMe, mpjSize, options, cpManager);
+ if (mpjSize == 1) {
+ throw new ProtTestInternalException("Dynamic Distribution Strategy" +
+ " requires at least 2 processors");
+ }
+ itemsPerProc = new int[mpjSize];
+ displs = new int[mpjSize];
+ modelSet = new SingleModelCollection(options.getAlignment());
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#distribute(es.uvigo.darwin.prottest.util.collection.ModelCollection)
+ */
+ public Model[] distribute(ModelCollection arrayListModel, ModelWeightComparator comparator) {
+
+ Distributor distributor = new Distributor(this, arrayListModel, comparator, mpjMe, mpjSize);
+ Thread distributorThread = new Thread(distributor);
+ distributorThread.start();
+ numberOfModels = arrayListModel.size();
+ request();
+ itemsPerProc = distributor.getItemsPerProc();
+ displs = distributor.getDispls();
+
+ computationDone();
+ return arrayListModel.toArray(new Model[0]);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#request()
+ */
+ public void request() {
+
+ startTime = System.currentTimeMillis();
+
+ List<RunEstimator> runenvList = new ArrayList<RunEstimator>();
+
+ Model[] lastComputedModel = new Model[1];
+ while (true) {
+ // send request to root
+ Model[] modelToReceive = null;
+ Model model = null;
+ if (mpjMe > 0) {
+ Request modelRequest = MPI.COMM_WORLD.Isend(lastComputedModel, 0, 1, MPI.OBJECT, 0, TAG_SEND_REQUEST);
+ // prepare reception
+ modelToReceive = new Model[1];
+ // wait for request
+ modelRequest.Wait();
+ // receive model
+ Request modelReceive = MPI.COMM_WORLD.Irecv(modelToReceive, 0, 1, MPI.OBJECT, 0, TAG_SEND_MODEL);
+ modelReceive.Wait();
+ model = modelToReceive[0];
+ } else {
+ // This strategy is an easy way to avoid the problem of thread-safety
+ // in MPJ-Express. It works correctly, but it also causes to introduce
+ // coupling amongst this class and Distributor, having to define two
+ // public attributes: rootModelRequest and rootModel.
+ rootModelRequest = true;
+ while (rootModelRequest) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+ model = rootModel;
+ }
+ if (model == null)
+ break;
+ else {
+ // compute
+ modelSet.add(model);
+ RunEstimator runenv =
+ factory.createRunEstimator(options, model);
+ runenv.addObserver(this);
+
+ if(!runenv.optimizeModel())
+ throw new ProtTestInternalException("Optimization error");
+
+ runenvList.add(runenv);
+ lastComputedModel[0] = runenv.getModel();
+ }
+ }
+
+ endTime = System.currentTimeMillis();
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/MultipleDistributor.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/MultipleDistributor.java
new file mode 100755
index 0000000..c2d65a1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/MultipleDistributor.java
@@ -0,0 +1,246 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import java.util.Collections;
+
+import mpi.MPI;
+import mpi.Request;
+import mpi.Status;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * This class depends on MPJ-Express. Its behavior is inherently coupled to
+ * ImprovedDynamicDistributionStrategy's, providing the root process with
+ * the possibility of distribute the models and also computing likelihood
+ * values asynchronously.
+ *
+ * @see ImprovedDynamicDistributionStrategy
+ */
+public class MultipleDistributor implements Runnable {
+
+ /** MPJ Tag for requesting a new model. */
+ private static final int TAG_SEND_REQUEST = 1;
+ /** MPJ Tag for sending a new model. */
+ private static final int TAG_EXIST_MORE_MODELS = 2;
+ /** MPJ Tag for sending a new model. */
+ private static final int TAG_SEND_MODEL = 3;
+ /** MPJ Rank of the processor. */
+ private int mpjMe;
+ /** MPJ Size of the communicator. */
+ private int mpjSize;
+ /** The improved dynamic distribution strategy who calls this instance. */
+ private HybridDistributionStrategy caller;
+ /** The collection of all models to distribute. */
+ private ModelCollection modelsToSend;
+ /** The heuristic algorithm to compare models. */
+ private ModelWeightComparator comparator;
+ /** The number of models per processor. It will be necessary
+ * by the root process to do the non-uniform gathering */
+ private int[] itemsPerProc;
+ /** The array of displacements after the distribution.
+ * It will be necessary by the root process to do the non-uniform gathering */
+ private int[] displs;
+
+ //For now, we use a static number of available threads
+ //TODO: Make this dynamically filled for each node
+ private int maxAvailableThreads = 8;
+
+ /**
+ * Gets the array of items per processor.
+ *
+ * @return the array of items per processor
+ */
+ public int[] getItemsPerProc() {
+ return itemsPerProc;
+ }
+
+ /**
+ * Gets the array of displacements. The root process needs this attribute
+ * in order to do the non-uniform gathering.
+ *
+ * @return the array of displacements
+ */
+ public int[] getDispls() {
+ return displs;
+ }
+
+ /**
+ * Instantiates a new distributor. The root process needs this attribute
+ * in order to do the non-uniform gathering.
+ *
+ * @param caller the ImprovedDynamicDistributionStrategy instance which calls this constructor
+ * @param modelCollection the models to distribute amongst processors
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ */
+ public MultipleDistributor(HybridDistributionStrategy caller,
+ ModelCollection modelCollection, ModelWeightComparator comparator,
+ int mpjMe, int mpjSize) {
+ this.comparator = comparator;
+ this.modelsToSend = modelCollection.clone();
+ Collections.sort(this.modelsToSend, comparator);
+ this.mpjMe = mpjMe;
+ this.mpjSize = mpjSize;
+ this.caller = caller;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Runnable#run()
+ */
+ public void run() {
+
+ distribute();
+
+ }
+
+ /**
+ * Distributes the whole model collection amongst the processors in
+ * the communicator. This method should be synchronized with the
+ * request method in the Improved Dynamic Distribution Strategy.
+ *
+ * @see es.uvigo.darwin.prottest.facade.strategy.ImprovedDynamicDistributionStrategy#request()
+ *
+ * @param modelSet the model collection to distribute amongst processors
+ * @param comparator implementation of the heuristic algorithm for sort and distribute models
+ */
+ private void distribute() {
+
+ itemsPerProc = new int[mpjSize];
+ Status requestStatus = null;
+ displs = new int[mpjSize];
+ int[] freePEs = new int[1];
+ boolean sended = true;
+
+ Request modelRequest = null;
+ while (!modelsToSend.isEmpty()) {
+ // check root processor
+ //
+ // This strategy is an easy way to avoid the problem of thread-safety
+ // in MPJ-Express. It works correctly, but it also causes to introduce
+ // coupling between this class and ImprovedDynamicDistributionStrategy,
+ // having to define two public attributes: rootModelRequest and rootModel.
+ //
+ if (caller.rootModelRequest && caller.availablePEs > 0) {
+// if (caller.rootModel != null) {
+// caller.setCheckpoint(modelSet);
+// }
+ Model rootModel = getNextModel(caller.availablePEs);
+ if (rootModel != null) {
+ caller.rootModel = rootModel;
+ caller.rootModelRequest = false;
+ itemsPerProc[mpjMe]++;
+ }
+ } else {
+ // getModel request
+ if (sended) {
+ modelRequest = MPI.COMM_WORLD.Irecv(freePEs, 0, 1, MPI.INT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ // wait for request
+ sended = false;
+ }
+ requestStatus = modelRequest.Test();
+ if (requestStatus != null) {
+
+ Request notifySend = MPI.COMM_WORLD.Isend(new boolean[]{true}, 0, 1, MPI.BOOLEAN, requestStatus.source, TAG_EXIST_MORE_MODELS);
+
+ // prepare model
+ Model[] modelToSend = new Model[1];
+
+ notifySend.Wait();
+
+ modelToSend[0] = getNextModel(freePEs[0]);
+ Request modelSend = MPI.COMM_WORLD.Isend(modelToSend, 0, 1, MPI.OBJECT, requestStatus.source, TAG_SEND_MODEL);
+
+ if (modelToSend[0] != null) {
+ // update structures
+ itemsPerProc[requestStatus.source]++;
+ }
+
+ // wait for send
+ modelSend.Wait();
+ sended = true;
+
+ requestStatus = null;
+
+ }
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+
+ }
+ }
+
+ displs[0] = 0;
+ for (int i = 1; i < mpjSize; i++) {
+ displs[i] = displs[i - 1] + itemsPerProc[i - 1];
+ }
+
+ // finalize
+ // check root
+ while (!caller.rootModelRequest) {
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new ProtTestInternalException("Thread interrupted");
+ }
+ }
+ caller.rootModel = null;
+ caller.rootModelRequest = false;
+
+ for (int i = 1; i < mpjSize; i++) {
+ // getModel request
+ modelRequest = MPI.COMM_WORLD.Irecv(freePEs, 0, 1, MPI.INT, MPI.ANY_SOURCE, TAG_SEND_REQUEST);
+ // wait for request
+ requestStatus = modelRequest.Wait();
+ // send null model
+ Request notifySend = MPI.COMM_WORLD.Isend(new boolean[]{false}, 0, 1, MPI.BOOLEAN, requestStatus.source, TAG_EXIST_MORE_MODELS);
+ notifySend.Wait();
+
+ }
+
+ }
+
+ private Model getNextModel(int numPEs) {
+ Model nextModel = null;
+ for (Model model : modelsToSend) {
+ if (getPEs(model, maxAvailableThreads) <= numPEs) {
+ nextModel = model;
+ break;
+ }
+ }
+ modelsToSend.remove(nextModel);
+ return nextModel;
+ }
+
+ public static int getPEs(Model model, int maxAvailableThreads) {
+ int numberOfThreads;
+ if (model.isGamma()) {
+ numberOfThreads = 4;
+ } else if (model.isInv()) {
+ numberOfThreads = 2;
+ } else {
+ numberOfThreads = 1;
+ }
+ return Math.min(maxAvailableThreads, numberOfThreads);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/StaticDistributionStrategy.java b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/StaticDistributionStrategy.java
new file mode 100755
index 0000000..bfc6891
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/StaticDistributionStrategy.java
@@ -0,0 +1,145 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.strategy;
+
+import mpi.MPI;
+import mpi.Request;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.ParallelModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * This distribution strategy makes an static distribution of the models amongst the
+ * processors. This mean the model distribution it is completely and heuristically done
+ * before computing any likelihood value.
+ */
+public class StaticDistributionStrategy extends DistributionStrategy {
+
+ /**
+ * Instantiates a new static distribution strategy.
+ *
+ * @param mpjMe the rank of the current process in MPJ
+ * @param mpjSize the size of the MPJ communicator
+ * @param options the application options
+ */
+ public StaticDistributionStrategy(int mpjMe, int mpjSize, ApplicationOptions options) {
+ super(mpjMe, mpjSize, options, null);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#distribute(es.uvigo.darwin.prottest.util.collection.ModelCollection)
+ */
+ public Model[] distribute(ModelCollection arrayListModel, ModelWeightComparator comparator) {
+
+ itemsPerProc = new int[mpjSize];
+ displs = new int [mpjSize];
+ numberOfModels = arrayListModel.size();
+
+ ParallelModelCollection pmi = new ParallelModelCollection(arrayListModel, mpjSize, comparator);
+ Request[] requests = new Request[mpjSize - 1];
+ for (int procToSend = 1; procToSend < mpjSize; procToSend++) {
+ ModelCollection[] modelsToSend = new SingleModelCollection[1];
+ modelsToSend[0] = pmi.getModelCollection(procToSend);
+ itemsPerProc[procToSend] = modelsToSend[0].size();
+ requests[procToSend - 1] = MPI.COMM_WORLD.Isend(modelsToSend, 0, 1, MPI.OBJECT, procToSend, 2);
+ }
+ modelSet = pmi.getModelCollection(mpjMe);
+ itemsPerProc[0] = modelSet.size();
+ displs[0] = 0;
+ for (int i = 1; i < mpjSize; i++)
+ displs[i] = displs[i-1] + itemsPerProc[i-1];
+
+ Request.Waitall(requests);
+
+ startTime = System.currentTimeMillis();
+ Model[] models = compute(modelSet);
+ endTime = System.currentTimeMillis();
+
+ return models;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.facade.strategy.DistributionStrategy#request()
+ */
+ public void request() {
+
+ startTime = System.currentTimeMillis();
+
+ ModelCollection[] modelsToReceive = new SingleModelCollection[1];
+ Request request = MPI.COMM_WORLD.Irecv(modelsToReceive, 0, 1, MPI.OBJECT, 0, 2);
+ request.Wait();
+ modelSet = modelsToReceive[0];
+
+ compute(modelSet);
+
+ endTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Computes the likelihood value of the model set.
+ *
+ * @param modelSet the model set to compute
+ *
+ * @return the array of models after computing likelihood
+ */
+ private Model[] compute(ModelCollection modelSet) {
+ RunEstimator[] runenv = new RunEstimator[modelSet.size()];
+
+ int current = 0;
+ for (Model model : modelSet) {
+
+ runenv[current]
+ = factory.createRunEstimator(options, model);
+ runenv[current].addObserver(this);
+
+ if(!runenv[current].optimizeModel())
+ throw new ProtTestInternalException("Optimization error");
+
+ current++;
+ }
+
+ return gather();
+ }
+
+ /**
+ * Gathers the models of all processors into the root one. This method should
+ * be called by every processor after computing likelihood value of whole model set.
+ *
+ * This method will return an empty array of models for every non-root processor
+ *
+ * @return the array of gathered models
+ */
+ private Model[] gather() {
+
+ Model[] allModels = new Model[numberOfModels];
+
+ // gathering optimized models
+ if (mpjSize > 1)
+ MPI.COMM_WORLD.Gatherv(modelSet.toArray(new Model[0]), 0, modelSet.size(), MPI.OBJECT,
+ allModels, 0, itemsPerProc, displs, MPI.OBJECT, 0);
+ else
+ allModels = modelSet.toArray(new Model[0]);
+
+ return allModels;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/strategy/package.html b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/package.html
new file mode 100755
index 0000000..dd78207
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/strategy/package.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the different strategies for distribution and execution. The MPJ Express facade
+implements an strategy pattern for model distribution among processes. All the classes
+needed by the several strategies are below this package.
+
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/thread/ThreadPoolSynchronizer.java b/src/main/java/es/uvigo/darwin/prottest/facade/thread/ThreadPoolSynchronizer.java
new file mode 100755
index 0000000..a7fad4f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/thread/ThreadPoolSynchronizer.java
@@ -0,0 +1,104 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.thread;
+
+import java.util.Hashtable;
+
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * Synchronization of all threads in a thread pool. This class
+ * maps every thread to an internal unique thread identifier, which
+ * can be used to manage temporary files. This manager is a singleton
+ * class.
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class ThreadPoolSynchronizer {
+
+ /** Internal mapping of threads ids with sequential identifiers */
+ private Hashtable<Long, Integer> threadIds;
+ /** The value of the next thread in the pool */
+ private int nextValue;
+ /** The size of the thread pool */
+ private int poolSize;
+ /** The unique instance of the class */
+ private static ThreadPoolSynchronizer instance;
+
+ /**
+ * Instantiates the synchronizer
+ *
+ * @param poolSize the size of the thread pool
+ */
+ private ThreadPoolSynchronizer(int poolSize) {
+ this.poolSize = poolSize;
+ threadIds = new Hashtable<Long, Integer>(poolSize);
+ nextValue = 0;
+ }
+
+ /**
+ * Gets the internal identifier of a thread
+ *
+ * @param thread the thread
+ *
+ * @return the unique internal identifier
+ */
+ public synchronized int getThreadId(Thread thread) {
+ long threadNumber = thread.getId();
+ Integer value = threadIds.get(threadNumber);
+
+ if (value == null) {
+ if (nextValue >= poolSize) {
+ throw new ProtTestInternalException("Thread out of sync on ThreadPool");
+ }
+ // next value
+ value = nextValue++;
+ threadIds.put(threadNumber, value);
+ }
+
+ return value;
+ }
+
+ /**
+ * Synchronizes a new manager. This method instantiates the unique
+ * instance of the class.
+ *
+ * @param poolSize the size of the thread pool
+ */
+ public static void synchronize(int poolSize) {
+ instance = new ThreadPoolSynchronizer(poolSize);
+ }
+
+ /**
+ * Gets the unique instance of the class. Before the first call of
+ * this method, the class thread pool shoud be synchronized.
+ *
+ * @return the unique instance
+ *
+ * @throws ProtTestInternalException Signals that the thread pool is not synchronized.
+ */
+ public synchronized static ThreadPoolSynchronizer getInstance()
+ throws ProtTestInternalException {
+ if (instance == null) {
+ throw new ProtTestInternalException("ThreadPool out of sync");
+ }
+ return instance;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/thread/package.html b/src/main/java/es/uvigo/darwin/prottest/facade/thread/package.html
new file mode 100755
index 0000000..d5f305d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/thread/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the threaded execution utils.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/util/ProtTestParameterVO.java b/src/main/java/es/uvigo/darwin/prottest/facade/util/ProtTestParameterVO.java
new file mode 100755
index 0000000..1f1bcc4
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/util/ProtTestParameterVO.java
@@ -0,0 +1,144 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.util;
+
+import java.util.Collection;
+import pal.alignment.Alignment;
+
+/**
+ * A value object containing all parameters of a ProtTest-HPC execution.
+ *
+ * @author Diego Darriba López
+ *
+ * @since 3.0
+ */
+public class ProtTestParameterVO {
+
+ /** The alignment */
+ private Alignment alignment;
+ /** The path of the file which contains the alignment */
+ private String alignmentFilePath;
+ /** The path of the file which contains the starting topology, if exists */
+ private String treeFilePath;
+ /** The matrices of the models to optimize. */
+ private Collection<String> matrices;
+ /** The distributions of the models to optimize. */
+ private Collection<String> distributions;
+ /** The number of transition categories. It is only useful if the distribution is gamma */
+ public int ncat;
+ /** Boolean value to consider or not the empirical amino-acid frequencies. */
+ private boolean plusF;
+ /** The starting topology strategy mode */
+ private int strategyMode;
+
+ /**
+ * Gets the path of the alignment file.
+ *
+ * @return the path of the alignment file
+ */
+ public String getAlignmentFilePath() {
+ return alignmentFilePath;
+ }
+
+ /**
+ * Gets the alignment.
+ *
+ * @return the alignment
+ */
+ public Alignment getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Gets the path of the starting user topology file, if it exists.
+ *
+ * @return the path of the starting user topology file
+ */
+ public String getTreeFilePath() {
+ return treeFilePath;
+ }
+
+ /**
+ * Gets the set of substitution matrix names.
+ *
+ * @return a collection of the substitution matrix names
+ */
+ public Collection<String> getMatrices() {
+ return matrices;
+ }
+
+ /**
+ * Gets the set of distributions in consideration.
+ *
+ * @return a collection of the distribution manes.
+ */
+ public Collection<String> getDistributions() {
+ return distributions;
+ }
+
+ /**
+ * Gets the number of rate categories, if the distribution +G is considered.
+ *
+ * @return the number of rate categories
+ */
+ public int getNcat() {
+ return ncat;
+ }
+
+ /**
+ * Gets the state of the empirical frequencies consideration.
+ *
+ * @return true, if empirical frequencies are considered
+ */
+ public boolean isPlusF() {
+ return plusF;
+ }
+
+ /**
+ * Gets the starting topology strategy mode.
+ * @return the starting topology strategy mode
+ */
+ public int getStrategyMode() {
+ return strategyMode;
+ }
+
+ /**
+ * Instantiates a new ProtTestParameterVO.
+ *
+ * @param alignmentFilePath the path of the file which contains the alignment
+ * @param alignment the alignment
+ * @param treeFilePath the path of the file which contains the starting topology, if exists
+ * @param matrices the matrices of the models to optimize
+ * @param distributions the distributions of the models to optimize
+ * @param plusF boolean value to consider or not the empirical amino-acid frequencies
+ * @param ncat the number of transition categories. It is only useful if the distribution is gamma
+ * @param strategyMode the starting topology strategy mode
+ */
+ public ProtTestParameterVO(String alignmentFilePath, Alignment alignment, String treeFilePath,
+ Collection<String> matrices, Collection<String> distributions, boolean plusF,
+ int ncat, int strategyMode) {
+ this.alignmentFilePath = alignmentFilePath;
+ this.alignment = alignment;
+ this.treeFilePath = treeFilePath;
+ this.matrices = matrices;
+ this.distributions = distributions;
+ this.plusF = plusF;
+ this.ncat = ncat;
+ this.strategyMode = strategyMode;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/util/SelectionChunk.java b/src/main/java/es/uvigo/darwin/prottest/facade/util/SelectionChunk.java
new file mode 100755
index 0000000..a96229f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/util/SelectionChunk.java
@@ -0,0 +1,210 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.facade.util;
+
+import java.util.Collection;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+
+/**
+ * A value object to calculate information criteria. It works as
+ * a wrapper for the information criteria class.
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class SelectionChunk {
+
+ /**
+ * Akaike Information Criteiron constant.
+ */
+ public static final int AIC = 1;
+ /**
+ * Bayesian Information Criteiron constant.
+ */
+ public static final int BIC = 2;
+ /**
+ * Corrected Akaike Information Criteiron constant.
+ */
+ public static final int AICC = 3;
+ /**
+ * Decision Theory Criteiron constant.
+ */
+ public static final int DT = 4;
+ /**
+ * log Likelihood Criterion constant.
+ */
+ public static final int LNL = 5;
+ /**
+ * The inner information criterion
+ */
+ private InformationCriterion informationCriterion;
+
+ /**
+ * Gets the inner information criterion
+ *
+ * @return the information criterion
+ */
+ public InformationCriterion getInformationCriterion() {
+ return informationCriterion;
+ }
+
+ /**
+ * Instantiates a new Selection Chunk.
+ *
+ * @param informationCriterion the inner information criterion
+ */
+ public SelectionChunk(InformationCriterion informationCriterion) {
+ this.informationCriterion = informationCriterion;
+ }
+
+ public boolean existGammaModels() {
+ return informationCriterion.isExistGammaModels();
+ }
+
+ public boolean existInvModels() {
+ return informationCriterion.isExistInvModels();
+ }
+
+ public boolean existGammaInvModels() {
+ return informationCriterion.isExistGammaInvModels();
+ }
+
+ public boolean existFModels() {
+ return informationCriterion.isExistFModels();
+ }
+
+ /**
+ * Gets the criterion value of a specific substitution model.
+ *
+ * @param model the substitution model
+ *
+ * @return the criterion value
+ */
+ public double getValue(Model model) {
+ return informationCriterion.get(model).getValue();
+ }
+
+ /**
+ * Gets the incremental criterion value of a specific substitution model.
+ *
+ * @param model the substitution model
+ *
+ * @return the incremental criterion value
+ */
+ public double getDeltaValue(Model model) {
+ return informationCriterion.get(model).getDeltaValue();
+ }
+
+ /**
+ * Gets the relative weight of a specific substitution model.
+ *
+ * @param model the substitution model
+ *
+ * @return the relative weight
+ */
+ public double getWeightValue(Model model) {
+ return informationCriterion.get(model).getWeightValue();
+ }
+
+ /**
+ * Gets the overall importance of the alpha parameter.
+ *
+ * @return the overall importance of the +G models.
+ */
+ public double getOverallAlpha() {
+ return informationCriterion.getOverallAlpha();
+ }
+
+ /**
+ * Gets the overall importance of the alpha parameter on +I+G models..
+ *
+ * @return the overall importance.
+ */
+ public double getOverallAlphaInv() {
+ return informationCriterion.getOverallAlphaInv();
+ }
+
+ /**
+ * Gets the overall importance of the proportion of invariant sites
+ * parameter.
+ *
+ * @return the overall importance of the +I models.
+ */
+ public double getOverallInv() {
+ return informationCriterion.getOverallInv();
+ }
+
+ /**
+ * Gets the overall importance of the proportion of invariant sites
+ * parameter on +I+G models.
+ *
+ * @return the overall importance
+ */
+ public double getOverallInvAlpha() {
+ return informationCriterion.getOverallInvAlpha();
+ }
+
+ /**
+ * Gets the relative importance of +G parameter.
+ *
+ * @return the relative importance
+ */
+ public double getAlphaImportance() {
+ return informationCriterion.getAlphaImportance();
+ }
+
+ /**
+ * Gets the relative importance of +I parameter.
+ *
+ * @return the relative importance
+ */
+ public double getInvImportance() {
+ return informationCriterion.getInvImportance();
+ }
+
+ /**
+ * Gets the relative importance of +I+G parameter.
+ *
+ * @return the relative importance
+ */
+ public double getAlphaInvImportance() {
+ return informationCriterion.getAlphaInvImportance();
+ }
+
+ /**
+ * Gets the relative importance of empirical frequencies parameter.
+ *
+ * @return the relative importance
+ */
+ public double getFImportance() {
+ return informationCriterion.getFImportance();
+ }
+
+ /**
+ * Gets the models which belong to the confidence interval.
+ *
+ * @return the models in the confidence interval.
+ */
+ public Collection<SelectionModel> getConfidenceModels() {
+ return informationCriterion.getConfidenceModels();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/facade/util/package.html b/src/main/java/es/uvigo/darwin/prottest/facade/util/package.html
new file mode 100755
index 0000000..2d7414e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/facade/util/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains some utilies for the facades.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/AminoAcidApplicationGlobals.java b/src/main/java/es/uvigo/darwin/prottest/global/AminoAcidApplicationGlobals.java
new file mode 100755
index 0000000..c81806e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/AminoAcidApplicationGlobals.java
@@ -0,0 +1,63 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The global application settings and parameter names for
+ * amino-acid alignment sequences.
+ */
+public class AminoAcidApplicationGlobals extends ApplicationGlobals {
+
+ /** The Amino-Acid supported matrices. */
+ public static String[] ALL_MATRICES = {
+ "JTT",
+ "LG",
+ "DCMut",
+ "MtREV",
+ "MtMam",
+ "MtArt",
+ "Dayhoff",
+ "WAG",
+ "RtREV",
+ "CpREV",
+ "Blosum62",
+ "VT",
+ "HIVb",
+ "HIVw",
+ "FLU"
+ };
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.global.ApplicationGlobals#getSupportedMatrices()
+ */
+ @Override
+ public List<String> getSupportedMatrices() {
+ return Arrays.asList(ALL_MATRICES);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.global.ApplicationGlobals#getModelName(java.lang.String, int)
+ */
+ @Override
+ public String getModelName(String matrix, int frequenciesDistribution) {
+ return matrix;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/ApplicationGlobals.java b/src/main/java/es/uvigo/darwin/prottest/global/ApplicationGlobals.java
new file mode 100755
index 0000000..7e0d5ec
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/ApplicationGlobals.java
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.List;
+import java.util.Properties;
+
+import es.uvigo.darwin.prottest.ProtTest;
+
+/**
+ * The global application settings and parameter names.
+ */
+public abstract class ApplicationGlobals implements ProtTestConstants {
+
+ /** The application APPLICATION_PROPERTIES. */
+ public static final Properties APPLICATION_PROPERTIES;
+ public static final String JAR_PATH = ProtTest.class.getProtectionDomain().getCodeSource().getLocation().getFile()
+ .replace("%20", " ");
+ public static final String PATH = JAR_PATH.replaceFirst(new File(JAR_PATH).getName(),"");
+
+ static {
+ APPLICATION_PROPERTIES = new Properties();
+ try {
+ FileInputStream prop = new FileInputStream(PATH + "prottest.properties");
+ APPLICATION_PROPERTIES.load(prop);
+ } catch (IOException e) {
+ System.err.println("Properties file (prottest.properties) cannot be resolved");
+ System.exit(EXIT_NO_PROPERTIES);
+ }
+
+ }
+ public static final String DEFAULT_SNAPSHOT_DIR = "snapshot/";
+
+ /**
+ * Gets the supported matrices.
+ *
+ * @return the supported matrices
+ */
+ public abstract List<String> getSupportedMatrices();
+
+ /**
+ * Gets the model name from matrix and distribution names. This
+ * method is useful specially when a custom matrix is set, so
+ * his internal name is not representative for the user.
+ *
+ * @param matrix the matrix name
+ * @param frequenciesDistribution the frequencies distribution name
+ *
+ * @return the model name
+ */
+ public abstract String getModelName(String matrix, int frequenciesDistribution);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConsoleParameters.java b/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConsoleParameters.java
new file mode 100755
index 0000000..16c2024
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConsoleParameters.java
@@ -0,0 +1,74 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global;
+
+/**
+ * Console execution parameters
+ *
+ * @author diego
+ */
+public interface ProtTestConsoleParameters {
+
+ /** Data type parameter token. */
+ public static final String PARAM_DATA_TYPE = "d"; // data type
+ /** Nucleotide data type parameter value. */
+ public static final String DATA_TYPE_NUCLEOTIDE = "nt";
+ /** Amino-acid data type parameter value. */
+ public static final String DATA_TYPE_AMINOACID = "aa"; // default
+ /** Number of threads parameter token. */
+ public static final String PARAM_NUM_THREADS = "threads";
+ /** Alignment file parameter token. */
+ public static final String PARAM_ALIGNMENT_FILE = "i"; // alignment file (required)
+ /** Output file parameter token. */
+ public static final String PARAM_OUTPUT_FILE = "o"; // output file
+ /** Tree file parameter token. */
+ public static final String PARAM_TREE_FILE = "t"; // tree file
+ /** Sort by parameter token. */
+ public static final String PARAM_DO_AIC = "AIC"; // sort models by AIC
+ public static final String PARAM_DO_BIC = "BIC"; // sort models by BIC
+ public static final String PARAM_DO_AICC = "AICC"; // sort models by AICc
+ public static final String PARAM_DO_DT = "DT"; // sort models by DT
+ /** Display all framework comparison parameter token. */
+ public static final String PARAM_ALL_FRAMEWORK_COMPARISON = "all"; // display 7-framework comparison table
+ /** Optimization strategy selection parameter token. */
+ public static final String PARAM_TREE_SEARCH_OP = "s"; // tree search operation
+ /** Optimization strategy selection parameter token. */
+ public static final String PARAM_OPTIMIZATION_STRATEGY = "S"; // optimization strategy
+ /** Display Newick tree parameter token. */
+ public static final String PARAM_DISPLAY_NEWICK_TREE = "t1"; // display newick tree
+ /** Display ASCII tree parameter token. */
+ public static final String PARAM_DISPLAY_ASCII_TREE = "t2"; // display ASCII tree
+ /** Display Consensus tree parameter token. */
+ public static final String PARAM_DISPLAY_CONSENSUS_TREE = "tc"; // display Consensus tree
+ /** Include models with observed frequencies parameter token. */
+ public static final String PARAM_PLUSF = "F";
+ /** Include models with a proportion invariable sites parameter token. */
+ public static final String PARAM_PLUSI = "I";
+ /** Include models with rate variation among sites and number of categories parameter token. */
+ public static final String PARAM_PLUSG = "G";
+ /** Include models with a proportion of invariable sites and rate variation parameter token. */
+ public static final String PARAM_PLUSIG = "IG";
+ /** User defined number of categories parameter token. */
+ public static final String PARAM_NCAT = "ncat";
+ /** Include models with all distributions (like -I -G). */
+ public static final String PARAM_ALL_DISTRIBUTIONS = "all-distributions";
+ /** Enable or Disable output logging files. */
+ public static final String PARAM_LOGGING = "log";
+ /** Verbose mode parameter token. */
+ public static final String PARAM_VERBOSE = "verbose";
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConstants.java b/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConstants.java
new file mode 100755
index 0000000..f331539
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/ProtTestConstants.java
@@ -0,0 +1,111 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global;
+
+/**
+ * The global constants of ProtTest-HPC
+ *
+ * @author diego
+ */
+public interface ProtTestConstants {
+
+ /** The exit status for signals caused by the non existence of properties file. */
+ static final int EXIT_NO_PROPERTIES = 101;
+ // third-party applications
+ /** The Constant ANALYZER_PHYML. It is used to check the analyzer in the properties file */
+ static final String ANALYZER_PHYML = "phyml";
+ /** The Constant ANALYZER_RAXML. It is used to check the analyzer in the properties file */
+ static final String ANALYZER_RAXML = "raxml";
+ /** The number of states for amino-acids. */
+ static final int AMINOACID_NUM_STATES = 20;
+
+ /** The empirical frequencies parameter. */
+ static final String PARAMETER_F = "+F";
+ /** The invariant sites parameter. */
+ static final String PARAMETER_I = "+I";
+ /** The gamma distribution parameter. */
+ static final String PARAMETER_G = "+G";
+ /** The invariant sites and gamma distribution parameter. */
+ static final String PARAMETER_IG = "+I+G";
+
+ // tree search operation
+ /** NNI moves */
+ static final String TREE_SEARCH_NNI = "nni";
+ /** SPR moves */
+ static final String TREE_SEARCH_SPR = "spr";
+ /** Best of NNI and SPR moves */
+ static final String TREE_SEARCH_BEST = "best";
+
+ /** Fixed BIONJ topology for every model. */
+ static final int OPTIMIZE_FIXED_BIONJ = 0;
+ /** BIONJ topology for each model. */
+ static final int OPTIMIZE_BIONJ = 1;
+ /** Maximum likelighood topology for each model. */
+ static final int OPTIMIZE_ML = 2;
+ /** User defined topology. */
+ static final int OPTIMIZE_USER = 3;
+ /** Set of descriptions of the optimization strategies. */
+ public static final String[] OPTIMIZE_NAMES = {
+ "Fixed BIONJ JTT",
+ "BIONJ Tree",
+ "Maximum Likelihood tree",
+ "User defined topology"
+ };
+ /** Set of values of the optimization strategies. */
+ static final int[] OPTIMIZE_VALUES = {
+ OPTIMIZE_FIXED_BIONJ,
+ OPTIMIZE_BIONJ,
+ OPTIMIZE_ML,
+ OPTIMIZE_USER
+ };
+ static final String[] CRITERION_NAMES = {
+ "AKAIKE INFORMATION CRITERION",
+ "BAYESIAN INFORMATION CRITERION",
+ "CORRECTED AKAIKE INFORMATION CRITERION",
+ "DECISION THEORY CRITERION",
+ "LOG-LIKELIHOOD"
+ };
+ // default settings
+ /** The default setting of property "Display Newick tree". */
+ static final boolean DEFAULT_DISPLAY_NEWICK_TREE = false;
+ /** The default setting of property "Number of threads". */
+ static final int DEFAULT_THREADS = 1;
+ /** The default setting of property "Display ASCII tree". */
+ static final boolean DEFAULT_DISPLAY_ASCII_TREE = false;
+ /** The default setting of property "Display Consensus tree". */
+ static final boolean DEFAULT_DISPLAY_CONSENSUS_TREE = false;
+ /** The default setting of property "Debug" (Verbose mode). */
+ static final boolean DEFAULT_DEBUG = false;
+ /** The default setting of property "Display a 7-framework comparison". */
+ static final boolean DEFAULT_COMPARE_ALL = false;
+ /** The default setting of property "Compute all matrices". */
+ static final boolean DEFAULT_MATRICES = false;
+ /** The default setting of property "Compute all distributions". */
+ static final boolean DEFAULT_DISTRIBUTIONS = false;
+ /** The default setting of property "Number of categories". */
+ static final int DEFAULT_NCAT = 4;
+ /** The default setting of property "Optimization strategy mode". */
+ static final int DEFAULT_STRATEGY_MODE = OPTIMIZE_FIXED_BIONJ;
+
+ // Tree properties
+ /** Tree property for write branch length averaging */
+ static final String PROP_BRANCH_LENGTH_AVERAGING = "branch_length_averaging";
+
+ static final int IMPORTANCE_PRECISSION = 3;
+ static final int CRITERION_PRECISSION = 5;
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/RaxmlAminoAcidApplicationGlobals.java b/src/main/java/es/uvigo/darwin/prottest/global/RaxmlAminoAcidApplicationGlobals.java
new file mode 100755
index 0000000..d6afe81
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/RaxmlAminoAcidApplicationGlobals.java
@@ -0,0 +1,52 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The global application settings and parameter names for
+ * amino-acid alignment sequences using RAxML.
+ */
+public class RaxmlAminoAcidApplicationGlobals extends
+ AminoAcidApplicationGlobals {
+
+ /** The Amino-Acid substitution matrices supported by RAxML. */
+ public static final String[] RAXML_MATRICES = {
+ "JTT",
+ "DCMut",
+ "MtREV",
+ "MtMam",
+ "Dayhoff",
+ "WAG",
+ "RtREV",
+ "CpREV",
+ "Blosum62",
+ "VT",
+ "FLU"
+ };
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.global.ApplicationGlobals#getSupportedMatrices()
+ */
+ @Override
+ public List<String> getSupportedMatrices() {
+ return Arrays.asList(RAXML_MATRICES);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/options/ApplicationOptions.java b/src/main/java/es/uvigo/darwin/prottest/global/options/ApplicationOptions.java
new file mode 100755
index 0000000..b784f76
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/options/ApplicationOptions.java
@@ -0,0 +1,841 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global.options;
+
+import static es.uvigo.darwin.prottest.global.AminoAcidApplicationGlobals.*;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser;
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+import es.uvigo.darwin.prottest.util.fileio.AlignmentReader;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Level;
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.*;
+
+/**
+ * The ProtTest application options models the common global options for the
+ * application execution. It is a singleton class which gathers all
+ * necessary options to run.
+ */
+public class ApplicationOptions {
+
+ /** Verbose mode on/off. */
+ protected boolean debug = DEFAULT_DEBUG;
+ /** The sample size. It is only useful if the sample size mode is custom */
+ protected double sampleSize = 0.0;
+ /** The alignment filename. */
+ protected String align_file = null;
+ /** The tree filename. */
+ protected String tree_file = null;
+ /** Logging Enabled/Disabled **/
+ protected boolean logEnabled = true;
+ /** The log filename. */
+ protected String log_file = null;
+ /** The alignment, according to the alignment input file. */
+ protected Alignment alignment;
+ /** The tree, according to the tree filename. */
+ protected Tree tree;
+ /** The number of categories. It is only useful if the distribution is gamma */
+ public int ncat = 4;
+ /** The optimization strategy mode. */
+ public int strategyMode = DEFAULT_STRATEGY_MODE;
+ /** The matrices of the models to optimize. */
+ private List<String> matrices = new ArrayList<String>(); //{"JTT", "MtREV", "Dayhoff", "WAG"};
+ /** The distributions of the models to optimize. */
+ private List<Integer> distributions = new ArrayList<Integer>(); //{0,1,2,3};
+ /** Hash table with the relationship between distribution name and distribution internal parameter. */
+ private HashMap<String, Integer> distributionsHash;
+ /** Boolean value to consider or not different kind of amino-acid frequencies. */
+ private boolean plusF = false;
+ // display options
+ /** Display Newick tree on results. */
+ private boolean displayNewickTree = DEFAULT_DISPLAY_NEWICK_TREE;
+ /** Display ASCII tree on results. */
+ private boolean displayASCIITree = DEFAULT_DISPLAY_ASCII_TREE;
+ /** Display Consensus tree on results. */
+ private boolean displayConsensusTree = DEFAULT_DISPLAY_CONSENSUS_TREE;
+ /** Consensus threshold **/
+ private double consensusThreshold;
+ /** Display a 7-framework comparison. */
+ private boolean compareAll = DEFAULT_COMPARE_ALL;
+ /** Write a log file. */
+ public boolean writeLog = true;
+ /** Criterion to sort the models. */
+ private boolean doAIC,doBIC,doAICc,doDT;
+ /** Tree search operation */
+ private String treeSearchOperation = TREE_SEARCH_NNI;
+
+ /**
+ * Sets the number of categories.
+ *
+ * @param ncat the new number of categories
+ */
+ public void setNumberOfCategories(int ncat) {
+ this.ncat = ncat;
+ }
+
+ /**
+ * Gets the value of plusF attribute.
+ *
+ * @return the plusF value
+ */
+ public boolean isPlusF() {
+ return plusF;
+ }
+
+ /**
+ * Sets the empirical amino-acid frequencies usage.
+ *
+ * @param plusF the new value for consider empirical frequencies
+ */
+ public void setPlusF(boolean plusF) {
+ this.plusF = plusF;
+ }
+
+ /**
+ * Checks if is required to display newick tree.
+ *
+ * @return true, if is required to display newick tree
+ */
+ public boolean isDisplayNewickTree() {
+ return displayNewickTree;
+ }
+
+ /**
+ * Checks if is required to display ascii tree.
+ *
+ * @return true, if is required to display ascii tree
+ */
+ public boolean isDisplayASCIITree() {
+ return displayASCIITree;
+ }
+
+ /**
+ * Checks whether PhyML logging is enabled
+ *
+ * @return true, if PhyML logging is enabled
+ */
+ public boolean isLogEnabled() {
+ return logEnabled;
+ }
+
+ /**
+ * Checks if is required to display consensus tree.
+ *
+ * @return true, if is required to display consensus tree
+ */
+ public boolean isDisplayConsensusTree() {
+ return displayConsensusTree;
+ }
+
+ /**
+ * Gets the threshold to create consensus tree.
+ *
+ * @return the threshold
+ */
+ public double getConsensusThreshold() {
+ return consensusThreshold;
+ }
+
+ /**
+ * Check if should compute the AIC criterion
+ *
+ * @return true, if AIC should be computed
+ */
+ public boolean isAIC() {
+ return doAIC;
+ }
+
+ /**
+ * Check if should compute the BIC criterion
+ *
+ * @return true, if BIC should be computed
+ */
+ public boolean isBIC() {
+ return doBIC;
+ }
+
+ /**
+ * Check if should compute the AICc criterion
+ *
+ * @return true, if AICc should be computed
+ */
+ public boolean isAICc() {
+ return doAICc;
+ }
+
+ /**
+ * Check if should compute the DT criterion
+ *
+ * @return true, if DT should be computed
+ */
+ public boolean isDT() {
+ return doDT;
+ }
+ public String getTreeSearchOperation() {
+ return treeSearchOperation;
+ }
+
+ public void setTreeSearchOperation(String treeSearchOperation) {
+ this.treeSearchOperation = treeSearchOperation;
+ }
+
+ /**
+ * Sets the alignment filename without checking
+ *
+ * @param alignFile the alignment filename
+ */
+ public void setAlignmentFilename(String alignFile) {
+ this.align_file = alignFile;
+ }
+
+ /**
+ * Sets the alignment file
+ *
+ * @param alignFile the alignment filename
+ *
+ * @return true, if successful
+ *
+ * @throws AlignmentParseException Signals that the alignment filename is not correct.
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public boolean setAlignment(String alignFile)
+ throws AlignmentParseException,
+ IOException {
+
+ this.align_file = alignFile;
+
+ StringWriter sw = new StringWriter();
+ setAlignment(AlignmentReader.readAlignment(new PrintWriter(sw), alignFile, debug));
+ sw.flush();
+ println(sw.toString());
+
+ return alignFile != null;
+ }
+
+ /**
+ * Gets the alignment.
+ *
+ * @return the alignment
+ */
+ public Alignment getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Gets the tree.
+ *
+ * @return the tree
+ */
+ public Tree getTree() {
+ return tree;
+ }
+
+ /**
+ * Sets the alignment.
+ *
+ * @param alignment the new alignment
+ */
+ public void setAlignment(Alignment alignment) {
+ this.alignment = alignment;
+ }
+
+ /**
+ * Sets the tree.
+ *
+ * @param tree the new tree
+ */
+ public synchronized void setTree(Tree tree) {
+ this.tree = tree;
+ }
+
+ /**
+ * Checks if is debug (verbose mode).
+ *
+ * @return true, if is debug
+ */
+ public boolean isDebug() {
+ return debug;
+ }
+
+ /**
+ * Sets the debug mode value.
+ *
+ * @param debug the new debug mode value
+ */
+ public void setDebug(boolean debug) {
+ this.debug = debug;
+ }
+
+ /**
+ * Checks if a 7-framework comparison should be displayed.
+ *
+ * @return true, if a 7-framework comparison should be displayed
+ */
+ public boolean isAll() {
+ return compareAll;
+ }
+
+ /**
+ * Sets the 7-framework comparison display value.
+ *
+ * @param all the new 7-framework comparison display value
+ */
+ public void setAll(boolean all) {
+ this.compareAll = all;
+ }
+
+ /**
+ * Gets the tree filename.
+ *
+ * @return the tree filename
+ */
+ public String getTreeFile() {
+ return tree_file;
+ }
+
+ /**
+ * Sets the tree filename.
+ *
+ * @param treeFile the new tree filename
+ *
+ * @throws TreeFormatException Signals there was an error parsing the tree file
+ */
+ public void setTreeFile(String treeFile)
+ throws TreeFormatException, FileNotFoundException, IOException {
+ if (treeFile != null) {
+ this.tree_file = treeFile;
+
+ StringWriter sw = new StringWriter();
+ setTree(AlignmentReader.readTree(new PrintWriter(sw), treeFile, debug));
+ sw.flush();
+ println(sw.toString());
+ }
+ }
+
+ /**
+ * Gets the number of model matrices.
+ *
+ * @return the number of model matrices
+ */
+ public int getNumberOfMatrices() {
+ return matrices.size();
+ }
+
+ /**
+ * Gets the model matrices.
+ *
+ * @return the model matrices
+ */
+ public List<String> getMatrices() {
+ List<String> matricesClone = new ArrayList<String>(matrices);
+ return matricesClone;
+ }
+
+ /**
+ * Sets the model matrices.
+ *
+ * @param newMatrices the new model matrices
+ */
+ public void setMatrices(List<String> newMatrices) {
+ matrices = newMatrices;
+ }
+
+ /**
+ * Gets the matrix at a certain position.
+ *
+ * @param pos the position of the matrix
+ *
+ * @return the matrix at the required position
+ */
+ public String getMatrixAt(int pos) {
+ return matrices.get(pos);
+ }
+
+ /**
+ * Check if one matrix exists in the model matrices set of the application.
+ *
+ * @param matrix the matrix to check out
+ *
+ * @return true, if the set of matrices contains the model matrix
+ */
+ public boolean existsMatrix(String matrix) {
+ return matrices.contains(matrix);
+ }
+
+ /**
+ * Removes one matrix of the set.
+ *
+ * @param matrix the matrix to remove
+ *
+ * @return true, if the matrix was successfully removed
+ */
+ public boolean removeMatrix(String matrix) {
+ return matrices.remove(matrix);
+ }
+
+ /**
+ * Adds one matrix to the set.
+ *
+ * @param matrix the matrix to add
+ */
+ public void addMatrix(String matrix) {
+ if (!matrices.contains(matrix)) {
+ matrices.add(matrix);
+ }
+ }
+
+ /**
+ * Gets the distributions.
+ *
+ * @return the distributions
+ */
+ public List<Integer> getDistributions() {
+ List<Integer> distributionsClone = new ArrayList<Integer>(distributions);
+ return distributionsClone;
+ }
+
+ /**
+ * Sets the distributions.
+ *
+ * @param newDistributions the new distributions
+ */
+ public void setDistributions(List<Integer> newDistributions) {
+ distributions = newDistributions;
+ }
+
+ /**
+ * Gets the number of distributions.
+ *
+ * @return the number of distributions
+ */
+ public int getNumberOfDistributions() {
+ return distributions.size();
+ }
+
+ /**
+ * Gets the distribution at a certain position of the list.
+ *
+ * @param pos the position of the distribution to get
+ *
+ * @return the distribution at the required position
+ */
+ public int getDistributionAt(int pos) {
+ return distributions.get(pos);
+ }
+
+ /**
+ * Gets the internal value of a distribution.
+ *
+ * @param distribution the distribution name
+ *
+ * @return the distribution value
+ */
+ public int getDistribution(String distribution) {
+ return distributionsHash.get(distribution);
+ }
+
+ /**
+ * Check if exist one distribution in the distribution set.
+ *
+ * @param distribution the distribution to check out
+ *
+ * @return true, if the set of distribution contains the distribution
+ */
+ public boolean existsDistribution(String distribution) {
+ return distributionsHash.containsKey(distribution);
+ }
+
+ /**
+ * Adds one distribution to the distributions set.
+ *
+ * @param distribution the distribution to add
+ */
+ public void addDistribution(String distribution) {
+ Integer distributionValue = distributionsHash.get(distribution);
+ if (!distributions.contains(distributionValue)) {
+ distributions.add(distributionValue);
+ }
+ }
+
+ /**
+ * Removes the distribution from the distributions set.
+ *
+ * @param distribution the distribution to remove
+ *
+ * @return true, if the distribution was successfully removed
+ */
+ public boolean removeDistribution(String distribution) {
+ Integer distributionValue = distributionsHash.get(distribution);
+ return distributions.remove(distributionValue);
+ }
+
+ /**
+ * Gets the sample size.
+ *
+ * @return the sample size
+ */
+ public double getSampleSize() {
+ return alignment.getSiteCount();
+ }
+
+ /**
+ * Sets the sample size.
+ *
+ * @param sampleSize the new sample size
+ */
+ public void setSampleSize(double sampleSize) {
+ this.sampleSize = sampleSize;
+ }
+
+ /**
+ * Sets the strategy mode.
+ *
+ * @param strategyMode the new strategy mode
+ */
+ public void setStrategyMode(int strategyMode) {
+ if (strategyMode == OPTIMIZE_USER && getTreeFile() == null) {
+ throw new ProtTestInternalException("User defined topology must be set");
+ }
+ this.strategyMode = strategyMode;
+ }
+
+ /**
+ * Instantiates a new application options.
+ */
+ public ApplicationOptions() {
+ initLists();
+ }
+
+ /**
+ * Fill in attribute values with the arguments.
+ *
+ * @param arguments the arguments too fill the application options instance in
+ */
+ public void fillIn(ProtTestArgumentParser arguments) {
+
+ if (arguments.exists(ProtTestArgumentParser.PARAM_ALIGNMENT_FILE)) {
+ try {
+ setAlignment(arguments.getValue(ProtTestArgumentParser.PARAM_ALIGNMENT_FILE));
+ } catch (AlignmentParseException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ } else {
+ throw new IllegalArgumentException("Required input file argument -i");
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_TREE_FILE)) {
+ try {
+ setTreeFile(arguments.getValue(ProtTestArgumentParser.PARAM_TREE_FILE));
+ } catch (FileNotFoundException ex) {
+ throw new IllegalArgumentException(ex.getMessage());
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(ex.getMessage());
+ }
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_OUTPUT_FILE)) {
+ //open the PrintWriter with file
+ try {
+ FileOutputStream fo = new FileOutputStream(arguments.getValue(ProtTestArgumentParser.PARAM_OUTPUT_FILE));
+ ProtTestLogger.getDefaultLogger().addHandler(fo, Level.INFO);
+ } catch (FileNotFoundException fnfe) {
+ throw new ProtTestInternalException(fnfe.getMessage());
+ }
+ }
+
+ if (arguments.exists(ProtTestArgumentParser.PARAM_LOGGING)) {
+ logEnabled = arguments.getValue(ProtTestArgumentParser.PARAM_LOGGING).equalsIgnoreCase("enabled");
+ }
+
+ if (arguments.exists(ProtTestArgumentParser.PARAM_TREE_SEARCH_OP)) {
+ setTreeSearchOperation(arguments.getValue(ProtTestArgumentParser.PARAM_TREE_SEARCH_OP));
+ }
+ setDebug(arguments.isSet(ProtTestArgumentParser.PARAM_VERBOSE));
+ displayASCIITree = arguments.isSet(ProtTestArgumentParser.PARAM_DISPLAY_ASCII_TREE);
+ displayNewickTree = arguments.isSet(ProtTestArgumentParser.PARAM_DISPLAY_NEWICK_TREE);
+ displayConsensusTree = arguments.isSet(ProtTestArgumentParser.PARAM_DISPLAY_CONSENSUS_TREE);
+ if (arguments.exists(ProtTestArgumentParser.PARAM_DISPLAY_CONSENSUS_TREE)) {
+ displayConsensusTree = true;
+ try {
+ consensusThreshold = Double.parseDouble(arguments.getValue(ProtTestArgumentParser.PARAM_DISPLAY_CONSENSUS_TREE));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Consensus threshold must be a number between 0.5 (majority rule) and 1 (strict). You used " + arguments.getValue(ProtTestArgumentParser.PARAM_DISPLAY_CONSENSUS_TREE));
+ }
+ if (consensusThreshold < 0.5 || consensusThreshold > 1.0) {
+ throw new IllegalArgumentException("Consensus threshold must be a number between 0.5 (majority rule) and 1 (strict). You used " + consensusThreshold);
+ }
+ }
+ setAll(arguments.isSet(ProtTestArgumentParser.PARAM_ALL_FRAMEWORK_COMPARISON));
+ if (arguments.exists(ProtTestArgumentParser.PARAM_OPTIMIZATION_STRATEGY)) {
+ if (getTreeFile() != null) {
+ strategyMode = OPTIMIZE_USER;
+ } else {
+ strategyMode = Integer.parseInt(arguments.getValue(ProtTestArgumentParser.PARAM_OPTIMIZATION_STRATEGY));
+ // Check
+ if (strategyMode == OPTIMIZE_USER &&
+ getTreeFile() == null) {
+ throw new IllegalArgumentException("User defined topology must be set");
+ }
+ }
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_DO_AIC)) {
+ doAIC = arguments.isSet(ProtTestArgumentParser.PARAM_DO_AIC);
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_DO_BIC)) {
+ doBIC = arguments.isSet(ProtTestArgumentParser.PARAM_DO_BIC);
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_DO_AICC)) {
+ doAICc = arguments.isSet(ProtTestArgumentParser.PARAM_DO_AICC);
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_DO_DT)) {
+ doDT = arguments.isSet(ProtTestArgumentParser.PARAM_DO_DT);
+ }
+
+ setSampleSize(ProtTestAlignment.calculateSampleSize(alignment));
+
+ boolean existsMatrix = false;
+ for (String matrix : arguments.getMatrices()) {
+ if (arguments.isSet(matrix)) {
+ addMatrix(matrix);
+ existsMatrix = true;
+ } else {
+ removeMatrix(matrix);
+ }
+ }
+ if (!existsMatrix) {
+ throw new IllegalArgumentException("You must specify at least one model matrix");
+ }
+
+ // distributions
+ addDistribution("Uniform");
+ boolean plusG = false, plusIG = false;
+ if (arguments.isSet(ProtTestArgumentParser.PARAM_PLUSI)) {
+ addDistribution("+I");
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_PLUSG)) {
+ addDistribution("+G");
+ plusG = true;
+ }
+ if (arguments.exists(ProtTestArgumentParser.PARAM_PLUSIG)) {
+ addDistribution("+I+G");
+ plusIG = true;
+ }
+ if (plusG || plusIG) {
+ try {
+ setNumberOfCategories(Integer.parseInt(arguments.getValue(ProtTestArgumentParser.PARAM_NCAT)));
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException("Invalid number of categories " + arguments.getValue(ProtTestArgumentParser.PARAM_PLUSG));
+ }
+ }
+ if (arguments.isSet(ProtTestArgumentParser.PARAM_PLUSF)) {
+ setPlusF(true);
+ }
+ }
+
+ /**
+ * Inits the Lists.
+ */
+ private void initLists() {
+// for(int i=0; i<ALL_MATRICES.length; i++) {
+// matrixes.addElement(ALL_MATRICES[i]);
+// }
+ distributionsHash = new HashMap<String, Integer>();
+ distributionsHash.put("Uniform", new Integer(Model.DISTRIBUTION_UNIFORM));
+ distributionsHash.put("+I", new Integer(Model.DISTRIBUTION_INVARIABLE));
+ distributionsHash.put("+G", new Integer(Model.DISTRIBUTION_GAMMA));
+ distributionsHash.put("+I+G", new Integer(Model.DISTRIBUTION_GAMMA_INV));
+ }
+
+ /**
+ * Display the command line usage of the application.
+ */
+ public static void usage() {
+ println("-------------------------------------------------------------------------------------------------");
+ println("Basic usage: ");
+ println(" - Sequential version: ");
+ println(" java -jar prottest-2.1.jar -i alignm_file [OPTIONS]");
+ println(" - Parallel version: ");
+ println(" mpjrun.sh -wdir $PWD/ -np [NUM_PROCS] -jar ModelTest-2.1.jar -i alignm_file [OPTIONS]");
+ println("OPTIONS:");
+ println(" -i alignment_filename");
+ println(" Alignment input file (required)");
+ println(" -t tree_filename");
+ println(" Tree file (optional) [default: NJ tree]");
+ println(" -o output_filename");
+ println(" Output file (optional) [default: standard output]");
+ println(" -log enabled/disabled");
+ println(" Enables / Disables PhyML logging into log directory (see prottest.properties)");
+ println(" -[matrix]");
+ print( " Include matrix (Amino-acid) = " );
+ int count = 0;
+ List<String> matrices = ProtTestFactory.getInstance().getApplicationGlobals().getSupportedMatrices();
+ for (String matrix : matrices) {
+ print(matrix + " ");
+ if (count == (7)) {
+ println("");
+ print(" ");
+ }
+ count++;
+ }
+ println("");
+ println(" If you don't specify any matrix, all matrices displayed above will");
+ println(" be included.");
+ println(" -I");
+ println(" Include models with a proportion of invariable sites");
+ println(" -G");
+ println(" Include models with rate variation among sites and number of categories");
+ println(" -IG");
+ println(" include models with both +I and +G properties");
+ println(" -all-distributions");
+ println(" Include models with rate variation among sites, number of categories and both");
+ println(" -ncat number_of_categories");
+ println(" Define number of categories for +G and +I+G models [default: " + DEFAULT_NCAT + "]");
+ println(" -F");
+ println(" Include models with empirical frequency estimation ");
+ println(" -AIC");
+ println(" Display models sorted by Akaike Information Criterion (AIC)");
+ println(" -BIC");
+ println(" Display models sorted by Bayesian Information Criterion (BIC)");
+ println(" -AICC");
+ println(" Display models sorted by Corrected Akaike Information Criterion (AICc)");
+ println(" -DT");
+ println(" Display models sorted by Decision Theory Criterion");
+ println(" -all");
+ println(" Displays a 7-framework comparison table");
+ println(" -S optimization_strategy");
+ println(" Optimization strategy mode: [default: " + DEFAULT_STRATEGY_MODE + "]");
+ for (int i = 0; i < OPTIMIZE_NAMES.length; i++) {
+ println(" " + i + ": " + OPTIMIZE_NAMES[i]);
+ }
+ println(" -s moves");
+ println(" Tree search operation for ML search: ");
+ println(" NNI (fastest), SPR (slowest), BEST (best of NNI and SPR) [default: NNI]");
+ println(" -t1 ");
+ println(" Display best-model's newick tree [default: " + DEFAULT_DISPLAY_NEWICK_TREE + "]");
+ println(" -t2 ");
+ println(" Display best-model's ASCII tree [default: " + DEFAULT_DISPLAY_ASCII_TREE + "]");
+ println(" -tc consensus_threshold ");
+ println(" Display consensus tree with the specified threshold, between 0.5 and 1.0");
+ println(" [0.5 = majority rule consensus ; 1.0 = strict consensus]");
+ println(" -threads number_or_threads ");
+ println(" Number of threads requested to compute (only if MPJ is not used) [default: " +
+ DEFAULT_THREADS + "]");
+ println(" -verbose");
+ println(" Verbose mode [default: " + DEFAULT_DEBUG + "]");
+ println("-------------------------------------------------------------------------------------------------");
+ println("Example: ");
+ println("- Sequential version:");
+ println(" java -jar ModelTest-2.1.jar -i alignm_file -t tree_file -S 0 -all-distributions -F -AIC -BIC -tc 0.5 > output");
+ println("- Parallel version:");
+ println(" mpjrun.sh -wdir $PWD/ -np 2 -jar ModelTest-2.1.jar -i alignm_file -t tree_file -S 0 -all-distributions -F -AIC -BIC -tc 0.5");
+ }
+
+ public void reportModelOptimization() {
+ String tmp;
+ tmp = "BioNJ";
+ if (tree_file != null) {
+ tmp = tree_file;
+ }
+ println("");
+ println("ProtTest options");
+ println("----------------");
+ println(" Alignment file........... : " + align_file);
+ println(" Tree..................... : " + tmp);
+ println(" StrategyMode............. : " + OPTIMIZE_NAMES[strategyMode]);
+
+ println(" Candidate models......... : ");
+ print(" Matrices............... : ");
+ for (int i = 0; i < matrices.size(); i++) {
+ print(matrices.get(i) + " ");
+ }
+ println("");
+ print(" Distributions.......... : ");
+ for (String dist : distributionsHash.keySet()) {
+ Integer value = (Integer) distributionsHash.get(dist);
+ if (distributions.contains(value)) {
+ print(dist + " ");
+ }
+ }
+ println("");
+ println(" Observed frequencies... : " + plusF);
+ println("");
+ }
+
+ /**
+ * Report the current options.
+ */
+ public void reportComplete() {
+ reportModelOptimization();
+
+ println(" Statistical framework");
+ println(" Sort models according to....: ");
+ StringBuilder sb = new StringBuilder();
+ if (doAIC) {
+ sb.append(" AIC ");
+ }
+ if (doBIC) {
+ sb.append(" BIC ");
+ }
+ if (doAICc) {
+ sb.append(" AICc ");
+ }
+ if (doDT) {
+ sb.append(" DT ");
+ }
+ if (!(doAIC|doBIC|doAICc|doDT))
+ sb.append(" lnL");
+ println(" " + sb.toString());
+ println(" Sample size.................: " + sampleSize + " (not calculated yet)");
+ println(" Other options:");
+ println(" Display best tree in ASCII..: " + displayASCIITree);
+ println(" Display best tree in Newick.: " + displayNewickTree);
+ println(" Display consensus tree......: " + displayConsensusTree);
+ if (displayConsensusTree) {
+ println(" Consensus threshold.........: " + consensusThreshold);
+ }
+ println(" Verbose.....................: " + debug);
+
+ println("");
+ }
+
+ private static void print(String message) {
+ info(message, ApplicationOptions.class);
+ }
+
+ private static void println(String message) {
+ infoln(message, ApplicationOptions.class);
+ }
+}
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/options/SerializableApplicationOptions.java b/src/main/java/es/uvigo/darwin/prottest/global/options/SerializableApplicationOptions.java
new file mode 100755
index 0000000..7bc026b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/options/SerializableApplicationOptions.java
@@ -0,0 +1,194 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.global.options;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * This class is a serializable version of {@link ApplicationOptions ApplicationOptions}.
+ * It has all important attributes in a concrete state of the application, and
+ * reduces alignment ant topology to a hash, making this object much lighter
+ * than the Application Options instance.
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class SerializableApplicationOptions implements Serializable {
+
+ private static final long serialVersionUID = 7758895101915536602L;
+ /** The alignment, according to the alignment input file. */
+ protected int alignment;
+ /** The tree, according to the tree filename. */
+ protected int tree;
+ /** The number of categories. It is only useful if the distribution is gamma */
+ public int numberOfCategories;
+ /** The optimization strategy mode. */
+ public int strategyMode;
+ /** The matrices of the models to optimize. */
+ private List<String> matrices;
+ /** The distributions of the models to optimize. */
+ private List<Integer> distributions;
+ /** Boolean value to consider or not different kind of amino-acid frequencies. */
+ private boolean plusF;
+
+ /**
+ * Gets the alignment hash.
+ *
+ * @return the alignment hash
+ */
+ public int getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Gets the phylogenetic tree hash.
+ *
+ * @return the tree hash
+ */
+ public int getTree() {
+ return tree;
+ }
+
+ /**
+ * Gets the number of rate categories.
+ *
+ * @return the number of rate categories
+ */
+ public int getNumberOfCategories() {
+ return numberOfCategories;
+ }
+
+ /**
+ * Gets the starting topology strategy mode.
+ *
+ * @return the starting topology strategy mode
+ */
+ public int getStrategyMode() {
+ return strategyMode;
+ }
+
+ /**
+ * Gets the collection of matrix names.
+ *
+ * @return the collection of matrix names
+ */
+ public List<String> getMatrices() {
+ return matrices;
+ }
+
+ /**
+ * Gets the collection of distribution identifiers.
+ *
+ * @return the collection of distribution identifiers
+ */
+ public List<Integer> getDistributions() {
+ return distributions;
+ }
+
+ /**
+ * Gets the state of empirical frequencies consideration.
+ *
+ * @return true, if empirical frequencies are considered
+ */
+ public boolean isPlusF() {
+ return plusF;
+ }
+
+ /**
+ * Instantiates a new serializable application options.
+ *
+ * @param options the actual application options instance
+ */
+ public SerializableApplicationOptions(ApplicationOptions options) {
+ this.alignment = options.getAlignment().toString().hashCode();
+ if (options.getTree() != null) {
+ this.tree = options.getTree().toString().hashCode();
+ }
+ this.numberOfCategories = options.ncat;
+ this.strategyMode = options.strategyMode;
+ this.matrices = options.getMatrices();
+ this.distributions = options.getDistributions();
+ this.plusF = options.isPlusF();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + alignment;
+ result = prime * result + ((distributions == null) ? 0 : distributions.hashCode());
+ result = prime * result + ((matrices == null) ? 0 : matrices.hashCode());
+ result = prime * result + numberOfCategories;
+ result = prime * result + (plusF ? 1231 : 1237);
+ result = prime * result + strategyMode;
+ result = prime * result + tree;
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ SerializableApplicationOptions other = (SerializableApplicationOptions) obj;
+ if (alignment != other.alignment) {
+ return false;
+ }
+ if (distributions == null) {
+ if (other.distributions != null) {
+ return false;
+ }
+ } else if (!distributions.equals(other.distributions)) {
+ return false;
+ }
+ if (matrices == null) {
+ if (other.matrices != null) {
+ return false;
+ }
+ } else if (!matrices.equals(other.matrices)) {
+ return false;
+ }
+ if (numberOfCategories != other.numberOfCategories) {
+ return false;
+ }
+ if (plusF != other.plusF) {
+ return false;
+ }
+ if (strategyMode != other.strategyMode) {
+ return false;
+ }
+ if (tree != other.tree) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "SerializableApplicationOptions [alignment=" + alignment + ", distributions=" + distributions + ", matrices=" + matrices + ", numberOfCategories=" + numberOfCategories + ", plusF=" + plusF + ", strategyMode=" + strategyMode + ", tree=" + tree + "]";
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/options/package.html b/src/main/java/es/uvigo/darwin/prottest/global/options/package.html
new file mode 100755
index 0000000..df6c79d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/options/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the configuration classes for a single execution.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/global/package.html b/src/main/java/es/uvigo/darwin/prottest/global/package.html
new file mode 100755
index 0000000..d78288e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/global/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains global classes and interfaces which can be used from everywhere in the model.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/AminoAcidModel.java b/src/main/java/es/uvigo/darwin/prottest/model/AminoAcidModel.java
new file mode 100755
index 0000000..3bf15bb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/AminoAcidModel.java
@@ -0,0 +1,88 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.model;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+
+/**
+ * Substitution model form amino-acid sequences
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class AminoAcidModel extends Model {
+
+ /** The serialVersionUID. */
+ private static final long serialVersionUID = -8634618735564880783L;
+
+ /**
+ * Instantiates a new amino acid substitution model.
+ *
+ * @param matrix the matrix name
+ * @param distribution the distribution value
+ * @param plusF consider observed frequencies
+ */
+ public AminoAcidModel(String matrix, int distribution, boolean plusF,
+ Alignment alignment, Tree tree, int ncat) {
+ super(matrix, distribution, plusF, alignment, tree, ncat);
+
+ if (isPlusF())
+ frequenciesDistribution = FREQ_DISTRIBUTION_EMPIRICAL;
+ else
+ frequenciesDistribution = FREQ_DISTRIBUTION_OTHER;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.Model#getNumberOfModelParameters()
+ */
+ public int getNumberOfModelParameters() {
+ int numModelParameters;
+ numModelParameters = getNumBranches() + getDistributionParameters();
+ if(isPlusF())
+ numModelParameters = numModelParameters + 19;
+ return numModelParameters;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.Model#getModelName()
+ */
+ @Override
+ public String getModelName() {
+
+ String matrixName =
+ ProtTestFactory.getInstance().
+ getApplicationGlobals().
+ getModelName(getMatrix(), frequenciesDistribution);
+ StringBuffer modelName = new StringBuffer(matrixName);
+ if(getDistribution() == Model.DISTRIBUTION_INVARIABLE)
+ modelName.append("+I");
+ else if(getDistribution() == Model.DISTRIBUTION_GAMMA)
+ modelName.append("+G");
+ else if(getDistribution() == Model.DISTRIBUTION_GAMMA_INV)
+ modelName.append("+I+G");
+
+ if(isPlusF())
+ modelName.append("+F");
+
+ return modelName.toString();
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/Model.java b/src/main/java/es/uvigo/darwin/prottest/model/Model.java
new file mode 100755
index 0000000..f7158f1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/Model.java
@@ -0,0 +1,479 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.model;
+
+import java.io.PrintWriter;
+import java.io.Serializable;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import pal.tree.TreeUtils;
+import es.uvigo.darwin.prottest.model.state.ModelEmptyLkState;
+import es.uvigo.darwin.prottest.model.state.ModelFilledLkState;
+import es.uvigo.darwin.prottest.model.state.ModelLkState;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.*;
+
+import java.io.StringWriter;
+
+/**
+ * Substitution model.
+ */
+public abstract class Model implements Serializable {
+
+ /** The serialVersionUID. */
+ private static final long serialVersionUID = 20090804L;
+
+ // distributions
+ /** Useful constant for uniform distribution. */
+ public static final int DISTRIBUTION_UNIFORM = 0;
+ /** Useful constant for distribution with a proportion of invariable sites. */
+ public static final int DISTRIBUTION_INVARIABLE = 1;
+ /** Useful constant for gamma distribution. */
+ public static final int DISTRIBUTION_GAMMA = 2;
+ /** Useful constant for gamma distribution with a proportion of invariable sites. */
+ public static final int DISTRIBUTION_GAMMA_INV = 3;
+
+ // frequencies distribution
+ /** The value of Uniform Frequencies Distribution. */
+ static final int FREQ_DISTRIBUTION_UNIFORM = 1;
+ /** The value of Empirical Frequencies Distribution. */
+ static final int FREQ_DISTRIBUTION_EMPIRICAL = 2;
+ /** The value of Maximum Likelihood Frequencies Distribution. */
+ static final int FREQ_DISTRIBUTION_MAXIMUM_LIKELIHOOD = 3;
+ /** The value of any other frequencies distribution. */
+ static final int FREQ_DISTRIBUTION_OTHER = 4;
+
+ /** Useful constant for consider observed frequencies. */
+ public static final String PROP_PLUS_F = "plusF";
+ /** The matrix name. */
+ private String matrix;
+ /** The distribution. */
+ private int distribution;
+ /** Consider observed frequencies. */
+ private boolean plusF;
+ /** The frequencies distribution. */
+ protected int frequenciesDistribution;
+ /** The alignment hashcode. */
+ private int alignment;
+ /** The number of sequences. */
+ private int numberOfSequences;
+ /** The tree. */
+ private Tree tree;
+ /** The number of model parameters. */
+// private int numModelParameters;
+ /** The number of transition categories. */
+ private int numOfTransCategories;
+ /** The likelihood calculation state. */
+ private ModelLkState lkState;
+ /** The external executor command line. */
+ private String[] commandLine;
+
+ /**
+ * Gets the likelihood estimated value.
+ *
+ * @return the likelihood estimated value
+ */
+ public double getLk() {
+ return lkState.getLk();
+ }
+
+ /**
+ * Checks if is computed.
+ *
+ * @return true, if is computed
+ */
+ public boolean isComputed() {
+ return (lkState instanceof ModelFilledLkState);
+ }
+
+ /**
+ * Sets the likelihood estimated value.
+ *
+ * @param lk the new likelihood estimated value
+ */
+ public void setLk(double lk) {
+ lkState = lkState.setLk(lk);
+ }
+
+ /**
+ * Gets the alpha estimated value.
+ *
+ * @return the alpha estimated value
+ */
+ public double getAlpha() {
+ return lkState.getAlpha();
+ }
+
+ /**
+ * Sets the alpha estimated value.
+ *
+ * @param alpha the new alpha estimated value
+ */
+ public void setAlpha(double alpha) {
+ lkState = lkState.setAlpha(alpha);
+ }
+
+ /**
+ * Gets the proportion of invariant sites.
+ *
+ * @return the proportion of invariant sites
+ */
+ public double getInv() {
+ return lkState.getInv();
+ }
+
+ /**
+ * Sets the proportion of invariant sites.
+ *
+ * @param inv the new proportion of invariant sites
+ */
+ public void setInv(double inv) {
+ lkState = lkState.setInv(inv);
+ }
+
+ /**
+ * Gets the alignment hashcode.
+ *
+ * @return the alignment hashcode
+ */
+ public int getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Sets the alignment only if there wasn't set or it is a different instance of the same object.
+ *
+ * @param alignment the new alignment
+ */
+ public void setAlignment(Alignment alignment) {
+ if (this.alignment != 0 && this.alignment != alignment.toString().hashCode()) {
+ throw new ProtTestInternalException("cannot set a different alignment");
+ }
+ this.alignment = alignment.toString().hashCode();
+ this.numberOfSequences = alignment.getSequenceCount();
+ }
+
+ /**
+ * Checks if an alignment matches the internal model alignment
+ *
+ * @return alignment equality
+ */
+ public boolean checkAlignment(Alignment alignment) {
+ if (alignment == null) {
+ return false;
+ }
+ return (this.alignment == alignment.toString().hashCode() &&
+ this.numberOfSequences == alignment.getSequenceCount());
+ }
+
+ /**
+ * Gets the tree.
+ *
+ * @return the tree
+ */
+ public Tree getTree() {
+ return tree;
+ }
+
+ /**
+ * Sets the tree.
+ *
+ * @param tree the new tree
+ */
+ public void setTree(Tree tree) {
+ this.tree = tree;
+ }
+
+ /**
+ * Gets the command line.
+ *
+ * @return the command line
+ */
+ public String[] getCommandLine() {
+ return commandLine;
+ }
+
+ /**
+ * Sets the command line.
+ *
+ * @param commandLine the new command line
+ */
+ public void setCommandLine(String[] commandLine) {
+ this.commandLine = commandLine;
+ }
+
+ /**
+ * Gets the number of transition categories.
+ *
+ * @return the number of transition categories
+ */
+ public int getNumberOfTransitionCategories() {
+ return numOfTransCategories;
+ }
+
+ /**
+ * Instantiates a new substitution model.
+ *
+ * @param matrix the matrix name
+ * @param distribution the distribution value
+ * @param plusF consider observed frequencies
+ * @param alignment the alignment
+ * @param tree the tree
+ * @param ncat the ncat
+ */
+ public Model(String matrix, int distribution, boolean plusF, Alignment alignment, Tree tree, int ncat) {
+
+ if (distribution < 0 || distribution > 3) {
+ throw new ProtTestInternalException("Distribution not supported " + distribution);
+ }
+
+ if (alignment == null) {
+ throw new ProtTestInternalException("Null alignment");
+ }
+
+ this.matrix = matrix;
+ this.distribution = distribution;
+ this.plusF = plusF;
+ this.alignment = alignment.toString().hashCode();
+ this.numberOfSequences = alignment.getSequenceCount();
+ this.tree = tree;
+ this.lkState = new ModelEmptyLkState();
+
+// numBranches = 2*alignment.getSequenceCount() - 3;
+ switch (distribution) {
+ case DISTRIBUTION_UNIFORM:
+ numOfTransCategories = 1;
+ break;
+ case DISTRIBUTION_INVARIABLE:
+ numOfTransCategories = 2;
+ break;
+ case DISTRIBUTION_GAMMA:
+ numOfTransCategories = ncat;
+ break;
+ case DISTRIBUTION_GAMMA_INV:
+ numOfTransCategories = ncat;
+ break;
+ }
+
+ }
+
+ /**
+ * Gets the number of parameters according with the distribution.
+ *
+ * @return the distribution parameters according with the distribution
+ */
+ public int getDistributionParameters() {
+ int value = -1;
+ switch (distribution) {
+ case DISTRIBUTION_UNIFORM:
+ value = 0;
+ break;
+ case DISTRIBUTION_INVARIABLE:
+ value = 1;
+ break;
+ case DISTRIBUTION_GAMMA:
+ value = 1;
+ break;
+ case DISTRIBUTION_GAMMA_INV:
+ value = 2;
+ break;
+ }
+ return value;
+ }
+
+ /**
+ * Gets the number of model parameters.
+ *
+ * @return the number of model parameters
+ */
+ public abstract int getNumberOfModelParameters();
+
+ /**
+ * Gets the matrix name.
+ *
+ * @return the matrix name
+ */
+ public String getMatrix() {
+ return matrix;
+ }
+
+ /**
+ * Gets the distribution.
+ *
+ * @return the distribution
+ */
+ public int getDistribution() {
+ return distribution;
+ }
+
+ /**
+ * Checks if observed frequencies are considered.
+ *
+ * @return true, if the model considers observed frequencies
+ */
+ public boolean isPlusF() {
+ return plusF;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + distribution;
+ result = prime * result + ((matrix == null) ? 0 : matrix.hashCode());
+ result = prime * result + (isPlusF() ? 1231 : 1237);
+ return result;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ Model other = (Model) obj;
+ if (distribution != other.distribution) {
+ return false;
+ }
+ if (matrix == null) {
+ if (other.matrix != null) {
+ return false;
+ }
+ } else if (!matrix.equals(other.matrix)) {
+ return false;
+ }
+ if (isPlusF() != other.isPlusF()) {
+ return false;
+ }
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return "Model [distribution=" + distribution + ", matrix=" + matrix + ", plusF=" + isPlusF();
+// + ", weight=" + weight + "]";
+ }
+
+ /**
+ * Gets the complete model name.
+ *
+ * @return the model name
+ */
+ public abstract String getModelName();
+
+ /**
+ * Gets the number of branches.
+ *
+ * @return the number of branches
+ */
+ public int getNumBranches() {
+ return 2 * numberOfSequences - 3;
+ }
+
+ /**
+ * Checks if distribution is gamma.
+ *
+ * @return true, if is gamma
+ */
+ public boolean isGamma() {
+ return (distribution == DISTRIBUTION_GAMMA ||
+ distribution == DISTRIBUTION_GAMMA_INV);
+ }
+
+ /**
+ * Checks if a proportion of invariant sites are considered.
+ *
+ * @return true, if considers a proportion of invariant sites
+ */
+ public boolean isInv() {
+ return (distribution == DISTRIBUTION_INVARIABLE ||
+ distribution == DISTRIBUTION_GAMMA_INV);
+ }
+
+ /**
+ * Prints the model status report.
+ */
+ public void printReport() {
+
+ println("Model................................ : " + getModelName());
+ print(" Number of parameters............... : " + getNumberOfModelParameters());
+ println(" (" + (getNumberOfModelParameters() - getNumBranches()) + " + " +
+ getNumBranches() + " branch length estimates)");
+
+ if (isComputed()) {
+ if (isGamma()) {
+ println(" gamma shape (" + getNumberOfTransitionCategories() + " rate categories).. = " + getAlpha());
+ }
+ if (isInv()) {
+ println(" proportion of invariable sites... = " + getInv());
+ }
+ if (isPlusF()) {
+ println(" aminoacid frequencies............ = observed (see above)");
+ }
+ print(" -lnL................................ = " + ProtTestFormattedOutput.getDecimalString((-1 * getLk()), 2));
+ println("");
+
+ verboseln("The tree:");
+ verboseln("---------");
+ StringWriter ascciiSw = new StringWriter();
+ TreeUtils.report(getTree(), new PrintWriter(ascciiSw));
+ ascciiSw.flush();
+ verboseln(ascciiSw.toString());
+ StringWriter newickSw = new StringWriter();
+ verboseln("---------");
+ TreeUtils.printNH(getTree(), new PrintWriter(newickSw));
+ newickSw.flush();
+ verboseln(newickSw.toString());
+ verboseln("");
+ }
+ flush(Model.class);
+ }
+
+ private void print(String message) {
+ info(message, Model.class);
+ }
+
+ private void println(String message) {
+ infoln(message, Model.class);
+ }
+
+ private void verbose(String message) {
+ finer(message, Model.class);
+ }
+
+ private void verboseln(String message) {
+ finerln(message, Model.class);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/package.html b/src/main/java/es/uvigo/darwin/prottest/model/package.html
new file mode 100755
index 0000000..71513cb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/package.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the information about the selection models. This hierarchy not only supports amino-acid
+substitution models, but also a future implementation of nucleotide models can be implemented.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/state/ModelEmptyLkState.java b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelEmptyLkState.java
new file mode 100755
index 0000000..7664711
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelEmptyLkState.java
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.model.state;
+
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * The Class ModelEmptyLkState defines the behavior of the model while the
+ * likelihood is not yet calculated.
+ */
+public class ModelEmptyLkState extends ModelLkState {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = -6972504372160405275L;
+
+ /**
+ * Throws an internal exception.
+ *
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getLk()
+ */
+ @Override
+ public double getLk() {
+ throw new ProtTestInternalException("Lk not initialized");
+ }
+
+ /**
+ *
+ * Sets the log Likelihood and changes the state to {@link ModelFilledLkState}.
+ *
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setLk(double)
+ *
+ * @return the new state
+ */
+ @Override
+ public ModelLkState setLk(double lk) {
+ return new ModelFilledLkState(lk);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getAlpha()
+ */
+ @Override
+ public double getAlpha() {
+ throw new ProtTestInternalException("This model is still unoptimized");
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getInv()
+ */
+ @Override
+ public double getInv() {
+ throw new ProtTestInternalException("This model is still unoptimized");
+ }
+
+ /**
+ * Throws an internal exception.
+ *
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setAlpha(double)
+ */
+ @Override
+ public ModelLkState setAlpha(double alpha) {
+ throw new ProtTestInternalException("This model is still unoptimized");
+ }
+
+ /**
+ * Throws an internal exception.
+ *
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setInv(double)
+ */
+ @Override
+ public ModelLkState setInv(double inv) {
+ throw new ProtTestInternalException("This model is still unoptimized");
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/state/ModelFilledLkState.java b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelFilledLkState.java
new file mode 100755
index 0000000..0356b72
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelFilledLkState.java
@@ -0,0 +1,100 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.model.state;
+
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+/**
+ * The Class ModelFilledLkState defines the behavior of the model when the
+ * likelihood is already calculated.
+ */
+public class ModelFilledLkState extends ModelLkState {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 8247641688056141331L;
+
+ /** The likelihood logarithm value. */
+ private double lk;
+
+ /** The calculated alpha value. */
+ private double alpha;
+
+ /** The calculated proportion of invariant sites. */
+ private double inv;
+
+ /**
+ * Instantiates a new model filled lk state.
+ *
+ * @param lk the lk
+ */
+ public ModelFilledLkState(double lk) {
+ this.lk = lk;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getLk()
+ */
+ @Override
+ public double getLk() {
+ return lk;
+ }
+
+ /**
+ * Throws an internal exception.
+ *
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setLk(double)
+ */
+ @Override
+ public ModelLkState setLk(double lk) {
+ throw new ProtTestInternalException("Trying to modify lnl value");
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getAlpha()
+ */
+ @Override
+ public double getAlpha() {
+ return alpha;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setAlpha(double)
+ */
+ @Override
+ public ModelLkState setAlpha(double alpha) {
+ this.alpha = alpha;
+ return this;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#getInv()
+ */
+ @Override
+ public double getInv() {
+ return inv;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.model.state.ModelLkState#setInv(double)
+ */
+ @Override
+ public ModelLkState setInv(double inv) {
+ this.inv = inv;
+ return this;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/state/ModelLkState.java b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelLkState.java
new file mode 100755
index 0000000..de34348
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/state/ModelLkState.java
@@ -0,0 +1,78 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.model.state;
+
+import java.io.Serializable;
+
+/**
+ * The Class ModelLkState defines the behavior of the model in relation to the
+ * likelihood value.
+ */
+public abstract class ModelLkState implements Serializable {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 2199513513876803640L;
+
+ /**
+ * Gets the likelihood of the model.
+ *
+ * @return the likelihood logarithm value.
+ */
+ public abstract double getLk();
+
+ /**
+ * Sets the likelihood of the model.
+ *
+ * @param lk the likelihood logarithm value.
+ *
+ * @return the new state of the model.
+ */
+ public abstract ModelLkState setLk(double lk);
+
+ /**
+ * Gets the alpha estimated value.
+ *
+ * @return the alpha estimated value
+ */
+ public abstract double getAlpha();
+
+ /**
+ * Sets the alpha estimated value.
+ *
+ * @param alpha the new alpha estimated value
+ *
+ * @return the new state
+ */
+ public abstract ModelLkState setAlpha(double alpha);
+
+ /**
+ * Gets the proportion of invariant sites.
+ *
+ * @return the proportion of invariant sites
+ */
+ public abstract double getInv();
+
+ /**
+ * Sets the proportion of invariant sites.
+ *
+ * @param inv the new proportion of invariant sites
+ *
+ * @return the new state
+ */
+ public abstract ModelLkState setInv(double inv);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/model/state/package.html b/src/main/java/es/uvigo/darwin/prottest/model/state/package.html
new file mode 100755
index 0000000..87f7e1b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/model/state/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+This state pattern allows to manage the optimization state of the models.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/observer/ModelUpdaterObserver.java b/src/main/java/es/uvigo/darwin/prottest/observer/ModelUpdaterObserver.java
new file mode 100755
index 0000000..5463523
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/observer/ModelUpdaterObserver.java
@@ -0,0 +1,40 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.observer;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * The observer interface for model update.
+ *
+ * @author Diego Darriba López
+ *
+ * @since 3.0
+ */
+public interface ModelUpdaterObserver {
+
+ /**
+ * Updates the observers.
+ *
+ * @param o the observable object
+ * @param model the updated model
+ * @param options the application options
+ */
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/observer/ObservableModelUpdater.java b/src/main/java/es/uvigo/darwin/prottest/observer/ObservableModelUpdater.java
new file mode 100755
index 0000000..d82a20e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/observer/ObservableModelUpdater.java
@@ -0,0 +1,83 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.observer;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * The observable class for model update.
+ *
+ * @author Diego Darriba López
+ *
+ * @since 3.0
+ */
+public abstract class ObservableModelUpdater {
+
+ /** Collection of observers */
+ private Collection<ModelUpdaterObserver> modelUpdaterObservers;
+
+ /**
+ * Constructor for observable objects.
+ */
+ public ObservableModelUpdater() {
+ modelUpdaterObservers = new ArrayList<ModelUpdaterObserver>();
+ }
+
+ /**
+ * Adds a new observer.
+ *
+ * @param o the observer
+ */
+ public void addObserver(ModelUpdaterObserver o) {
+ modelUpdaterObservers.add(o);
+ }
+
+ /**
+ * Removes an observer.
+ *
+ * @param o the observer
+ */
+ public void removeObserver(ModelUpdaterObserver o) {
+ modelUpdaterObservers.remove(o);
+ }
+
+ /**
+ * Notifies all observers.
+ */
+ public void notifyObservers() {
+ for (ModelUpdaterObserver o : modelUpdaterObservers) {
+ o.update(this, null, null);
+ }
+ }
+
+ /**
+ * Notifies all observers with a model an options
+ *
+ * @param model the substitution models
+ * @param options the application options
+ */
+ public void notifyObservers(Model model, ApplicationOptions options) {
+ for (ModelUpdaterObserver o : modelUpdaterObservers) {
+ o.update(this, model, options);
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/observer/package.html b/src/main/java/es/uvigo/darwin/prottest/observer/package.html
new file mode 100755
index 0000000..7400fc2
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/observer/package.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains a custom implementation of the <code>Observer</code> pattern for
+ProtTest-HPC.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/package.html b/src/main/java/es/uvigo/darwin/prottest/package.html
new file mode 100755
index 0000000..951bb31
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/package.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the main class of ProtTest-HPC console version. This is the main package and contains only
+the main class of ProtTest-HPC. Packages below this one contains all the model classes and the
+facades, and provides the whole functionality of the application.
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/AIC.java b/src/main/java/es/uvigo/darwin/prottest/selection/AIC.java
new file mode 100755
index 0000000..b4c976b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/AIC.java
@@ -0,0 +1,89 @@
+/*
+Copyright (C) 2009 David Posada
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.AICSelectionModel;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+
+/**
+ * The Akaike Information Criterion
+ *
+ * Description: AIC computation
+ * @author David Posada, University of Vigo, Spain
+ * dposada at uvigo.es | darwin.uvigo.es
+ */
+public class AIC extends InformationCriterion
+{
+
+// /**
+// * Instantiates a new Akaike Information Criterion.
+// *
+// * @param models the models
+// * @param confidenceInterval the confidence interval
+// */
+// public AIC (ModelCollection models, double confidenceInterval)
+// {
+// super(models, confidenceInterval);
+//
+// Collections.sort(selectionModels);
+// }
+
+ /**
+ * Instantiates a new Akaike Information Criterion.
+ *
+ * @param models the models
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public AIC (ModelCollection models, double confidenceInterval, double sampleSize)
+ {
+ super(models, confidenceInterval, sampleSize);
+
+ Collections.sort(selectionModels);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getSelectionModels(es.uvigo.darwin.prottest.util.collection.ModelIterator)
+ */
+ protected List<SelectionModel> getSelectionModels(List<Model> models) {
+ List<SelectionModel> list = new ArrayList<SelectionModel>();
+ for (Model model : models) {
+ SelectionModel toAdd = new AICSelectionModel(
+ model,
+ sampleSize);
+ list.add( toAdd );
+ hashModels.put(model, toAdd);
+ }
+ return list;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getCriterionName()
+ */
+ public String getCriterionName() {
+ return "AIC";
+ }
+}
+
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/AICc.java b/src/main/java/es/uvigo/darwin/prottest/selection/AICc.java
new file mode 100755
index 0000000..4bde77f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/AICc.java
@@ -0,0 +1,74 @@
+/*
+Copyright (C) 2009 David Posada
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.AICcSelectionModel;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+
+/**
+ * The Corrected Akaike Information Criterion.
+ * @author David Posada, University of Vigo, Spain
+ * dposada at uvigo.es | darwin.uvigo.es
+ */
+public class AICc extends InformationCriterion
+{
+
+ /**
+ * Instantiates a new Corrected Akaike Information Criterion.
+ *
+ * @param models the models
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public AICc (ModelCollection models, double confidenceInterval, double sampleSize)
+ {
+ super(models, confidenceInterval, sampleSize);
+
+ Collections.sort(selectionModels);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getSelectionModels(es.uvigo.darwin.prottest.util.collection.ModelIterator)
+ */
+ protected List<SelectionModel> getSelectionModels(List<Model> models) {
+ List<SelectionModel> list = new ArrayList<SelectionModel>();
+ for (Model model : models) {
+ SelectionModel toAdd = new AICcSelectionModel(
+ model,
+ sampleSize);
+ list.add( toAdd );
+ hashModels.put(model, toAdd);
+ }
+ return list;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getCriterionName()
+ */
+ public String getCriterionName() {
+ return "AICc";
+ }
+}
+
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/BIC.java b/src/main/java/es/uvigo/darwin/prottest/selection/BIC.java
new file mode 100755
index 0000000..87f043d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/BIC.java
@@ -0,0 +1,87 @@
+/*
+Copyright (C) 2009 David Posada
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.BICSelectionModel;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+
+/**
+ * The Bayesian Information Criterion.
+ * @author David Posada, University of Vigo, Spain
+ * dposada at uvigo.es | darwin.uvigo.es
+ */
+public class BIC extends InformationCriterion
+{
+
+// /**
+// * Instantiates a new Bayesian Information Criterion.
+// *
+// * @param models the models
+// * @param confidenceInterval the confidence interval
+// */
+// public BIC (ModelCollection models, double confidenceInterval)
+// {
+// super(models, confidenceInterval);
+//
+// Collections.sort(selectionModels);
+// }
+
+ /**
+ * Instantiates a new Bayesian Information Criterion.
+ *
+ * @param models the models
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public BIC (ModelCollection models, double confidenceInterval, double sampleSize)
+ {
+ super(models, confidenceInterval, sampleSize);
+
+ Collections.sort(selectionModels);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getSelectionModels(es.uvigo.darwin.prottest.util.collection.ModelIterator)
+ */
+ protected List<SelectionModel> getSelectionModels(List<Model> models) {
+ List<SelectionModel> list = new ArrayList<SelectionModel>();
+ for (Model model : models) {
+ SelectionModel toAdd = new BICSelectionModel(
+ model,
+ sampleSize);
+ list.add( toAdd );
+ hashModels.put(model, toAdd);
+ }
+ return list;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getCriterionName()
+ */
+ public String getCriterionName() {
+ return "BIC";
+ }
+}
+
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/DT.java b/src/main/java/es/uvigo/darwin/prottest/selection/DT.java
new file mode 100755
index 0000000..f24ddeb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/DT.java
@@ -0,0 +1,87 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.DTSelectionModel;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.tree.TreeDistancesCache;
+import es.uvigo.darwin.prottest.tree.TreeEuclideanDistancesCache;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+
+/**
+ * The Decision Theory Information Criterion.
+ *
+ * @author Diego Darriba
+ */
+public class DT extends InformationCriterion
+{
+
+ private BIC bic;
+ private TreeDistancesCache distancesCache;
+
+ /**
+ * Instantiates a new Decision Theory Information Criterion.
+ *
+ * @param models the models
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public DT (ModelCollection models, double confidenceInterval, double sampleSize)
+ {
+ super(models, confidenceInterval, sampleSize);
+ Collections.sort(selectionModels);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getSelectionModels(es.uvigo.darwin.prottest.util.collection.ModelIterator)
+ */
+ protected List<SelectionModel> getSelectionModels(List<Model> models) {
+ ModelCollection modelCollection = new SingleModelCollection(
+ models.toArray(new Model[0]),
+ alignment);
+ bic = new BIC(modelCollection, confidenceInterval, sampleSize);
+ distancesCache = TreeEuclideanDistancesCache.getInstance();
+
+ List<SelectionModel> list = new ArrayList<SelectionModel>();
+ for (Model model : models) {
+ SelectionModel toAdd = new DTSelectionModel(
+ model,
+ sampleSize,
+ bic,
+ distancesCache);
+ list.add( toAdd );
+ hashModels.put(model, toAdd);
+ }
+ return list;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getCriterionName()
+ */
+ public String getCriterionName() {
+ return "DT";
+ }
+}
+
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/InformationCriterion.java b/src/main/java/es/uvigo/darwin/prottest/selection/InformationCriterion.java
new file mode 100755
index 0000000..6867ed6
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/InformationCriterion.java
@@ -0,0 +1,423 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Random;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import java.util.ArrayList;
+import pal.alignment.Alignment;
+
+/**
+ * Generic implementation of an information criterion for model selection.
+ * Model selection is used to model-averaging and estimate parameter importance
+ * in an evolutionary context after computing likelihood values for every model.
+ */
+public abstract class InformationCriterion {
+
+ /** The best model according the concrete criterion. */
+ protected SelectionModel bestModel;
+ /** The models including some information about the criterion. */
+ protected List<SelectionModel> selectionModels;
+ /** HashMap to quick find the selection models. */
+ protected HashMap<Model, SelectionModel> hashModels;
+ /** The confidence interval. */
+ protected double confidenceInterval;
+ /** The set of models that fall into the confidence interval. */
+ protected List<SelectionModel> confidenceModels;
+ /** The cumulative weight of the parameter. */
+ protected double cumWeight;
+ /** The overall alpha value. */
+ protected double overallAlpha = 0.0;
+ /** The overall invariant value. */
+ protected double overallInv = 0.0;
+ /** The overall alpha + invariant value. */
+ protected double overallAlphaInv = 0.0;
+ /** The overall invariant + alpha value. */
+ protected double overallInvAlpha = 0.0;
+ /** The alpha parameter importance. */
+ protected double alphaImportance = 0.0;
+ /** The invariant parameter importance. */
+ protected double invImportance = 0.0;
+ /** The alpha + invariant parameter importance. */
+ protected double alphaInvImportance = 0.0;
+ /** The +F parameter importance. */
+ protected double fImportance = 0.0;
+ /** The sample size. */
+ protected double sampleSize;
+ /** The alignment */
+ protected Alignment alignment;
+
+ private boolean existInvModels = false,
+ existGammaModels = false,
+ existGammaInvModels = false,
+ existFModels = false;
+
+ public boolean isExistFModels() {
+ return existFModels;
+ }
+
+ public boolean isExistGammaInvModels() {
+ return existGammaInvModels;
+ }
+
+ public boolean isExistGammaModels() {
+ return existGammaModels;
+ }
+
+ public boolean isExistInvModels() {
+ return existInvModels;
+ }
+
+ /**
+ * Gets the overall alpha value.
+ *
+ * @return the overall alpha value
+ */
+ public double getOverallAlpha() {
+ return overallAlpha;
+ }
+
+ /**
+ * Gets the overall invariant value.
+ *
+ * @return the overall invariant value
+ */
+ public double getOverallInv() {
+ return overallInv;
+ }
+
+ /**
+ * Gets the overall alpha + invariant value.
+ *
+ * @return the overall alpha + invariant value
+ */
+ public double getOverallAlphaInv() {
+ return overallAlphaInv;
+ }
+
+ /**
+ * Gets the overall invariant + alpha value.
+ *
+ * @return the overall invariant + alpha value
+ */
+ public double getOverallInvAlpha() {
+ return overallInvAlpha;
+ }
+
+ /**
+ * Gets the alpha parameter importance.
+ *
+ * @return the alpha parameter importance
+ */
+ public double getAlphaImportance() {
+ return alphaImportance;
+ }
+
+ /**
+ * Gets the invariant parameter importance.
+ *
+ * @return the invariant parameter importance
+ */
+ public double getInvImportance() {
+ return invImportance;
+ }
+
+ /**
+ * Gets the alpha + invariant parameter importance.
+ *
+ * @return the alpha + invariant parameter importance
+ */
+ public double getAlphaInvImportance() {
+ return alphaInvImportance;
+ }
+
+ /**
+ * Gets the +F parameter importance.
+ *
+ * @return the +F parameter importance
+ */
+ public double getFImportance() {
+ return fImportance;
+ }
+
+ /**
+ * Gets the sample size.
+ *
+ * @return the sample size
+ */
+ public double getSampleSize() {
+ return sampleSize;
+ }
+
+ /**
+ * Gets the confidence interval value
+ *
+ * @return the confidence interval
+ */
+ public double getConfidenceInterval() {
+ return confidenceInterval;
+ }
+
+ /**
+ * Gets the list of selection models.
+ *
+ * @return the list of selection models
+ */
+ public List<SelectionModel> getSelectionModels() {
+ return selectionModels;
+ }
+
+ /**
+ * Instantiates a new model selection criterion.
+ *
+ * @param models the models to compute
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public InformationCriterion(ModelCollection models,
+ double confidenceInterval, double sampleSize) {
+ this.alignment = models.getAlignment();
+ this.sampleSize = sampleSize;
+ int numberOfModels = models.size();
+ this.confidenceInterval = confidenceInterval;
+ this.hashModels = new HashMap<Model, SelectionModel>(numberOfModels);
+ this.confidenceModels = new ArrayList<SelectionModel>();
+ this.selectionModels = getSelectionModels(models);
+ Collections.sort(selectionModels);
+ for (Model model : models) {
+ if (!existInvModels && model.isInv() && !model.isGamma()) {
+ existInvModels = true;
+ } else if (!existGammaModels && !model.isInv() && model.isGamma()) {
+ existGammaModels = true;
+ } else if (!existGammaInvModels && model.isInv() && model.isGamma()) {
+ existGammaInvModels = true;
+ } else if (!existFModels && model.isPlusF()) {
+ existFModels = true;
+ }
+ }
+ compute();
+ }
+
+ /**
+ * Gets the list of selection models.
+ *
+ * @param models the models to calculate the information criterion
+ *
+ * @return the list of models having the information about the concrete criterion
+ */
+ protected abstract List<SelectionModel> getSelectionModels(List<Model> models);
+
+ /**
+ * Computes the delta criterion, the weight and the cumulative weight of the criterion
+ * over the model collection.
+ */
+ private void compute() {
+ double minValue, sumExp, cum;
+
+ bestModel = selectionModels.get(0);
+ minValue = bestModel.getValue();
+
+ // Calculate differences
+ sumExp = 0;
+ for (SelectionModel model : selectionModels) {
+ model.setDeltaValue(
+ model.getValue() - minValue);
+ sumExp += Math.exp(-0.5 * model.getDeltaValue());
+ }
+
+ // Calculate weights
+ for (SelectionModel model : selectionModels) {
+ if (model.getDeltaValue() > 1000) {
+ model.setWeightValue(0.0);
+ } else {
+ model.setWeightValue(
+ Math.exp(-0.5 * model.getDeltaValue()) / sumExp);
+ }
+ }
+
+ // Calculate cumulative weights, overalls and parameters importance
+ cum = 0.0;
+ alphaImportance = 0.0;
+ invImportance = 0.0;
+ alphaInvImportance = 0.0;
+ fImportance = 0.0;
+ overallAlpha = 0.0;
+ overallInv = 0.0;
+ overallAlphaInv = 0.0;
+ overallInvAlpha = 0.0;
+ for (SelectionModel model : selectionModels) {
+ cum += model.getWeightValue();
+ model.setCumulativeWeightValue(cum);
+
+ if (model.getModel().isGamma() && model.getModel().isInv()) {
+ alphaInvImportance += model.getWeightValue();
+ overallAlphaInv += model.getWeightValue() * model.getModel().getAlpha();
+ overallInvAlpha += model.getWeightValue() * model.getModel().getInv();
+ } else if (model.getModel().isGamma()) {
+ alphaImportance += model.getWeightValue();
+ overallAlpha += model.getWeightValue() * model.getModel().getAlpha();
+ } else if (model.getModel().isInv()) {
+ invImportance += model.getWeightValue();
+ overallInv += model.getWeightValue() * model.getModel().getInv();
+ }
+ if (model.getModel().isPlusF()) {
+ fImportance += model.getWeightValue();
+ }
+ }
+
+ overallAlpha /= alphaImportance;
+ overallInv /= invImportance;
+ overallInvAlpha /= alphaInvImportance;
+ overallAlphaInv /= alphaInvImportance;
+
+ // confidence interval
+ buildConfidenceInterval();
+ }
+
+ /**
+ * Builds the confidence interval of selected models
+ * and their cumulative weight
+ *
+ * The model that just passed the confidence will be or not
+ * in the interval by chance (see below).
+ */
+ public void buildConfidenceInterval() {
+ confidenceModels = new ArrayList<SelectionModel>();
+
+ // first construct the confidence interval for models
+ if (confidenceInterval >= 1.0) {
+
+ for (SelectionModel model : selectionModels) {
+ model.setInConfidenceInterval(true);
+ confidenceModels.add(model);
+ }
+ cumWeight = 1.0;
+
+ } else {
+ cumWeight = 0.0;
+ SelectionModel lastModel = null;
+ for (SelectionModel model : selectionModels) {
+ if (model.getCumulativeWeightValue() <= confidenceInterval) {
+ confidenceModels.add(model);
+ cumWeight += model.getWeightValue();
+ } else {
+ lastModel = model;
+ break;
+ }
+ }
+
+ // lets decide whether the model that just passed the confidence
+ // interval should be included (suggested by John Huelsenbeck)
+ double probOut = (lastModel.getCumulativeWeightValue() - confidenceInterval) / lastModel.getWeightValue();
+ double probIn = 1.0 - probOut;
+ Random generator = new Random();
+ double randomNumber = generator.nextDouble();
+ if (randomNumber <= probIn) {
+ lastModel.setInConfidenceInterval(true);
+ confidenceModels.add(lastModel);
+ cumWeight += lastModel.getWeightValue();
+ } else {
+ lastModel.setInConfidenceInterval(false);
+ }
+ }
+ }
+
+ /**
+ * All iterator.
+ *
+ * @return the iterator< selection model>
+ */
+ public Iterator<SelectionModel> allIterator() {
+ return selectionModels.iterator();
+ }
+
+ /**
+ * Confidence collection.
+ *
+ * @return the collection of confidence selection models
+ */
+ public Collection<SelectionModel> getConfidenceModels() {
+ return confidenceModels;
+ }
+
+ /**
+ * Gets the model collection.
+ *
+ * @return the model collection
+ */
+ public ModelCollection getModelCollection() {
+ ModelCollection models = new SingleModelCollection(alignment);
+ for (SelectionModel model : confidenceModels) {
+ models.add(model.getModel());
+ }
+ return models;
+ }
+
+ /**
+ * Gets the SelectionModel in an specific position of the
+ * collection, sorted by this criterion value.
+ *
+ * @param index the index
+ *
+ * @return the SelectionModel
+ */
+ public SelectionModel get(int index) {
+ return selectionModels.get(index);
+ }
+
+ /**
+ * Gets the SelectionModel filled with this criterion data that
+ * wraps the specified model.
+ * @see SelectionModel
+ *
+ * @param model the model contained in the SelectionModel
+ *
+ * @return the SelectionModel that wraps the model
+ *
+ */
+ public SelectionModel get(Model model) {
+ return hashModels.get(model);
+ }
+
+ /**
+ * Gets the best model according with the concrete criterion.
+ * (i.e. the model with the lowest criterion value)
+ * @see SelectionModel#getValue()
+ *
+ * @return the best model
+ */
+ public Model getBestModel() {
+ return bestModel.getModel();
+ }
+
+ /**
+ * Gets the criterion name.
+ *
+ * @return the criterion name
+ */
+ public abstract String getCriterionName();
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/LNL.java b/src/main/java/es/uvigo/darwin/prottest/selection/LNL.java
new file mode 100755
index 0000000..d039356
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/LNL.java
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.model.LNLSelectionModel;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+
+/**
+ * The Maximum Likelihood Information Criterion.
+ */
+public class LNL extends InformationCriterion
+{
+
+ /**
+ * Instantiates a new Maximum Likelihood Information Criterion.
+ *
+ * @param models the models
+ * @param confidenceInterval the confidence interval
+ * @param sampleSize the sample size if different of the default
+ */
+ public LNL (ModelCollection models, double confidenceInterval, double sampleSize)
+ {
+ super(models, confidenceInterval, sampleSize);
+
+ Collections.sort(selectionModels);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getSelectionModels(es.uvigo.darwin.prottest.util.collection.ModelIterator)
+ */
+ protected List<SelectionModel> getSelectionModels(List<Model> models) {
+ List<SelectionModel> list = new ArrayList<SelectionModel>();
+ for (Model model : models) {
+ SelectionModel toAdd = new LNLSelectionModel(
+ model);
+ list.add( toAdd );
+ hashModels.put(model, toAdd);
+ }
+ return list;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.InformationCriterion#getCriterionName()
+ */
+ public String getCriterionName() {
+ return "LnL";
+ }
+}
+
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/AICSelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/AICSelectionModel.java
new file mode 100755
index 0000000..1aba79e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/AICSelectionModel.java
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * Model wrapper including information about Akaike Information Criterion
+ */
+public class AICSelectionModel extends SelectionModel {
+
+ /**
+ * Instantiates a new AIC selection model.
+ *
+ * @param model the underlying model
+ * @param sampleSize the sample size
+ */
+ public AICSelectionModel(Model model, double sampleSize) {
+ super(model, sampleSize);
+ this.value = -2 * model.getLk() + 2*model.getNumberOfModelParameters();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/AICcSelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/AICcSelectionModel.java
new file mode 100755
index 0000000..efd3395
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/AICcSelectionModel.java
@@ -0,0 +1,39 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * Model wrapper including information about corrected Akaike Information Criterion
+ */
+public class AICcSelectionModel extends SelectionModel {
+
+ /**
+ * Instantiates a new AICc selection model.
+ *
+ * @param model the underlying model
+ * @param sampleSize the sample size
+ */
+ public AICcSelectionModel(Model model, double sampleSize) {
+ super(model, sampleSize);
+ double k = model.getNumberOfModelParameters();
+ double n = sampleSize;
+ this.value = (-2 * model.getLk() + 2*k + 2*k*(k+1)/(n-k-1));
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/BICSelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/BICSelectionModel.java
new file mode 100755
index 0000000..830465c
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/BICSelectionModel.java
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * Model wrapper including information about Bayesian Information Criterion
+ */
+public class BICSelectionModel extends SelectionModel {
+
+ /**
+ * Instantiates a new BIC selection model.
+ *
+ * @param model the underlying model
+ * @param sampleSize the sample size
+ */
+ public BICSelectionModel(Model model, double sampleSize) {
+ super(model, sampleSize);
+ this.value = -2 * model.getLk() + model.getNumberOfModelParameters() * Math.log (sampleSize);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/DTSelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/DTSelectionModel.java
new file mode 100755
index 0000000..d8ddf17
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/DTSelectionModel.java
@@ -0,0 +1,54 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.BIC;
+import es.uvigo.darwin.prottest.tree.TreeDistancesCache;
+
+/**
+ * Model wrapper including information about Decision Theory Information Criterion
+ */
+public class DTSelectionModel extends SelectionModel {
+
+ /**
+ * Instantiates a new Decision Theory selection model.
+ *
+ * @param model the underlying model
+ * @param sampleSize the sample size
+ */
+ public DTSelectionModel(Model model, double sampleSize, BIC bic,
+ TreeDistancesCache distancesCache) {
+ super(model, sampleSize);
+
+ double minBIC = bic.get(bic.getBestModel()).getValue();
+ double sum = 0.0;
+ for (SelectionModel selectionModel : bic.getSelectionModels()) {
+ double distance = distancesCache.getDistance(model.getTree(), selectionModel.getModel().getTree());
+ if (distance > 0) {
+ double power = Math.log(distance) - selectionModel.getValue() + minBIC;
+ if (power > -30) {
+ sum += Math.exp(power);
+ }
+ }
+ }
+
+ this.value = sum;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/LNLSelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/LNLSelectionModel.java
new file mode 100755
index 0000000..7975235
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/LNLSelectionModel.java
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+/**
+ * Model wrapper including information about
+ * Likelihood Score Selection
+ */
+public class LNLSelectionModel extends SelectionModel {
+
+ /**
+ * Instantiates a new LnL selection model.
+ *
+ * @param model the underlying model
+ */
+ public LNLSelectionModel(Model model) {
+ super(model, 0.0);
+ this.value = -model.getLk();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/SelectionModel.java b/src/main/java/es/uvigo/darwin/prottest/selection/model/SelectionModel.java
new file mode 100755
index 0000000..7476cc8
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/SelectionModel.java
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.model;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+
+/**
+ * This class provides a Model wrapper including information about a concrete
+ * model selection criterion, like AIC, BIC or corrected AIC.
+ *
+ * @see Model
+ * @see InformationCriterion
+ */
+public abstract class SelectionModel implements Comparable<SelectionModel> {
+
+ /** The contained model. */
+ private Model model;
+
+ /** The sample size. */
+ protected double sampleSize;
+
+ /** The model selection absolute value. */
+ protected double value;
+
+ /** The model selection relative weight value. */
+ private double weightValue;
+
+ /** The model selection delta value. */
+ private double deltaValue;
+
+ /** The cumulative weight value, in relationship to
+ * the order of the models sorted by the model selection
+ * criterion. */
+ private double cumulativeWeightValue;
+
+ /** Model lays into the confidence interval */
+ private boolean inConfidenceInterval;
+
+ /**
+ * Gets the underlying model.
+ *
+ * @return the underlyingmodel
+ */
+ public Model getModel() { return model; }
+
+ /**
+ * Gets the model selection criterion value.
+ *
+ * @return the model selection criterion value
+ */
+ public double getValue() {
+ return value;
+ }
+
+ /**
+ * Gets the model selection relative weight value.
+ *
+ * @return the weight value
+ */
+ public double getWeightValue() {
+ return weightValue;
+ }
+
+ /**
+ * Sets the model selection relative weight value.
+ *
+ * @param weightValue the new weight value
+ */
+ public void setWeightValue(double weightValue) {
+ this.weightValue = weightValue;
+ }
+
+ /**
+ * Gets the model selection criterion delta value.
+ *
+ * @return the delta value
+ */
+ public double getDeltaValue() {
+ return deltaValue;
+ }
+
+ /**
+ * Sets the model selection criterion delta value.
+ *
+ * @param deltaValue the new delta value
+ */
+ public void setDeltaValue(double deltaValue) {
+ this.deltaValue = deltaValue;
+ }
+
+ /**
+ * Gets the cumulative weight value.
+ *
+ * @return the cumulative weight value
+ */
+ public double getCumulativeWeightValue() {
+ return cumulativeWeightValue;
+ }
+
+ /**
+ * Sets the cumulative weight value.
+ *
+ * @param cumulateWeightValue the new cumulative weight value
+ */
+ public void setCumulativeWeightValue(double cumulateWeightValue) {
+ this.cumulativeWeightValue = cumulateWeightValue;
+ }
+
+ /**
+ * Checks if model lays into the confidence interval.
+ *
+ * @return true, if is in confidence interval
+ */
+ public boolean isInConfidenceInterval() {
+ return inConfidenceInterval;
+ }
+
+ /**
+ * Sets the in confidence interval.
+ *
+ * @param inConfidenceInterval the new in confidence interval
+ */
+ public void setInConfidenceInterval(boolean inConfidenceInterval) {
+ this.inConfidenceInterval = inConfidenceInterval;
+ }
+
+ /**
+ * Instantiates a new selection model.
+ *
+ * @param model the underlying model
+ * @param sampleSize the sample size
+ */
+ public SelectionModel(Model model, double sampleSize) {
+ this.model = model;
+ this.sampleSize = sampleSize;
+ }
+
+ /* (non-Javadoc)
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ public int compareTo(SelectionModel other) {
+ if (this.value > other.value)
+ return 1;
+ else if (this.value < other.value)
+ return -1;
+ else
+ return 0;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/model/package.html b/src/main/java/es/uvigo/darwin/prottest/selection/model/package.html
new file mode 100755
index 0000000..1354326
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/model/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the wrapper classes for model selection.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/package.html b/src/main/java/es/uvigo/darwin/prottest/selection/package.html
new file mode 100755
index 0000000..6c73bec
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/package.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+This package contains all the information criteria. Every information
+criterion is implemented in two parts. At a lower level, a wrapper class
+contain the concrete substitution models plus the criterion information.
+At a higher level, classes like <code>AIC</code> or <code>BIC</code> manages
+the criterion calculation over a set of wrappers.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/printer/AminoAcidPrintFramework.java b/src/main/java/es/uvigo/darwin/prottest/selection/printer/AminoAcidPrintFramework.java
new file mode 100755
index 0000000..d6a9784
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/printer/AminoAcidPrintFramework.java
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.selection.printer;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class AminoAcidPrintFramework.
+ */
+public class AminoAcidPrintFramework extends PrintFramework {
+
+ /**
+ * Instantiates a new amino acid print framework.
+ */
+ public AminoAcidPrintFramework() {
+ super();
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.printer.PrintFramework#printRelativeImportance(java.io.PrintWriter)
+ */
+ @Override
+ void printRelativeImportance(InformationCriterion ic) {
+
+ println("***********************************************");
+ println("Relative importance of parameters");
+ println("***********************************************");
+ println(" alpha (+G): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getAlphaImportance(), PARAMETER_G, ic.isExistGammaModels()));
+ println(" p-inv (+I): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getInvImportance(), PARAMETER_I, ic.isExistInvModels()));
+ println(" alpha+p-inv (+I+G):" + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getAlphaInvImportance(), PARAMETER_IG, ic.isExistGammaInvModels()));
+ println(" freqs (+F): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getFImportance(), PARAMETER_F, ic.isExistFModels()));
+ println("");
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.selection.printer.PrintFramework#printModelAveragedEstimation(java.io.PrintWriter)
+ */
+ @Override
+ void printModelAveragedEstimation(InformationCriterion ic) {
+
+ println("***********************************************");
+ println("Model-averaged estimate of parameters");
+ println("***********************************************");
+ println(" alpha (+G): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getOverallAlpha(), PARAMETER_G, ic.isExistGammaModels()));
+ println(" p-inv (+I): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getOverallInv(), PARAMETER_I, ic.isExistInvModels()));
+ println(" alpha (+I+G): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getOverallAlphaInv(), PARAMETER_IG, ic.isExistGammaInvModels()));
+ println(" p-inv (+I+G): " + ProtTestFormattedOutput.space(3, ' ') + getDisplayValue(ic.getOverallInvAlpha(), PARAMETER_IG, ic.isExistGammaInvModels()));
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/printer/PrintFramework.java b/src/main/java/es/uvigo/darwin/prottest/selection/printer/PrintFramework.java
new file mode 100755
index 0000000..6153c08
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/printer/PrintFramework.java
@@ -0,0 +1,407 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.prottest.selection.printer;
+
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.IMPORTANCE_PRECISSION;
+
+import java.util.Collections;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.AIC;
+import es.uvigo.darwin.prottest.selection.AICc;
+import es.uvigo.darwin.prottest.selection.BIC;
+import es.uvigo.darwin.prottest.selection.DT;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.util.StatFramework;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.comparator.LKComparator;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+
+/**
+ * Utility to print application data into loggers.
+ */
+public abstract class PrintFramework {
+
+ /**
+ * Prints the models sorted by a concrete information criterion.
+ */
+ public final void printModelsSorted(
+ InformationCriterion informationCriterion) {
+
+ int fieldLength = 15;
+ int numberOfFields = 5;
+ int lineLength = fieldLength * numberOfFields;
+
+ Model bestModel = informationCriterion.getBestModel();
+ ModelCollection models = informationCriterion.getModelCollection();
+
+ String columns[] = new String[5];
+ columns[0] = "Model";
+ columns[1] = "delta" + informationCriterion.getCriterionName();
+ columns[2] = informationCriterion.getCriterionName();
+ columns[3] = informationCriterion.getCriterionName() + "w";
+ columns[4] = "-lnL";
+
+ println("");
+ println(ProtTestFormattedOutput.space(lineLength, '*'));
+ println("Best model according to "
+ + informationCriterion.getCriterionName() + ": "
+ + bestModel.getModelName());
+ double confPercent = informationCriterion.getConfidenceInterval() * 100;
+ println("Confidence Interval: " + confPercent);
+ println(ProtTestFormattedOutput.space(lineLength, '*'));
+ for (int i = 0; i < numberOfFields; i++) {
+ print(columns[i]);
+ print(ProtTestFormattedOutput.space(
+ fieldLength - columns[i].length(), ' '));
+ }
+ println("");
+ println(ProtTestFormattedOutput.space(lineLength, '-'));
+ for (Model model : models) {
+ print(model.getModelName());
+ print(ProtTestFormattedOutput.space(fieldLength
+ - model.getModelName().length(), ' '));
+
+ String decimal;
+
+ decimal = ProtTestFormattedOutput.getDecimalString(
+ informationCriterion.get(model).getDeltaValue(), 2);
+ print(decimal);
+ print(ProtTestFormattedOutput.space(fieldLength - decimal.length(),
+ ' '));
+ decimal = ProtTestFormattedOutput.getDecimalString(
+ informationCriterion.get(model).getValue(), 2);
+ print(decimal);
+ print(ProtTestFormattedOutput.space(fieldLength - decimal.length(),
+ ' '));
+ decimal = ProtTestFormattedOutput.getDecimalString(
+ informationCriterion.get(model).getWeightValue(), 2);
+ print(decimal);
+ print(ProtTestFormattedOutput.space(fieldLength - decimal.length(),
+ ' '));
+ decimal = ProtTestFormattedOutput.getDecimalString(
+ -1 * model.getLk(), 2);
+ print(decimal);
+ print(ProtTestFormattedOutput.space(fieldLength - decimal.length(),
+ ' '));
+
+ println("");
+ }
+
+ println(ProtTestFormattedOutput.space(lineLength, '-'));
+
+ println(ProtTestFormattedOutput.space(lineLength, '-'));
+
+ printRelativeImportance(informationCriterion);
+
+ printModelAveragedEstimation(informationCriterion);
+
+ }
+
+ protected static void print(String text) {
+ ProtTestLogger.getDefaultLogger().info(text);
+ }
+
+ protected static void println(String text) {
+ ProtTestLogger.getDefaultLogger().infoln(text);
+ }
+
+ /**
+ * Prints the comparison over the 7 frameworks.
+ */
+ public static void printFrameworksComparison(ModelCollection models) {
+
+ boolean includeI, includeG, includeIG, includeF;
+ includeI = includeG = includeIG = includeF = false;
+
+ double[] aic = new double[models.size()];
+ double[] aicc = new double[models.size()];
+ double[] bic = new double[models.size()];
+ double[] dt = new double[models.size()];
+
+ String[] modelNames = new String[models.size()];
+
+ InformationCriterion aicS = new AIC(models, 1.0, 0);
+ InformationCriterion aiccS = new AICc(models, 1.0, models.getAlignment().getSiteCount());
+ InformationCriterion bicS = new BIC(models, 1.0, models.getAlignment().getSiteCount());
+ InformationCriterion dtS = new DT(models, 1.0, models.getAlignment().getSiteCount());
+
+ Collections.sort(models, new LKComparator());
+ for (int i = 0; i < models.size(); i++) {
+ Model model = models.get(i);
+
+ includeI |= model.isInv();
+ includeG |= model.isGamma();
+ includeIG |= model.isInv() && model.isGamma();
+ includeF |= model.isPlusF();
+
+ modelNames[i] = model.getModelName();
+
+ aicc[i] = aiccS.get(model).getValue();
+ dt[i] = dtS.get(model).getValue();
+ bic[i] = bicS.get(model).getValue();
+ aic[i] = aicS.get(model).getValue();
+
+ }
+
+ StatFramework aicF, aiccF, bicF, dtF;
+ aicF = new StatFramework(aicS, "AIC", "AIC");
+ aiccF = new StatFramework(aiccS, "AICc",
+ "second-order AIC");
+ bicF = new StatFramework(bicS, "BIC", "BIC");
+ dtF = new StatFramework(dtS, "DT", "DT");
+
+
+ // Hala, ahora a imprimir:
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("Table: Weights(Ranking) of the candidate models under the different frameworks");
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("model AIC AICc BIC DT");
+ String model__, tmp;
+ for (int i = 0; i < models.size(); i++) {
+ model__ = aicF.getModelName(i);
+ print(model__
+ + ProtTestFormattedOutput.space(15 - model__.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getWeight(model__), 2)
+ + "(" + aicF.getRanking(model__) + ")";
+ print(ProtTestFormattedOutput.space(0 - tmp.length(), ' ') + tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getWeight(model__), 2)
+ + "(" + aiccF.getRanking(model__) + ")";
+ print(ProtTestFormattedOutput.space(0 - tmp.length(), ' ') + tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getWeight(model__), 2)
+ + "(" + bicF.getRanking(model__) + ")";
+ print(ProtTestFormattedOutput.space(0 - tmp.length(), ' ') + tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getWeight(model__), 2)
+ + "(" + dtF.getRanking(model__) + ")";
+ print(ProtTestFormattedOutput.space(0 - tmp.length(), ' ') + tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeG | includeI | includeIG | includeF) {
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("Relative importance of");
+ println("parameters AIC AICc BICc DT");
+ if (includeG) {
+ print("+G" + ProtTestFormattedOutput.space(13, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getAlphaImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getAlphaImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getAlphaImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getAlphaImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeI) {
+ print("+I" + ProtTestFormattedOutput.space(13, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getInvImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getInvImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getInvImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getInvImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeIG) {
+ print("+I+G" + ProtTestFormattedOutput.space(11, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(aicF.getGIImp(),
+ 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getGIImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getGIImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getGIImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeF) {
+ print("+F" + ProtTestFormattedOutput.space(13, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(aicF.getFImp(),
+ 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getFImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getFImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getFImp(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ }
+ if (includeG | includeI | includeIG) {
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("Model-averaged estimate of");
+ println("parameters AIC AICc BIC DT");
+ if (includeG) {
+ print("alpha (+G)" + ProtTestFormattedOutput.space(5, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getOverallAlpha(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getOverallAlpha(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getOverallAlpha(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getOverallAlpha(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeI) {
+ print("p-inv (+I)" + ProtTestFormattedOutput.space(5, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getOverallInv(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getOverallInv(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getOverallInv(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getOverallInv(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ if (includeIG) {
+ print("alpha (+I+G)" + ProtTestFormattedOutput.space(3, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getOverallAlphaGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getOverallAlphaGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getOverallAlphaGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getOverallAlphaGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ print("p-inv (+I+G)" + ProtTestFormattedOutput.space(3, ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aicF.getOverallInvGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ aiccF.getOverallInvGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ bicF.getOverallInvGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ tmp = ProtTestFormattedOutput.getDecimalString(
+ dtF.getOverallInvGI(), 2);
+ print(tmp
+ + ProtTestFormattedOutput.space(12 - tmp.length(), ' '));
+ println("");
+ }
+ }
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("AIC : Akaike Information Criterion framework.");
+ println("AICc : Second-Order Akaike framework.");
+ println("BIC : Bayesian Information Criterion framework.");
+ println("DT : Decision Theory Criterion framework.");
+ println(ProtTestFormattedOutput.space(100, '-'));
+ println("");
+ }
+
+ public static String getDisplayValue(double value, String parameter,
+ boolean existModels) {
+ String toDisplay;
+ if (existModels) {
+ toDisplay = ProtTestFormattedOutput.getDecimalString(value,
+ IMPORTANCE_PRECISSION);
+ } else {
+ toDisplay = "No " + parameter + " models";
+ }
+ return toDisplay;
+ }
+
+ /**
+ * Prints the relative importance.
+ *
+ * @param ic
+ * the information criterion
+ */
+ abstract void printRelativeImportance(InformationCriterion ic);
+
+ /**
+ * Prints the model averaged estimation.
+ *
+ * @param ic
+ * the information criterion
+ */
+ abstract void printModelAveragedEstimation(InformationCriterion ic);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/selection/printer/package.html b/src/main/java/es/uvigo/darwin/prottest/selection/printer/package.html
new file mode 100755
index 0000000..95661a2
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/selection/printer/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains classes which can display selection information.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/taxa/Taxon.java b/src/main/java/es/uvigo/darwin/prottest/taxa/Taxon.java
new file mode 100755
index 0000000..ab7d3b0
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/taxa/Taxon.java
@@ -0,0 +1,164 @@
+package es.uvigo.darwin.prottest.taxa;
+
+import es.uvigo.darwin.prottest.util.attributable.AttributableHelper;
+import es.uvigo.darwin.prottest.util.attributable.Attributable;
+import es.uvigo.darwin.prottest.util.fileio.*;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Andrew Rambaut
+ * @author Alexei Drummond
+ *
+ * @version $Id: Taxon.java 569 2006-12-12 18:48:36Z twobeers $
+ */
+public final class Taxon implements Attributable, Comparable {
+
+ /**
+ * A private constructor. Taxon objects can only be created by the static Taxon.getTaxon()
+ * factory method.
+ * @param name the name of the taxon
+ */
+ private Taxon(String name) {
+ this(name, null);
+ }
+
+ /**
+ * A private constructor. Taxon objects can only be created by the static Taxon.getTaxon()
+ * factory method.
+ * @param name the name of the taxon
+ */
+ private Taxon(String name, TaxonomicLevel taxonomicLevel) {
+ this.name = name;
+ this.taxonomicLevel = taxonomicLevel;
+ }
+
+ /**
+ * get the name of the taxon
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * get the taxonomic level of the taxon
+ * @return the taxonomic level
+ */
+ public TaxonomicLevel getTaxonomicLevel() {
+ return taxonomicLevel;
+ }
+
+ // Attributable IMPLEMENTATION
+
+ public void setAttribute(String name, Object value) {
+ if (helper == null) {
+ helper = new AttributableHelper();
+ }
+ helper.setAttribute(name, value);
+ }
+
+ public Object getAttribute(String name) {
+ if (helper == null) {
+ return null;
+ }
+ return helper.getAttribute(name);
+ }
+
+ public void removeAttribute(String name) {
+ if( helper != null ) {
+ helper.removeAttribute(name);
+ }
+ }
+
+ public Set<String> getAttributeNames() {
+ if (helper == null) {
+ return Collections.emptySet();
+ }
+ return helper.getAttributeNames();
+ }
+
+ public Map<String, Object> getAttributeMap() {
+ if (helper == null) {
+ return Collections.emptyMap();
+ }
+ return helper.getAttributeMap();
+ }
+
+ private AttributableHelper helper = null;
+
+ // Static factory methods
+
+ /**
+ * @return a Set containing all the currently created Taxon objects.
+ */
+ public static Set<Taxon> getAllTaxa() {
+ return Collections.unmodifiableSet(new HashSet<Taxon>(taxa.values()));
+ }
+
+ /**
+ * A static method that returns a Taxon object with the given name. If this has
+ * already been created then the same instance will be returned.
+ *
+ * Due to problems with the singleton model of taxa, this factory method now
+ * creates a new instance.
+ *
+ * @param name
+ * @return the taxon
+ */
+ public static Taxon getTaxon(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Illegal null string for taxon name");
+ }
+ if (name.length() == 0) {
+ throw new IllegalArgumentException("Illegal empty string for taxon name");
+ }
+
+ Taxon taxon = taxa.get(name);
+
+ if (taxon == null) {
+ taxon = new Taxon(name);
+ taxa.put(name, taxon);
+ }
+
+ return taxon;
+ }
+
+ // private members
+
+
+ /**
+ * The name of this taxon.
+ */
+ private final String name;
+
+ /**
+ * A hash map containing taxon name, object pairs.
+ */
+ private static Map<String, Taxon> taxa = new HashMap<String, Taxon>();
+
+ /**
+ * the taxonomic level of this taxon.
+ */
+ private final TaxonomicLevel taxonomicLevel;
+
+ public String toString() {
+ return name;
+ }
+
+ public int compareTo(Object o) {
+ return name.compareTo(((Taxon)o).getName());
+ }
+
+
+ public boolean equals(Taxon t) {
+ return name.equals(t.getName());
+ }
+
+ public int hashCode() {
+ return name.hashCode();
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/taxa/TaxonomicLevel.java b/src/main/java/es/uvigo/darwin/prottest/taxa/TaxonomicLevel.java
new file mode 100755
index 0000000..7b52ecb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/taxa/TaxonomicLevel.java
@@ -0,0 +1,69 @@
+package es.uvigo.darwin.prottest.taxa;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Andrew Rambaut
+ * @author Alexei Drummond
+ *
+ * @version $Id: TaxonomicLevel.java 185 2006-01-23 23:03:18Z rambaut $
+ */
+public class TaxonomicLevel {
+
+ /**
+ * A private constructor. TaxonomicLevel objects can only be created by the static TaxonomicLevel.getTaxonomicLevel()
+ * factory method.
+ * @param name the name of the taxonomic level
+ */
+ private TaxonomicLevel(String name) {
+ this.name = name;
+ }
+
+ /**
+ * get the name of the taxonomic level
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The name of this taxonomic level
+ */
+ private final String name;
+
+ // Static factory methods
+
+ /**
+ * A static method that returns a TaxonomicLevel object with the given name. If this has
+ * already been created then the same instance will be returned.
+ * @param name the name of the taxonomic level
+ * @return the taxonomic level object
+ */
+ public static TaxonomicLevel getTaxonomicLevel(String name) {
+ TaxonomicLevel taxonomicLevel = (TaxonomicLevel)taxonomicLevels.get(name);
+
+ if (taxonomicLevel == null) {
+ taxonomicLevel = new TaxonomicLevel(name);
+ taxonomicLevels.put(name, taxonomicLevel);
+ }
+
+ return taxonomicLevel;
+ }
+
+ /**
+ * Returns a Set containing all the currently created taxonomic levels.
+ * @return the set of taxonomic levels
+ */
+ public static Set getTaxonomicLevels() {
+ return Collections.unmodifiableSet(taxonomicLevels.entrySet());
+ }
+
+ /**
+ * A hash map containing name, object pairs.
+ */
+ private static Map<String, TaxonomicLevel> taxonomicLevels = new HashMap<String, TaxonomicLevel>();
+}
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/taxa/package.html b/src/main/java/es/uvigo/darwin/prottest/taxa/package.html
new file mode 100755
index 0000000..59c5870
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/taxa/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains classes related to taxa.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/tree/TreeDistancesCache.java b/src/main/java/es/uvigo/darwin/prottest/tree/TreeDistancesCache.java
new file mode 100755
index 0000000..6b3d88d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/tree/TreeDistancesCache.java
@@ -0,0 +1,157 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.tree;
+
+import java.util.Hashtable;
+
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+import pal.tree.Tree;
+
+/**
+ * Caches the distances between every couple of trees in a set. This is
+ * useful for instance when a tree-distance-based algorithm is computed
+ * many times, like the Decision Theory Information Criterion.
+ *
+ * This cache support both euclidean and RF distances.
+ *
+ * @author Diego Darriba López
+ *
+ * @since 3.0
+ */
+public class TreeDistancesCache {
+
+ /** Constant of the euclidean distances */
+ public static final int EUCLIDEAN = 1;
+ /** Constant of the RF distances */
+ public static final int ROBINSON_FOULDS = 2;
+ /** Cache hash table coupling each pair of trees with its distance */
+ private Hashtable<TreePair, Double> distances;
+ /** Sort of computed distance */
+ private int distanceType;
+
+ /**
+ * Gets the distance type.
+ *
+ * @return the sort of distance, according to the defined constants
+ */
+ public int getDistanceType() {
+ return distanceType;
+ }
+
+ /**
+ * Instantiates a new tree distances cache.
+ *
+ * @param distanceType sort of distance to compute
+ */
+ public TreeDistancesCache(int distanceType) {
+
+ if (distanceType != EUCLIDEAN && distanceType != ROBINSON_FOULDS) {
+ throw new ProtTestInternalException("Unsupported distance type");
+ }
+ this.distanceType = distanceType;
+ distances = new Hashtable<TreePair, Double>();
+
+ }
+
+ /**
+ * Gets the distance between two trees
+ *
+ * @param t1 the first tree
+ * @param t2 the second tree
+ *
+ * @return the distance
+ */
+ public double getDistance(Tree t1, Tree t2) {
+ double distance = 0.0;
+ TreePair tp = new TreePair(t1, t2);
+ if (distances.containsKey(tp)) {
+ distance = distances.get(tp);
+ } else {
+ switch (distanceType) {
+ case EUCLIDEAN:
+ distance = TreeUtils.euclideanTreeDistance(t1, t2);
+ break;
+ case ROBINSON_FOULDS:
+ distance = TreeUtils.robinsonFouldsTreeDistance(t1, t2);
+ break;
+ }
+ distances.put(tp, distance);
+ }
+ return distance;
+ }
+
+ /**
+ * This class represents a pair of trees
+ */
+ private class TreePair {
+
+ private Tree t1, t2;
+
+ public TreePair(Tree t1, Tree t2) {
+ this.t1 = t1;
+ this.t2 = t2;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + getOuterType().hashCode();
+ result = prime * result + ((t1 == null) ? 0 : t1.hashCode());
+ result = prime * result + ((t2 == null) ? 0 : t2.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ TreePair other = (TreePair) obj;
+ if (!getOuterType().equals(other.getOuterType())) {
+ return false;
+ }
+ if (t1 == null) {
+ if (other.t1 != null) {
+ return false;
+ }
+ } else if (!t1.equals(other.t1)) {
+ return false;
+ }
+ if (t2 == null) {
+ if (other.t2 != null) {
+ return false;
+ }
+ } else if (!t2.equals(other.t2)) {
+ return false;
+ }
+ return true;
+ }
+
+ private TreeDistancesCache getOuterType() {
+ return TreeDistancesCache.this;
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/tree/TreeEuclideanDistancesCache.java b/src/main/java/es/uvigo/darwin/prottest/tree/TreeEuclideanDistancesCache.java
new file mode 100755
index 0000000..469c49b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/tree/TreeEuclideanDistancesCache.java
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.tree;
+
+/**
+ * This class is a distances cache implementing the euclidean distance
+ *
+ * @author Diego Darriba
+ *
+ * @since 3.0
+ */
+public class TreeEuclideanDistancesCache extends TreeDistancesCache {
+
+ private static TreeEuclideanDistancesCache instance;
+
+ private TreeEuclideanDistancesCache() {
+ super(EUCLIDEAN);
+ }
+
+ public static TreeEuclideanDistancesCache getInstance() {
+
+ if (instance == null)
+ instance = new TreeEuclideanDistancesCache();
+ return instance;
+
+ }
+
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/tree/TreeUtils.java b/src/main/java/es/uvigo/darwin/prottest/tree/TreeUtils.java
new file mode 100755
index 0000000..e87ba6b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/tree/TreeUtils.java
@@ -0,0 +1,516 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.tree;
+
+import pal.tree.Node;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import pal.io.FormattedOutput;
+import pal.misc.IdGroup;
+import pal.misc.Identifier;
+import pal.misc.SimpleIdGroup;
+import pal.tree.NodeUtils;
+
+/**
+ * Some utils to phylogenetic tree analysis.
+ * Based on PAL library.
+ */
+public abstract class TreeUtils {
+
+ public static final int DEFAULT_COLUMN_WIDTH = 70;
+ public static final String TREE_WEIGHT_ATTRIBUTE = "weight";
+ public static final String TREE_CLADE_SUPPORT_ATTRIBUTE = "support";
+ public static final String TREE_NAME_ATTRIBUTE = "treeName";
+
+ /**
+ * Calculates the euclidean tree distance between two trees.
+ *
+ * @param t1 the first tree
+ * @param t2 the second tree
+ *
+ * @return the double
+ */
+ public static double euclideanTreeDistance(Tree t1, Tree t2) {
+ double sum = 0.0;
+ int numberOfInternalNodes = t1.getInternalNodeCount();
+ if (numberOfInternalNodes != t2.getInternalNodeCount()) {
+ throw new ProtTestInternalException("Different number of internal nodes: " +
+ t1.getInternalNodeCount() + " vs " + t2.getInternalNodeCount());
+ }
+ int numberOfExternalNodes = t1.getExternalNodeCount();
+ if (numberOfExternalNodes != t2.getExternalNodeCount()) {
+ throw new ProtTestInternalException("Different number of external nodes: " +
+ t1.getInternalNodeCount() + " vs " + t2.getInternalNodeCount());
+ }
+ for (int i = 0; i < numberOfInternalNodes; i++) {
+ double bl1 = t1.getInternalNode(i).getBranchLength();
+ double bl2 = t2.getInternalNode(i).getBranchLength();
+ sum += (bl1 - bl2) * (bl1 - bl2);
+ }
+ for (int i = 0; i < numberOfExternalNodes; i++) {
+ double bl1 = t1.getExternalNode(i).getBranchLength();
+ double bl2 = t2.getExternalNode(i).getBranchLength();
+ sum += (bl1 - bl2) * (bl1 - bl2);
+ }
+ return Math.sqrt(sum);
+ }
+
+ /**
+ * Calculates the Robinson-Foulds tree distance between two trees.
+ *
+ * @param t1 the first tree
+ * @param t2 the second tree
+ *
+ * @return the double
+ */
+ public static double robinsonFouldsTreeDistance(Tree t1, Tree t2) {
+ return pal.tree.TreeUtils.getRobinsonFouldsDistance(t1, t2);
+ }
+
+ //
+ /**
+ * Calculates the number of branches from node to most remote tip.
+ *
+ * @param node the starting node
+ *
+ * @return the node distance
+ */
+ public static int nodeDistance(final Node node) {
+ if (node.isLeaf()) {
+ return 0;
+ }
+
+ int d = 0;
+ for (int i = 0; i < node.getChildCount(); i++) {
+ Node n = node.getChild(i);
+ d = Math.max(d, nodeDistance(n));
+ }
+ return d + 1;
+ }
+
+ /**
+ * Calculates the safe node height.
+ *
+ * @param tree the tree
+ * @param node the node
+ *
+ * @return the height of the node
+ */
+ public static double safeNodeHeight(final Tree tree, final Node node) {
+ if (node.getNodeHeight() > 0.0) {
+ return node.getNodeHeight();
+ }
+ return TreeUtils.nodeDistance(node);
+ }
+
+ /**
+ * Make sure subtree below node has consistent heights, i.e. node height is higher than it's descendants
+ *
+ * @param tree the tree
+ * @param node the node
+ *
+ * @return height of node
+ */
+ public static double insureConsistency(Tree tree, Node node) {
+ double height = TreeUtils.safeNodeHeight(tree, node);
+ if (node.isLeaf()) {
+ return height;
+ } else {
+ for (int i = 0; i < node.getChildCount(); i++) {
+ Node n = node.getChild(i);
+ final double childHeight = insureConsistency(tree, n);
+ height = Math.max(height, childHeight);
+ }
+ }
+
+ node.setNodeHeight(height);
+ return height;
+ }
+
+ @Deprecated
+ public static int printNH(PrintWriter out, Tree tree,
+ boolean printLengths, boolean printInternalLabels,
+ boolean printCladeSupport) {
+ return printNH(out, tree, tree.getRoot(),
+ printLengths, printInternalLabels,
+ printCladeSupport,
+ 0, true, DEFAULT_COLUMN_WIDTH);
+ }
+
+ public static String toNewick(Tree tree, boolean printLengths,
+ boolean printInternalLabels, boolean printCladeSupport) {
+
+ StringWriter sw = new StringWriter();
+ PrintWriter mp = new PrintWriter(sw);
+
+ printNH(mp, tree, tree.getRoot(),
+ printLengths, printInternalLabels, printCladeSupport,
+ 0, false, -1);
+
+ sw.append(';');
+ return sw.toString();
+
+ }
+
+ @Deprecated
+ public static int printNH(PrintWriter out, Tree tree, Node node,
+ boolean printLengths, boolean printInternalLabels,
+ boolean printCladeSupport,
+ int column, boolean breakLines, int colWidth) {
+
+ if (breakLines) {
+ column = breakLine(out, column, colWidth);
+ }
+
+ if (!node.isLeaf()) {
+ out.print("(");
+ column++;
+
+ for (int i = 0; i < node.getChildCount(); i++) {
+ if (i != 0) {
+ out.print(",");
+ column++;
+ }
+
+ column = printNH(out, tree, node.getChild(i),
+ printLengths, printInternalLabels,
+ printCladeSupport,
+ column, breakLines, colWidth);
+ }
+
+ out.print(")");
+ column++;
+ }
+
+ if (!node.isRoot()) {
+ if (node.isLeaf() || printInternalLabels) {
+ if (breakLines) {
+ column = breakLine(out, column, colWidth);
+ }
+
+ String id = node.getIdentifier().toString();
+ out.print(id);
+ column += id.length();
+ }
+
+ if (printCladeSupport) {
+ if (tree.getAttribute(node, TREE_CLADE_SUPPORT_ATTRIBUTE) != null) {
+ double support = (Double) tree.getAttribute(node, TREE_CLADE_SUPPORT_ATTRIBUTE);
+ column += ProtTestFormattedOutput.displayDecimal(out, support, 2);
+ }
+ }
+
+ if (printLengths) {
+ out.print(":");
+ column++;
+
+ if (breakLines) {
+ column = breakLine(out, column, colWidth);
+ }
+
+ column += ProtTestFormattedOutput.displayDecimal(out, node.getBranchLength(), 6);
+ }
+ }
+
+ return column;
+ }
+
+ /**
+ * get list of the identifiers of the external nodes
+ *
+ * @return leaf identifier group
+ */
+ public static final IdGroup getLeafIdGroup(Tree tree) {
+ tree.createNodeList();
+
+ IdGroup labelList =
+ new SimpleIdGroup(tree.getExternalNodeCount());
+
+ for (int i = 0; i < tree.getExternalNodeCount(); i++) {
+ labelList.setIdentifier(i, tree.getExternalNode(i).getIdentifier());
+ }
+
+ return labelList;
+ }
+
+ private static int breakLine(PrintWriter out, int column, int colWidth) {
+ if (column > colWidth) {
+ out.println();
+ column = 0;
+ }
+
+ return column;
+ }
+
+ // Print picture of current tree in ASCII
+ public static void printASCII(Tree tree, PrintWriter out) {
+ FormattedOutput format = FormattedOutput.getInstance();
+
+ tree.createNodeList();
+
+ int numExternalNodes = tree.getExternalNodeCount();
+ int numInternalNodes = tree.getInternalNodeCount();
+ int numBranches = numInternalNodes + numExternalNodes - 1;
+
+ boolean[] umbrella = new boolean[numExternalNodes];
+ int[] position = new int[numExternalNodes];
+
+ int minLength = (Integer.toString(numBranches)).length() + 1;
+
+ int MAXCOLUMN = 40;
+ Node root = tree.getRoot();
+ if (root.getNodeHeight() == 0.0) {
+ NodeUtils.lengths2Heights(root);
+ }
+ double proportion = (double) MAXCOLUMN / root.getNodeHeight();
+
+ for (int n = 0; n < numExternalNodes; n++) {
+ umbrella[n] = false;
+ }
+
+ position[0] = 1;
+ for (int i = root.getChildCount() - 1; i > -1; i--) {
+ printNodeInASCII(out, root.getChild(i), 1, i, root.getChildCount(),
+ numExternalNodes, umbrella, position, proportion, minLength);
+ if (i != 0) {
+ putCharAtLevel(out, 0, '|', position);
+ out.println();
+ }
+ }
+ }
+
+ private static void printNodeInASCII(PrintWriter out, Node node, int level, int m, int maxm,
+ int numExternalNodes, boolean[] umbrella, int[] position, double proportion, int minLength) {
+ position[level] = (int) (node.getBranchLength() * proportion);
+
+ if (position[level] < minLength) {
+ position[level] = minLength;
+ }
+
+ if (node.isLeaf()) // external branch
+ {
+ if (m == maxm - 1) {
+ umbrella[level - 1] = true;
+ }
+
+ printlnNodeWithNumberAndLabel(out, node, level, numExternalNodes, umbrella, position);
+
+ if (m == 0) {
+ umbrella[level - 1] = false;
+ }
+ } else // internal branch
+ {
+ for (int n = node.getChildCount() - 1; n > -1; n--) {
+ printNodeInASCII(out, node.getChild(n), level + 1, n, node.getChildCount(),
+ numExternalNodes, umbrella, position, proportion, minLength);
+
+ if (m == maxm - 1 && n == node.getChildCount() / 2) {
+ umbrella[level - 1] = true;
+ }
+
+ if (n != 0) {
+ if (n == node.getChildCount() / 2) {
+ printlnNodeWithNumberAndLabel(out, node, level, numExternalNodes, umbrella, position);
+ } else {
+ for (int i = 0; i < level + 1; i++) {
+ if (umbrella[i]) {
+ putCharAtLevel(out, i, '|', position);
+ } else {
+ putCharAtLevel(out, i, ' ', position);
+ }
+ }
+ out.println();
+ }
+ }
+
+ if (m == 0 && n == node.getChildCount() / 2) {
+ umbrella[level - 1] = false;
+ }
+ }
+ }
+ }
+
+ private static void printlnNodeWithNumberAndLabel(PrintWriter out, Node node, int level,
+ int numExternalNodes, boolean[] umbrella, int[] position) {
+ for (int i = 0; i < level - 1; i++) {
+ if (umbrella[i]) {
+ putCharAtLevel(out, i, '|', position);
+ } else {
+ putCharAtLevel(out, i, ' ', position);
+ }
+ }
+
+ putCharAtLevel(out, level - 1, '+', position);
+
+ int branchNumber;
+ if (node.isLeaf()) {
+ branchNumber = node.getNumber() + 1;
+ } else {
+ branchNumber = node.getNumber() + 1 + numExternalNodes;
+ }
+
+ String numberAsString = Integer.toString(branchNumber);
+
+ int numDashs = position[level] - numberAsString.length();
+
+// String cladeSupport = "";
+// if (node instanceof AttributeNode && ((AttributeNode)node).getAttribute(TreeUtils.TREE_CLADE_SUPPORT_ATTRIBUTE) != null) {
+// double cladeSupportValue = (Double) ((AttributeNode)node).getAttribute(TreeUtils.TREE_CLADE_SUPPORT_ATTRIBUTE);
+// cladeSupport = ProtTestFormattedOutput.getDecimalString(cladeSupportValue, 1);
+// }
+//
+// numDashs -= cladeSupport.length();
+
+ for (int i = 0; i < numDashs ; i++) {
+ out.print('-');
+ }
+ out.print(numberAsString);
+
+ if (node.isLeaf()) {
+ out.println(" " + node.getIdentifier());
+ } else {
+ if (!node.getIdentifier().equals(Identifier.ANONYMOUS)) {
+ out.print("(" + node.getIdentifier() + ")");
+ }
+ out.println();
+ }
+ }
+
+ private static void putCharAtLevel(PrintWriter out, int level, char c,
+ int[] position) {
+ int n = position[level] - 1;
+ for (int i = 0; i < n; i++) {
+ out.print(' ');
+ }
+ out.print(c);
+ }
+
+ public static void printBranchInfo(Tree tree, PrintWriter out) {
+
+ //
+ // CALL PRINTASCII FIRST !!!
+ //
+
+ // check if some SE values differ from the default zero
+
+ int numExternalNodes = tree.getExternalNodeCount();
+ int numInternalNodes = tree.getInternalNodeCount();
+ int numBranches = numBranches = numInternalNodes + numExternalNodes - 1;
+
+ boolean showSE = false;
+ for (int i = 0; i < numExternalNodes && showSE == false; i++) {
+ if (tree.getExternalNode(i).getBranchLengthSE() != 0.0) {
+ showSE = true;
+ }
+ if (i < numInternalNodes - 1) {
+ if (tree.getInternalNode(i).getBranchLengthSE() != 0.0) {
+ showSE = true;
+ }
+ }
+ }
+
+ ProtTestFormattedOutput.displayIntegerWhite(out, numExternalNodes);
+ out.print(" Length ");
+ if (showSE) {
+ out.print("S.E. ");
+ }
+ out.print("Label ");
+ if (numInternalNodes > 1) {
+ ProtTestFormattedOutput.displayIntegerWhite(out, numBranches);
+ out.print(" Length ");
+ if (showSE) {
+ out.print("S.E. ");
+ }
+ out.print("Label");
+ }
+ out.println();
+
+ for (int i = 0; i < numExternalNodes; i++) {
+ ProtTestFormattedOutput.displayInteger(out, i + 1, numExternalNodes);
+ out.print(" ");
+ ProtTestFormattedOutput.displayDecimal(out, tree.getExternalNode(i).getBranchLength(), 5);
+ out.print(" ");
+ if (showSE) {
+ ProtTestFormattedOutput.displayDecimal(out, tree.getExternalNode(i).getBranchLengthSE(), 5);
+ out.print(" ");
+ }
+ ProtTestFormattedOutput.displayLabel(out, tree.getExternalNode(i).getIdentifier().getName(), 10);
+
+ if (i < numInternalNodes - 1) {
+ ProtTestFormattedOutput.multiplePrint(out, ' ', 5);
+ ProtTestFormattedOutput.displayInteger(out, i + 1 + numExternalNodes, numBranches);
+ out.print(" ");
+ ProtTestFormattedOutput.displayDecimal(out, tree.getInternalNode(i).getBranchLength(), 5);
+ out.print(" ");
+ if (showSE) {
+ ProtTestFormattedOutput.displayDecimal(out, tree.getInternalNode(i).getBranchLengthSE(), 5);
+ out.print(" ");
+ }
+ ProtTestFormattedOutput.displayLabel(out, tree.getInternalNode(i).getIdentifier().getName(), 10);
+ }
+
+ out.println();
+ }
+ }
+
+ // Print height information
+ public static void heightInfo(Tree tree, PrintWriter out) {
+
+ int numExternalNodes = tree.getExternalNodeCount();
+ int numInternalNodes = tree.getInternalNodeCount();
+ int numBranches = numExternalNodes + numInternalNodes - 1;
+
+ if (tree.getRoot().getNodeHeight() == 0.0) {
+ NodeUtils.lengths2Heights(tree.getRoot());
+ }
+
+ ProtTestFormattedOutput.displayIntegerWhite(out, numExternalNodes);
+ out.print(" Height ");
+ ProtTestFormattedOutput.displayIntegerWhite(out, numBranches);
+ out.print(" Height ");
+
+ out.println();
+
+ for (int i = 0; i < numExternalNodes; i++) {
+ ProtTestFormattedOutput.displayInteger(out, i + 1, numExternalNodes);
+ out.print(" ");
+ ProtTestFormattedOutput.displayDecimal(out, tree.getExternalNode(i).getNodeHeight(), 7);
+ out.print(" ");
+
+ if (i < numInternalNodes) {
+ ProtTestFormattedOutput.multiplePrint(out, ' ', 5);
+
+ if (i == numInternalNodes - 1) {
+ out.print("R");
+ ProtTestFormattedOutput.multiplePrint(out, ' ', Integer.toString(numBranches).length() - 1);
+ } else {
+ ProtTestFormattedOutput.displayInteger(out, i + 1 + numExternalNodes, numBranches);
+ }
+
+ out.print(" ");
+ ProtTestFormattedOutput.displayDecimal(out, tree.getInternalNode(i).getNodeHeight(), 7);
+ out.print(" ");
+ }
+
+ out.println();
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/tree/WeightedTree.java b/src/main/java/es/uvigo/darwin/prottest/tree/WeightedTree.java
new file mode 100755
index 0000000..f0c2fa2
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/tree/WeightedTree.java
@@ -0,0 +1,60 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.tree;
+
+import pal.tree.Tree;
+
+/**
+ * This class represents a weighted PAL Tree
+ *
+ * @author diego
+ */
+public class WeightedTree {
+
+ /** The tree. */
+ private Tree tree;
+ /** The weight. */
+ private double weight;
+
+ public Tree getTree() {
+ return tree;
+ }
+
+ public void setTree(Tree tree) {
+ this.tree = tree;
+ }
+
+ public double getWeight() {
+ return weight;
+ }
+
+ public void setWeight(double weight) {
+ this.weight = weight;
+ }
+
+ /**
+ * Instantiates a new weighted tree.
+ *
+ * @param tree the tree
+ * @param weight the weight
+ */
+ public WeightedTree(Tree tree, double weight) {
+ this.tree = tree;
+ this.weight = weight;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/tree/package.html b/src/main/java/es/uvigo/darwin/prottest/tree/package.html
new file mode 100755
index 0000000..b611f0d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/tree/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains utilites to manage phylogenetic trees.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/FixedBitSet.java b/src/main/java/es/uvigo/darwin/prottest/util/FixedBitSet.java
new file mode 100755
index 0000000..d2c8c67
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/FixedBitSet.java
@@ -0,0 +1,268 @@
+package es.uvigo.darwin.prottest.util;
+
+import java.util.Arrays;
+
+/**
+ * A bit-set of fixed size. Size is determined on creation.
+ *
+ * @author Joseph Heled
+ * @version $Id: FixedBitSet.java 591 2006-12-21 02:39:18Z pepster $
+ */
+public class FixedBitSet implements Comparable<FixedBitSet> {
+ int[] bits;
+ int size;
+ //private int intSize = Integer.SIZE;
+
+ private final static int ADDRESS_BITS_PER_UNIT = 5;
+ private final static int BITS_PER_UNIT = 1 << ADDRESS_BITS_PER_UNIT;
+ private final static int BIT_INDEX_MASK = BITS_PER_UNIT - 1;
+
+
+ private static int unitIndex(int bitIndex) {
+ return bitIndex >> ADDRESS_BITS_PER_UNIT;
+ }
+
+ private int countBits(int b) {
+ int sum = 0;
+
+ while (b != 0) {
+ // remove most significant bit
+ b = b & (b - 1);
+ ++sum;
+ }
+ return sum;
+ }
+
+ /**
+ * Given a bit index, return a unit that masks that bit in its unit.
+ * @return the mask
+ */
+ private static int bit(int bitIndex) {
+ return 1 << (bitIndex & BIT_INDEX_MASK);
+ }
+
+ public FixedBitSet(int size) {
+ this.size = size;
+ bits = new int[(unitIndex(size - 1) + 1)];
+ }
+
+ public FixedBitSet(FixedBitSet bs) {
+ bits = bs.bits.clone();
+ size = bs.size;
+ }
+
+
+ public void set(int position) {
+ int unitIndex = unitIndex(position);
+ bits[unitIndex] |= bit(position);
+ }
+
+ public void clear(int position) {
+ int unitIndex = unitIndex(position);
+ bits[unitIndex] &= ~bit(position);
+ }
+
+ /**
+ * @param bitset
+ * @return true if bitset contains this set (this <= bitset)
+ */
+ public boolean setInclusion(final FixedBitSet bitset) {
+ for (int k = 0; k < bits.length; ++k) {
+ if (bits[k] != (bits[k] & bitset.bits[k])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void union(FixedBitSet b) {
+ for (int k = 0; k < Math.min(bits.length, b.bits.length); ++k) {
+ bits[k] |= b.bits[k];
+ }
+ }
+
+ public void intersect(FixedBitSet b) {
+ for (int k = 0; k < Math.min(bits.length, b.bits.length); ++k) {
+ bits[k] &= b.bits[k];
+ }
+ }
+
+ public void setMinus(FixedBitSet b) {
+ for (int k = 0; k < Math.min(bits.length, b.bits.length); ++k) {
+ bits[k] &= ~b.bits[k];
+ }
+ }
+
+ public int intersectCardinality(FixedBitSet b) {
+ int c = 0;
+ for (int k = 0; k < Math.min(bits.length, b.bits.length); ++k) {
+ c += countBits(bits[k] & b.bits[k]);
+ }
+ return c;
+ }
+
+ public static FixedBitSet complement(FixedBitSet b) {
+ FixedBitSet t = new FixedBitSet(b);
+ t.complement();
+ return t;
+ }
+
+ public void complement() {
+ int k;
+ for (k = 0; k < bits.length - 1; ++k) {
+ bits[k] = ~ bits[k];
+ }
+
+ bits[k] = ~bits[k];
+ // reset all higher order bits
+ final int mask = bit(size) - 1;
+ if( mask != 0 ) {
+ bits[k] &= mask;
+ }
+ }
+
+ private final static byte firstBitLocation[] = {
+ -1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
+
+ private int firstOnBit(int i) {
+ for (int k = 0; k < 4; ++k) {
+ char b = (char) (i & 0xff);
+ if (b != 0) {
+ return 8 * k + firstBitLocation[b];
+ }
+ i = i >> 8;
+ }
+ return -1;
+ }
+
+ /**
+ * Iteration helper. A typical iteration on set bits might be
+ * FixedBitSet b;
+ * for(int i = b.nextOnBit(0); i >= 0; i = b.nextOnBit(i+1)) ...
+ *
+ * @param fromIndex
+ * @return Next set member whose index is >= fromIndex. -1 if none.
+ */
+ public int nextOnBit(int fromIndex) {
+ int u = unitIndex(fromIndex);
+ int testIndex = (fromIndex & BIT_INDEX_MASK);
+ int unit = bits[u] >> testIndex;
+
+ if (unit == 0) {
+ testIndex = 0;
+
+ while ((unit == 0) && (u < bits.length - 1))
+ unit = bits[++u];
+ }
+
+ if (unit == 0)
+ return -1;
+
+ testIndex += firstOnBit(unit);
+ return ((u * BITS_PER_UNIT) + testIndex);
+ }
+
+ public int cardinality() {
+ int sum = 0;
+ for (int b : bits) {
+ sum += countBits(b);
+ }
+ return sum;
+ }
+
+ public boolean contains(final int i) {
+ final int unitIndex = unitIndex(i);
+ return (bits[unitIndex] & bit(i)) != 0;
+ }
+
+ @Override
+ public int hashCode() {
+ int code = 0;
+
+ for (int bit : bits) {
+ code = code ^ bit;
+ }
+ return code;
+ }
+
+ @Override
+ public boolean equals(Object x) {
+ if (x instanceof FixedBitSet) {
+ final FixedBitSet b = (FixedBitSet) x;
+
+ return b.size == size && Arrays.equals(bits, b.bits);
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder rep = new StringBuilder();
+ rep.append("{");
+ for (int b = 0; b < size; ++b) {
+ if (contains(b)) {
+ if (rep.length() > 0) {
+ rep.append("," + b);
+ } else {
+ rep.append("" + b);
+ }
+ }
+ }
+ rep.append("}");
+ return rep.toString();
+ }
+
+ public String splitRepresentation() {
+ StringBuilder rep = new StringBuilder();
+ for (int b = 0; b < size; ++b) {
+ if (contains(b)) {
+ rep.append("*");
+ }
+ else {
+ rep.append("-");
+ }
+ }
+ return rep.toString();
+ }
+
+ public int compareTo(FixedBitSet fbs) {
+ int minSize;
+ int defaultValue;
+ if (size < fbs.size) {
+ minSize = size;
+ defaultValue = -1;
+ } else {
+ minSize = fbs.size;
+ if (size == fbs.size)
+ defaultValue = 0;
+ else
+ defaultValue = 1;
+ }
+
+ for (int i = 0; i < minSize; i++) {
+ if (this.contains(i) && !fbs.contains(i)) {
+ return -1;
+ }
+ if (!this.contains(i) && fbs.contains(i)) {
+ return 1;
+ }
+ }
+ return defaultValue;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/ProtTestAlignment.java b/src/main/java/es/uvigo/darwin/prottest/util/ProtTestAlignment.java
new file mode 100755
index 0000000..5f176e3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/ProtTestAlignment.java
@@ -0,0 +1,177 @@
+/*
+Copyright (C) 2009 Diego Darriba, Federico Abascal
+
+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
+ */
+package es.uvigo.darwin.prottest.util;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import java.io.PrintWriter;
+
+import pal.alignment.Alignment;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+
+/**
+ * The Class ProtTestAlignment provides some operations about Alignment, as
+ * could be the empirical frequencies or the sample size calculation.
+ *
+ * @author Federico Abascal
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public abstract class ProtTestAlignment {
+
+ /**
+ * Calculate sample size.
+ *
+ * @param alignment
+ * the alignment to calculate sample size
+ * @return the sample size
+ */
+ public static double calculateSampleSize(Alignment alignment) {
+ // For AICc and BIC frameworks
+ return alignment.getSiteCount();
+ }
+
+ /**
+ * Calculate invariable sites.
+ *
+ * @param alignment
+ * the alignment
+ * @param verbose
+ * the verbose
+ *
+ * @return the int
+ */
+ public static int calculateInvariableSites(Alignment alignment,
+ boolean verbose) {
+ // use this function to estimate a good starting value for the
+ // InvariableSites distribution.
+ int numSites = alignment.getSiteCount();
+ int numSeqs = alignment.getSequenceCount();
+ int inv = 0;
+ int tmp;
+ boolean tmpInv = true;
+ for (int i = 0; i < numSites; i++) {
+ tmp = indexOfChar(alignment.getData(0, i));
+ tmpInv = true;
+ for (int j = 0; j < numSeqs; j++) {
+ if (indexOfChar(alignment.getData(j, i)) != tmp) { // if at
+ // least one
+ // difference
+ // in column
+ // i:
+ j = numSeqs; // we exit this for.
+ tmpInv = false; // i is not an invariable site.
+ }
+ }
+ if (tmpInv)
+ inv++;
+ }
+ if (verbose)
+ System.out.println("Observed number of invariant sites: " + inv);
+ return inv;
+ }
+
+ /**
+ * Gets the frequencies.
+ *
+ * @param alignment
+ * the alignment
+ *
+ * @return the frequencies
+ */
+ public static double[] getFrequencies(Alignment alignment) {
+ int numSites = alignment.getSiteCount();
+ int numSeqs = alignment.getSequenceCount();
+ double freqs[] = new double[AMINOACID_NUM_STATES];
+ int aas[] = new int[AMINOACID_NUM_STATES];
+ int total_aas = 0;
+ for (int i = 0; i < AMINOACID_NUM_STATES; i++)
+ aas[i] = 0;
+
+ for (int i = 0; i < numSites; i++)
+ for (int j = 0; j < numSeqs; j++) {
+ int index = indexOfChar(alignment.getData(j, i));
+ if (index >= 0) {
+ aas[index]++;
+ total_aas++;
+ }
+ }
+
+ for (int i = 0; i < AMINOACID_NUM_STATES; i++)
+ freqs[i] = (double) aas[i] / (double) total_aas;
+
+ return freqs;
+ }
+
+ /**
+ * Prints the frequencies.
+ *
+ * @param freqs
+ * the freqs
+ * @param out
+ * the out
+ */
+ public static void printFrequencies(double[] freqs, PrintWriter out) {
+
+ out.println("Observed aminoacid frequencies:");
+ for (int i = 0; i < AMINOACID_NUM_STATES; i++) {
+ char aa = charOfIndex(i);
+ out.print(" " + aa + ": "
+ + ProtTestFormattedOutput.getDecimalString(freqs[i], 3)
+ + " ");
+ if ((i + 1) % 5 == 0)
+ out.println("");
+ }
+ }
+
+ /**
+ * Char of index.
+ *
+ * @param c
+ * the c
+ *
+ * @return the char
+ */
+ public static char charOfIndex(int c) {
+ char[] charSet = { 'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L',
+ 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y' };
+ if (c >= 0 && c <= charSet.length)
+ return charSet[c];
+ else {
+ return '?';
+ }
+ }
+
+ /**
+ * Index of char.
+ *
+ * @param c
+ * the c
+ *
+ * @return the int
+ */
+ private static int indexOfChar(char c) {
+ char[] charSet = { 'A', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'K', 'L',
+ 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'V', 'W', 'Y' };
+ for (int charIndex = 0; charIndex < charSet.length; charIndex++)
+ if (charSet[charIndex] == c)
+ return charIndex;
+
+ return -1;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/StatFramework.java b/src/main/java/es/uvigo/darwin/prottest/util/StatFramework.java
new file mode 100755
index 0000000..e6527cd
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/StatFramework.java
@@ -0,0 +1,141 @@
+/*
+Copyright (C) 2004 Federico Abascal
+
+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.
+*/
+package es.uvigo.darwin.prottest.util;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+
+public class StatFramework {
+ //recibe los delta.
+ //ordena los datos y calcula los pesos
+ //guarda las cosas en un hash
+ //implementa métodos para dar el ranking y el peso a partir del String modelName
+ //implementa métodos para dar el modelName y el peso a partir del ranking
+
+ private HashMap<String, Integer> hashSorted; //clave: nombre modelo, valor: ranking
+ private HashMap<Integer, String> hashSortedReverse; //clave: raking, valor: nombre
+ private HashMap<String, Double> hashWeights; //clave: nombre modelo, valor: peso
+ private HashMap<String, Double> hashDeltas; //clave: nombre modelo, valor delta
+ private String framework;
+ private String description;
+ private double alphaImp = 0.0;
+ private double invImp = 0.0;
+ private double GIImp = 0.0;
+ private double FImp = 0.0;
+ private double overallAlpha = 0.0;
+ private double overallInv = 0.0;
+ private double overallAlphaGI = 0.0;
+ private double overallInvGI = 0.0;
+ private String[] names;
+
+ public StatFramework (InformationCriterion ic, String framework, String description) {
+ this.framework = framework;
+ this.description = description;
+ alphaImp = ic.getAlphaImportance();//calculateAlphaImp (ic, false);
+ invImp = ic.getInvImportance(); //calculateInvImp (ic, false);
+ GIImp = ic.getAlphaInvImportance();//calculateAlphaImp (ic, true );
+ FImp = ic.getFImportance();//calculateFImp (ic);
+ overallAlpha = ic.getOverallAlpha();//calculateOverallAlpha(ic, false);
+ overallInv = ic.getOverallInv();//calculateOverallInv (ic, false);
+ overallAlphaGI = ic.getOverallAlphaInv();//calculateOverallAlpha(ic, true );
+ overallInvGI = ic.getOverallInvAlpha();//calculateOverallInv (ic, true );
+ initHashes (ic, names);
+ }
+
+ private void initHashes (InformationCriterion ic, String[] names) {
+ hashSorted = new HashMap<String, Integer>(); //clave: nombre modelo, valor ranking
+ hashSortedReverse = new HashMap<Integer, String>(); //clave: raking, valor: nombre
+ hashWeights = new HashMap<String, Double>(); //clave: nombre modelo, valor peso
+ hashDeltas = new HashMap<String, Double>(); //clave: nombre modelo, valor delta
+ Iterator<SelectionModel> selectionModels = ic.allIterator();
+ int position = 0;
+ while (selectionModels.hasNext()) {
+ SelectionModel model = selectionModels.next();
+ hashSorted.put (model.getModel().getModelName(), new Integer(position));
+ hashSortedReverse.put(new Integer(position),model.getModel().getModelName());
+ hashWeights.put (model.getModel().getModelName(), new Double(model.getWeightValue()));
+ hashDeltas.put (model.getModel().getModelName(), new Double(model.getDeltaValue()));
+ position++;
+ }
+ }
+
+ public int getRanking (String modelName) {
+ return hashSorted.get(modelName).intValue()+1;
+ }
+
+ public double getWeight (String modelName) {
+ return hashWeights.get(modelName).doubleValue();
+ }
+
+ public double getDelta (String modelName) {
+ return hashDeltas.get(modelName).doubleValue();
+ }
+
+ public String getModelName (int ranking) {
+ return hashSortedReverse.get(new Integer(ranking));
+ }
+
+ public String getFramework () {
+ return framework;
+ }
+
+ public String getDescription () {
+ return description;
+ }
+
+ public double getAlphaImp() {
+ return alphaImp;
+ }
+
+ public double getInvImp() {
+ return invImp;
+ }
+
+ public double getGIImp() {
+ return GIImp;
+ }
+
+ public double getFImp() {
+ return FImp;
+ }
+
+ public double getOverallAlpha() {
+ return overallAlpha;
+ }
+
+ public double getOverallInv() {
+ return overallInv;
+ }
+
+ public double getOverallAlphaGI() {
+ return overallAlphaGI;
+ }
+
+ /**
+ * Gets the overall inv gi.
+ *
+ * @return the overall inv gi
+ */
+ public double getOverallInvGI() {
+ return overallInvGI;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/Utilities.java b/src/main/java/es/uvigo/darwin/prottest/util/Utilities.java
new file mode 100755
index 0000000..d2a7a71
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/Utilities.java
@@ -0,0 +1,299 @@
+/*
+Copyright (C) 2004 Federico Abascal
+
+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
+*/
+package es.uvigo.darwin.prottest.util;
+
+import java.net.URL;
+import java.util.StringTokenizer;
+
+/**
+ * The Class Utilities.
+ */
+public class Utilities {
+
+ /**
+ * Instantiates a new utilities.
+ */
+ public Utilities() { }
+
+ /**
+ * Last token.
+ *
+ * @param str the str
+ *
+ * @return the string
+ */
+ public static String lastToken (String str) {
+ StringTokenizer st = new StringTokenizer(str);
+ String token = "";
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ }
+ return token;
+ }
+
+ /**
+ * Next token.
+ *
+ * @param str the string
+ * @param previousToken the previous token
+ *
+ * @return the next token
+ */
+ public static String nextToken (String str, String previousToken) {
+ StringTokenizer st = new StringTokenizer(str);
+ String token = "";
+ while (st.hasMoreTokens()) {
+ token = st.nextToken();
+ if (token.equals(previousToken))
+ return st.nextToken();
+ }
+ return null;
+ }
+
+ /**
+ * Checks if is windows.
+ *
+ * @return true, if is windows
+ */
+ public static boolean isWindows () {
+ if(System.getProperty("os.name").startsWith("Window"))
+ return true;
+ return false;
+ }
+
+ /**
+ * Gets the average.
+ *
+ * @param meassures the meassures
+ *
+ * @return the average
+ */
+ public static long getAverage(long[] meassures) {
+ double avg = 0;
+ for (long value : meassures)
+ avg += value;
+ avg /= meassures.length;
+ return Math.round(avg);
+ }
+
+ /**
+ * Gets the max.
+ *
+ * @param meassures the meassures
+ *
+ * @return the max
+ */
+ public static long getMax(long[] meassures) {
+ long max = Long.MIN_VALUE;
+ for (long value : meassures) {
+ if (value > max)
+ max = value;
+ }
+ return max;
+ }
+
+ /**
+ * Gets the min.
+ *
+ * @param meassures the meassures
+ *
+ * @return the min
+ */
+ public static long getMin(long[] meassures) {
+ long min = Long.MAX_VALUE;
+ for (long value : meassures) {
+ if (value < min)
+ min = value;
+ }
+ return min;
+ }
+
+ /**
+ * Arrange runtime.
+ *
+ * @param runTime the run time
+ *
+ * @return the string
+ */
+ public static String arrangeRuntime(long runTime) {
+ long seconds = (long) Math.round(runTime/1000.0);
+ int hours = (int ) (seconds/(60.0*60.0));
+ int rest1 = (int ) (seconds%(60.0*60.0));
+ int minutes = (int ) (rest1/60.0);
+ seconds = (int ) (seconds - (hours*60*60 + minutes*60));
+ String h = "" + hours;
+ String m = "" + minutes;
+ String s = "" + seconds;
+ if(minutes < 10)
+ m = "0"+m;
+ if(seconds < 10)
+ s = "0"+s;
+ return h + "h:" + m + ":" + s + "";
+ }
+
+ /**
+ * Calculate runtime.
+ *
+ * @param startTime the start time
+ * @param endTime the end time
+ *
+ * @return the string
+ */
+ public static String calculateRuntime(long startTime, long endTime) {
+ return arrangeRuntime(endTime - startTime);
+ }
+
+ /**
+ * Gets the path.
+ *
+ * @return the path
+ */
+ public static String getPath () {
+ return (new Utilities()).internalGetPath(false);
+ }
+
+ /**
+ * Gets the uRL path.
+ *
+ * @return the uRL path
+ */
+ public static String getURLPath () {
+ return (new Utilities()).internalGetPath(true);
+ }
+
+ /**
+ * Internal get path.
+ *
+ * @param withFile the with file
+ *
+ * @return the string
+ */
+ private String internalGetPath (boolean withFile) {
+ //ClassLoader loader = this.getClass().getClassLoader();
+ //URL tmp = loader.getResource("./");
+ String j = null;
+ URL tmp = null;
+ try {
+ //tmp = XProtTest.class.getResource("");
+ tmp = getClass().getResource("");
+ } catch (Exception e) {
+ System.err.println(e);
+ e.printStackTrace();
+ return null;
+ }
+ if(tmp == null) {
+ System.err.println("***************************************************************");
+ System.err.println("** ERROR: Cannot find ProtTest's path, unable to run phyml!! **");
+ System.err.println("***************************************************************");
+ //prottest.setValue(-1);
+ return null;
+ } else {
+ j = tmp.getPath();
+ j = replace(j, "%20", " ");
+ //j = tmp.getPath().replaceAll("%20", " ");
+ //System.err.println("j: " + j);
+ if(!withFile) {
+ if(isWindows())
+ j = replace(j, "file:/", "");
+ else
+ j = replace(j, "file:" , "");
+ }
+ //j = Pattern.compile("file:").matcher(j).replaceFirst("");
+ //j = j.replaceFirst("file:", "");
+ //System.err.println("after replaceFirst: " + j);
+ //j = Pattern.compile("!.*$").matcher(j).replaceFirst("");
+ int last2 = j.lastIndexOf("!");
+ j = j.substring(0, last2);
+ //j = j.replaceFirst("!.*$", "");
+ //System.err.println("after replaceFirst2: " + j);
+ int last = j.lastIndexOf("/");
+ //j = j.replaceFirst("/.*?.jar$", "");
+ j = j.substring(0, last);
+ //System.err.println("after replaceFirst3: " + j);
+ }
+ return j;
+ }
+
+ /**
+ * Quote it.
+ *
+ * @param orig the orig
+ *
+ * @return the string
+ */
+ public static String quoteIt (String orig) {
+ //quote spaces (or other characters) of filenames:
+ String result = replace(orig, " " , "\\ ");
+ //orig = replace(orig, "\\\\ ", "\\ ");
+ return result;
+ }
+
+ //I took this method from SkeetUtil ( http://www.yoda.arachsys.com/java/skeetutil/ )
+ /**
+ * Replace.
+ *
+ * @param orig the orig
+ * @param from the from
+ * @param to the to
+ *
+ * @return the string
+ */
+ public static String replace (String orig, String from, String to) {
+ int fromLength = from.length();
+
+ if (fromLength==0)
+ throw new IllegalArgumentException
+ ("String to be replaced must not be empty");
+
+ int start = orig.indexOf (from);
+ if (start==-1)
+ return orig;
+
+ boolean greaterLength = (to.length() >= fromLength);
+
+ StringBuffer buffer;
+ // If the "to" parameter is longer than (or
+ // as long as) "from", the final length will
+ // be at least as large
+ if (greaterLength) {
+ if (from.equals (to))
+ return orig;
+ buffer = new StringBuffer(orig.length());
+ }
+ else {
+ buffer = new StringBuffer();
+ }
+
+ char [] origChars = orig.toCharArray();
+
+ int copyFrom=0;
+ while (start != -1) {
+ buffer.append (origChars, copyFrom, start-copyFrom);
+ buffer.append (to);
+ copyFrom=start+fromLength;
+ start = orig.indexOf (from, copyFrom);
+ }
+ buffer.append (origChars, copyFrom, origChars.length-copyFrom);
+
+ return buffer.toString();
+ }
+
+ public static double round(double value, int decimals) {
+ return (Math.round(value * Math.pow(10, decimals)))/Math.pow(10, decimals);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/WriterOutputStream.java b/src/main/java/es/uvigo/darwin/prottest/util/WriterOutputStream.java
new file mode 100755
index 0000000..4e1e4e9
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/WriterOutputStream.java
@@ -0,0 +1,87 @@
+// ========================================================================
+// Copyright (c) 1999 Mort Bay Consulting (Australia) Pty. Ltd.
+// $Id: WriterOutputStream.java,v 1.1 2003/02/13 22:39:19 mpowers Exp $
+// ========================================================================
+
+package es.uvigo.darwin.prottest.util;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+
+/* ------------------------------------------------------------ */
+/** Wrap a Writer as an OutputStream.
+ * When all you have is a Writer and only an OutputStream will do.
+ * Try not to use this as it indicates that your design is a dogs
+ * breakfast (JSP made me write it).
+ * @version 1.0 Tue Feb 12 2002
+ * @author Greg Wilkins (gregw)
+ */
+public class WriterOutputStream extends OutputStream
+{
+ protected Writer _writer;
+ protected String _encoding;
+ private byte[] _buf=new byte[1];
+
+ /* ------------------------------------------------------------ */
+ public WriterOutputStream(Writer writer, String encoding)
+ {
+ _writer=writer;
+ _encoding=encoding;
+ }
+
+ /* ------------------------------------------------------------ */
+ public WriterOutputStream(Writer writer)
+ {
+ _writer=writer;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void close()
+ throws IOException
+ {
+ _writer.close();
+ _writer=null;
+ _encoding=null;
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void flush()
+ throws IOException
+ {
+ _writer.flush();
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void write(byte[] b)
+ throws IOException
+ {
+ if (_encoding==null)
+ _writer.write(new String(b));
+ else
+ _writer.write(new String(b,_encoding));
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void write(byte[] b, int off, int len)
+ throws IOException
+ {
+ if (_encoding==null)
+ _writer.write(new String(b,off,len));
+ else
+ _writer.write(new String(b,off,len,_encoding));
+ }
+
+ /* ------------------------------------------------------------ */
+ public synchronized void write(int b)
+ throws IOException
+ {
+ _buf[0]=(byte)b;
+ write(_buf);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/AminoAcidArgumentParser.java b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/AminoAcidArgumentParser.java
new file mode 100755
index 0000000..5413a2e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/AminoAcidArgumentParser.java
@@ -0,0 +1,98 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.argumentparser;
+
+import es.uvigo.darwin.prottest.global.ApplicationGlobals;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+import java.util.Properties;
+
+/**
+ * The Class AminoAcidArgumentParser.
+ */
+public class AminoAcidArgumentParser extends ProtTestArgumentParser {
+
+ /** Amino-Acid model matrices to include in the analysis. */
+ public static final List<String> PARAM_MATRICES;
+
+ /** Include models with all matrices (like -JTT -LG -etc,). */
+ public static final String PARAM_ALL_MATRICES = "all-matrices";
+
+ static {
+ ApplicationGlobals apGlobals = ProtTestFactory.getInstance().getApplicationGlobals();
+ PARAM_MATRICES = apGlobals.getSupportedMatrices();
+ Map<String, String> allMatrices = new HashMap<String, String>(PARAM_MATRICES.size());
+ for (String matrix : PARAM_MATRICES) {
+ valuesRequired.put(matrix, false);
+ allMatrices.put(matrix, "T");
+ }
+ valuesRequired.put(PARAM_ALL_MATRICES, false);
+ specialArguments.put(PARAM_ALL_MATRICES, allMatrices);
+ }
+
+ /**
+ * Instantiates a new amino-acid argument parser.
+ *
+ * @param args the command line arguments
+ * @param options the application options
+ *
+ * @throws IllegalArgumentException when exists some error in the command line argument
+ */
+ public AminoAcidArgumentParser(String[] args, ApplicationOptions options)
+ throws IllegalArgumentException {
+ super(args, options);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser#getMatrices()
+ */
+ public List<String> getMatrices() {
+ return PARAM_MATRICES;
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser#getMatrices()
+ */
+ protected Properties checkArgs(String[] args)
+ throws IllegalArgumentException {
+
+ // set all-matrices as default
+ boolean existMatrix = false;
+ int index = 0;
+ String modArgs[] = new String[args.length + 1];
+ for (String arg : args) {
+ if (PARAM_MATRICES.contains(arg.substring(1))) {
+ existMatrix = true;
+ }
+ modArgs[index] = arg;
+ index++;
+ }
+ if (!existMatrix) {
+ modArgs[index] = "-" + PARAM_ALL_MATRICES;
+ } else {
+ modArgs = args;
+ }
+
+ return super.checkArgs(modArgs);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/ProtTestArgumentParser.java b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/ProtTestArgumentParser.java
new file mode 100755
index 0000000..8da7836
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/ProtTestArgumentParser.java
@@ -0,0 +1,293 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.argumentparser;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import es.uvigo.darwin.prottest.global.ProtTestConsoleParameters;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+
+/**
+ * The Class ModelTestArgumentParser.
+ */
+public abstract class ProtTestArgumentParser
+ implements ProtTestConsoleParameters {
+
+
+ /** Hashtable to associate parameter tokens within parameter localArguments requirements. */
+ protected static final HashMap<String, Boolean> valuesRequired;
+ /** Hashtable to associate parameter tokens within parameter localArguments range. */
+ protected static final HashMap<String, String[]> argumentValues;
+ /** Hashtable to handle special localArguments like "all-distributions". */
+ protected static final HashMap<String, Map<String, String>> specialArguments;
+ /** The default APPLICATION_PROPERTIES. */
+ private static final Properties defaultProperties;
+ /** The argument prefix. */
+ public static final String ARG_TOKEN = "-";
+ /** The command line localArguments. */
+ private Properties arguments;
+
+ static {
+
+ valuesRequired = new HashMap<String, Boolean>();
+ argumentValues = new HashMap<String, String[]>();
+ specialArguments = new HashMap<String, Map<String, String>>();
+ valuesRequired.put(PARAM_ALIGNMENT_FILE, true);
+ valuesRequired.put(PARAM_OUTPUT_FILE, true);
+ valuesRequired.put(PARAM_TREE_FILE, true);
+ String[] optimizationStrategies = new String[OPTIMIZE_VALUES.length];
+ for (int index = 0; index < OPTIMIZE_VALUES.length; index++) {
+ optimizationStrategies[index] = String.valueOf(OPTIMIZE_VALUES[index]);
+ }
+ valuesRequired.put(PARAM_OPTIMIZATION_STRATEGY, true);
+ argumentValues.put(PARAM_OPTIMIZATION_STRATEGY, optimizationStrategies);
+
+ String[] treeSearchOps = {
+ TREE_SEARCH_NNI,
+ TREE_SEARCH_SPR,
+ TREE_SEARCH_BEST
+ };
+ String[] enabling = {
+ "enabled",
+ "disabled"
+ };
+
+ valuesRequired.put(PARAM_TREE_SEARCH_OP, true);
+ argumentValues.put(PARAM_TREE_SEARCH_OP, treeSearchOps);
+
+ valuesRequired.put(PARAM_NUM_THREADS, true);
+ valuesRequired.put(PARAM_ALL_FRAMEWORK_COMPARISON, false);
+ valuesRequired.put(PARAM_DISPLAY_NEWICK_TREE, false);
+ valuesRequired.put(PARAM_DISPLAY_ASCII_TREE, false);
+ valuesRequired.put(PARAM_DISPLAY_CONSENSUS_TREE, true);
+ valuesRequired.put(PARAM_PLUSF, false);
+ valuesRequired.put(PARAM_PLUSI, false);
+ valuesRequired.put(PARAM_PLUSG, false);
+ valuesRequired.put(PARAM_PLUSIG, false);
+ valuesRequired.put(PARAM_NCAT, true);
+ valuesRequired.put(PARAM_ALL_DISTRIBUTIONS, false);
+ valuesRequired.put(PARAM_VERBOSE, false);
+ valuesRequired.put(PARAM_DO_AIC, false);
+ valuesRequired.put(PARAM_DO_BIC, false);
+ valuesRequired.put(PARAM_DO_AICC, false);
+ valuesRequired.put(PARAM_DO_DT, false);
+ valuesRequired.put(PARAM_LOGGING, true);
+ argumentValues.put(PARAM_LOGGING, enabling);
+ Map<String, String> distributionsMap = new HashMap<String, String>(3);
+ distributionsMap.put(PARAM_PLUSG, "T");
+ distributionsMap.put(PARAM_PLUSI, "T");
+ distributionsMap.put(PARAM_PLUSIG, "T");
+ specialArguments.put(PARAM_ALL_DISTRIBUTIONS, distributionsMap);
+
+ defaultProperties = new Properties();
+
+ defaultProperties.setProperty(PARAM_NUM_THREADS, String.valueOf(DEFAULT_THREADS));
+ defaultProperties.setProperty(PARAM_NCAT, String.valueOf(DEFAULT_NCAT));
+ defaultProperties.setProperty(PARAM_OPTIMIZATION_STRATEGY, String.valueOf(DEFAULT_STRATEGY_MODE));
+ defaultProperties.setProperty(PARAM_DATA_TYPE, DATA_TYPE_AMINOACID);
+ }
+
+ /**
+ * Instantiates a new model test argument parser.
+ *
+ * @param args the command line localArguments
+ * @param options the application options
+ *
+ * @throws IllegalArgumentException when exists some error in the command line argument
+ */
+ public ProtTestArgumentParser(String[] args, ApplicationOptions options)
+ throws IllegalArgumentException {
+
+ arguments = checkArgs(args);
+
+ if (!(exists(PARAM_DO_BIC) || exists(PARAM_DO_AIC)
+ || exists(PARAM_DO_AICC) || exists(PARAM_DO_DT))) {
+ putArgument(PARAM_DO_BIC, "T", arguments);
+ }
+
+ options.fillIn(this);
+ }
+
+ /**
+ * Check localArguments are grammatically correct and parse them into
+ * the instance.
+ *
+ * @param args the command line localArguments
+ *
+ * @return the argument APPLICATION_PROPERTIES
+ *
+ * @throws IllegalArgumentException when exists some error in the command line argument
+ */
+ protected Properties checkArgs(String[] args)
+ throws IllegalArgumentException {
+
+ Properties localArguments = new Properties(defaultProperties);
+ int i = 0;
+ while (i < args.length) {
+
+ String arg = args[i];
+ if (!arg.startsWith(ARG_TOKEN)) {
+ System.err.print("Command line: ");
+ for (String simpleArg : args) {
+ System.err.print(simpleArg + " ");
+ }
+ System.err.println(" ");
+ throw new IllegalArgumentException("Arguments must start with \"-\". The ofending argument was: " + arg);
+ }
+
+ arg = arg.substring(ARG_TOKEN.length());
+ if (valuesRequired.containsKey(arg)) {
+ if (valuesRequired.get(arg)) {
+ if (i + 1 < args.length) {
+ i++;
+ String value = args[i];
+ if (argumentValues.containsKey(arg)) {
+ String[] values = argumentValues.get(arg);
+ if (!Arrays.asList(values).contains(value.toLowerCase())) {
+ throw new IllegalArgumentException("Invalid argument value " + value + " for parameter " + arg);
+ }
+ }
+
+ // special cases
+ if (specialArguments.containsKey(arg)) {
+ Map<String, String> mapValues = specialArguments.get(arg);
+ for (String key : mapValues.keySet()) {
+ if (mapValues.get(key).equals("?")) {
+ mapValues.put(key, value);
+ }
+ }
+ putArgument(mapValues, localArguments);
+ } else {
+ putArgument(arg, value, localArguments);
+ }
+ } else {
+ IllegalArgumentException e = new IllegalArgumentException("Parameter " + arg + " requires a value");
+ throw e;
+ }
+ } else {
+ if (specialArguments.containsKey(arg)) {
+ Map<String, String> mapValues = specialArguments.get(arg);
+ putArgument(mapValues, localArguments);
+ } else {
+ putArgument(arg, "T", localArguments);
+ }
+ }
+ } else {
+ // Obsolete arguments checking...
+ if (arg.equals("-sort")) {
+ System.err.println(" WARNING! \"sort\" argument is obsolete since 3.2 version. You should use one or more of the following instead: -AIC -AICC -BIC -DT");
+ }
+ throw new IllegalArgumentException("Invalid argument " + arg);
+ }
+ i++;
+ }
+
+ return localArguments;
+
+ }
+
+ /**
+ * Checks if a concrete argument exists in the application.
+ *
+ * @param arg the argument to check
+ *
+ * @return true, if the argument has a value
+ */
+ public boolean exists(String arg) {
+ return arguments.containsKey(arg);
+ }
+
+ /**
+ * Checks if a boolean argument is set in the application.
+ * The method will return false if the boolean argument
+ * is set to 'false', the argument is not boolean or the
+ * argument does not exist in the argument list.
+ *
+ * @param arg the argument to check
+ *
+ * @return true, if the boolean argument is set to 'true'
+ */
+ public boolean isSet(String arg) {
+ boolean isSet;
+ try {
+ isSet = arguments.get(arg).equals("T");
+ } catch (NullPointerException npe) {
+ isSet = false;
+ }
+ return isSet;
+ }
+
+ /**
+ * Gets the value of an argument. If the argument key is not found,
+ * the default localArguments will be checked. If the argument key does
+ * not exist, the method will return null.
+ *
+ * @param arg the argument to check
+ *
+ * @return the argument value
+ */
+ public String getValue(String arg) {
+ return arguments.getProperty(arg);
+ }
+
+ /**
+ * Puts an argument into the argument list, with specified key and value.
+ * If the argument was already set to a certain value, the argument will
+ * take the new value, and a warning message will be printed into
+ * standard error output.
+ *
+ * @param key the argument key
+ * @param value the argument value
+ * @param localArguments the argument list
+ */
+ private void putArgument(String key, String value, Properties arguments) {
+ if (arguments.containsKey(key)) {
+ System.err.println("WARNING! Repeated argument \"" + key + "\". New value is " + value);
+ }
+ arguments.setProperty(key, value);
+ }
+
+ /**
+ * Puts a set of couples argument-value into the argument list.
+ * For each argument that was already set to a certain value, the
+ * argument will take the new value, and a warning message will be
+ * printed into standard error output.
+ *
+ * @param items the new localArguments to put
+ * @param localArguments the argument list
+ */
+ private void putArgument(Map<String, String> items, Properties arguments) {
+ // localArguments.putAll(items);
+ for (String key : items.keySet()) {
+ putArgument(key, items.get(key), arguments);
+ }
+ }
+
+ /**
+ * Gets the matrix name list of all supported matrices.
+ *
+ * @return the matrix name list
+ */
+ public abstract List<String> getMatrices();
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/package.html b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/package.html
new file mode 100755
index 0000000..1649080
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/argumentparser/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+This classes allow to manage application arguments from command console.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/attributable/Attributable.java b/src/main/java/es/uvigo/darwin/prottest/util/attributable/Attributable.java
new file mode 100755
index 0000000..c8ae584
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/attributable/Attributable.java
@@ -0,0 +1,57 @@
+package es.uvigo.darwin.prottest.util.attributable;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.Collection;
+import java.util.HashSet;
+
+/**
+ * Interface for associating attributeNames with an object.
+ *
+ * @version $Id: Attributable.java 575 2006-12-14 15:49:14Z twobeers $
+ *
+ * @author Andrew Rambaut
+ */
+public interface Attributable {
+
+ /**
+ * Sets an named attribute for this object.
+ * @param name the name of the attribute.
+ * @param value the new value of the attribute.
+ */
+ void setAttribute(String name, Object value);
+
+ /**
+ * @return an object representing the named attributed for this object.
+ * @param name the name of the attribute of interest, or null if the attribute doesn't exist.
+ */
+ Object getAttribute(String name);
+
+ /**
+ * @param name name of attribute to remove
+ */
+ void removeAttribute(String name);
+
+ /**
+ * @return an array of the attributeNames that this object has.
+ */
+ Set<String> getAttributeNames();
+
+ /**
+ * Gets the entire attribute map.
+ * @return an unmodifiable map
+ */
+ Map<String, Object> getAttributeMap();
+
+ public static class Utils {
+ Set<String> getAttributeNames(Collection<Attributable> attributables) {
+ Set<String> names = new HashSet<String>();
+
+ for (Attributable attributable : attributables) {
+ names.addAll(attributable.getAttributeNames());
+ }
+
+ return names;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/attributable/AttributableHelper.java b/src/main/java/es/uvigo/darwin/prottest/util/attributable/AttributableHelper.java
new file mode 100755
index 0000000..62e8594
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/attributable/AttributableHelper.java
@@ -0,0 +1,41 @@
+package es.uvigo.darwin.prottest.util.attributable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author rambaut
+ * Date: Nov 27, 2005
+ * Time: 1:31:50 PM
+ */
+public class AttributableHelper implements Attributable {
+
+ @Override
+ public void setAttribute(String name, Object value) {
+ attributeMap.put(name, value);
+ }
+
+ @Override
+ public Object getAttribute(String name) {
+ return attributeMap.get(name);
+ }
+
+ @Override
+ public void removeAttribute(String name) {
+ attributeMap.remove(name);
+ }
+
+ @Override
+ public Set<String> getAttributeNames() {
+ return attributeMap.keySet();
+ }
+
+ @Override
+ public Map<String, Object> getAttributeMap() {
+ return Collections.unmodifiableMap(attributeMap);
+ }
+
+ Map<String, Object> attributeMap = new HashMap<String, Object>();
+}
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/attributable/package.html b/src/main/java/es/uvigo/darwin/prottest/util/attributable/package.html
new file mode 100755
index 0000000..6709700
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/attributable/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+This hierarchy allows a single class to support attributes.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/CheckPointManager.java b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/CheckPointManager.java
new file mode 100755
index 0000000..97ec8e3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/CheckPointManager.java
@@ -0,0 +1,185 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.checkpoint;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.Arrays;
+import java.util.Comparator;
+
+import es.uvigo.darwin.prottest.util.checkpoint.status.ApplicationStatus;
+
+public class CheckPointManager {
+
+ private ApplicationStatus lastCheckpoint;
+ private File snapshotDir;
+ private File snapshotFile;
+ private boolean cpEnabled;
+ private final String SNAPSHOT_PREFIX = "SNAPSHOT";
+ private final String SNAPSHOT_SUFFIX = "snp";
+
+ public ApplicationStatus getLastCheckpoint() {
+ return lastCheckpoint;
+ }
+
+ public CheckPointManager() {
+ String snapshotDirName = APPLICATION_PROPERTIES.getProperty("snapshot_dir");
+ cpEnabled = snapshotDirName != null;
+ if (cpEnabled) {
+ snapshotDir = new File(snapshotDirName);
+ if (!snapshotDir.exists()) {
+ snapshotDir.mkdirs();
+ }
+ }
+ }
+
+ public synchronized boolean setStatus(ApplicationStatus newCheckpoint) {
+ if (cpEnabled) {
+ // check integrity
+ boolean validStatus = (lastCheckpoint == null || lastCheckpoint.isCompatible(newCheckpoint));
+
+ if (validStatus) {
+ lastCheckpoint = newCheckpoint;
+ saveStatus(lastCheckpoint);
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private synchronized void saveStatus(ApplicationStatus checkpoint) {
+
+ if (cpEnabled) {
+ try {
+ if (snapshotFile == null) {
+ // create new Snapshot file
+ snapshotFile = File.createTempFile(
+ SNAPSHOT_PREFIX, SNAPSHOT_SUFFIX, snapshotDir);
+ }
+
+ if (snapshotFile.exists()) {
+ snapshotFile.delete();
+ }
+ snapshotFile.createNewFile();
+
+ FileOutputStream fos = new FileOutputStream(snapshotFile);
+ ObjectOutputStream out = new ObjectOutputStream(fos);
+ out.writeObject(checkpoint);
+ out.close();
+ fos.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+ @SuppressWarnings("unchecked")
+ public boolean loadStatus(ApplicationStatus initialStatus) {
+
+ boolean loaded = false;
+ if (cpEnabled) {
+ if (snapshotDir != null && snapshotDir.exists() && snapshotDir.canRead()) {
+ FilenameFilter filter = new FilenameFilter() {
+
+ @Override
+ public boolean accept(File dir, String name) {
+
+ return name.startsWith(SNAPSHOT_PREFIX) && name.endsWith(SNAPSHOT_SUFFIX);
+ }
+ };
+ File[] snapshotFiles = snapshotDir.listFiles(filter);
+ Arrays.sort(snapshotFiles, new Comparator() {
+
+ public int compare(Object o1, Object o2) {
+
+ if (((File) o1).lastModified() > ((File) o2).lastModified()) {
+ return -1;
+ } else if (((File) o1).lastModified() < ((File) o2).lastModified()) {
+ return +1;
+ } else {
+ return 0;
+ }
+ }
+ });
+
+ ObjectInputStream in = null;
+ for (File statusFile : snapshotFiles) {
+ try {
+ //Construct the ObjectInputStream object
+ in = new ObjectInputStream(new FileInputStream(statusFile));
+
+ Object obj = null;
+
+ obj = in.readObject();
+
+ if (obj instanceof ApplicationStatus) {
+ if (initialStatus.isCompatible((ApplicationStatus) obj)) {
+ this.snapshotFile = statusFile;
+ this.lastCheckpoint = (ApplicationStatus) obj;
+ loaded = true;
+ break;
+ }
+ }
+
+ } catch (EOFException ex) {
+ // This exception will be caught when EOF is reached
+ // There is no data in the status file
+ statusFile.delete();
+ } catch (ClassNotFoundException ex) {
+ // This exception will be caught when there is no
+ // serialized data in the status file
+ statusFile.delete();
+ } catch (FileNotFoundException ex) {
+
+ } catch (IOException ex) {
+
+ } finally {
+ //Close the ObjectInputStream
+ try {
+ if (in != null) {
+ in.close();
+ }
+ } catch (IOException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ return loaded;
+
+ }
+
+ public void done() {
+ if (snapshotFile != null) {
+ snapshotFile.delete();
+ }
+ lastCheckpoint = null;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/package.html b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/package.html
new file mode 100755
index 0000000..e094aa0
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains classes which add fault tolerance support using a distributed checkpointing system.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ApplicationStatus.java b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ApplicationStatus.java
new file mode 100755
index 0000000..19d1fc9
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ApplicationStatus.java
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.checkpoint.status;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+public abstract class ApplicationStatus implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Calendar creationDate;
+
+ public Calendar getCreationDate() {
+ return creationDate;
+ }
+
+ public ApplicationStatus() {
+ creationDate = Calendar.getInstance();
+ }
+
+ /**
+ * Compare the current application status with another one
+ * in order to check if both application status are
+ * consistent.
+ *
+ * @param other the other aplication status
+ *
+ * @return true, if both are consistents
+ */
+ public abstract boolean isCompatible(ApplicationStatus other);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ProtTestStatus.java b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ProtTestStatus.java
new file mode 100755
index 0000000..86cee3a
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/ProtTestStatus.java
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.checkpoint.status;
+
+import java.util.Collection;
+
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.global.options.SerializableApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+public class ProtTestStatus extends ApplicationStatus {
+
+ private static final long serialVersionUID = 1L;
+
+ private SerializableApplicationOptions applicationOptions;
+ private Model[] models;
+
+ public Model[] getModels() {
+ return models;
+ }
+
+ public SerializableApplicationOptions getApplicationOptions() {
+ return applicationOptions;
+ }
+
+ public ProtTestStatus(Model[] models, ApplicationOptions applicationOptions) {
+ if (applicationOptions == null)
+ throw new ProtTestInternalException("Wrong status format");
+ if (models != null
+ && models.length > 0)
+ checkIntegrity(models, applicationOptions);
+
+ this.models = models;
+ this.applicationOptions = new SerializableApplicationOptions(applicationOptions);
+ }
+
+ private boolean checkIntegrity(Model[] models, ApplicationOptions options) {
+ Collection<String> matrices = options.getMatrices();
+ Collection<Integer> distributions = options.getDistributions();
+ boolean plusF = options.isPlusF();
+ for (Model model : models) {
+ if (!(matrices.contains(model.getMatrix())
+ && distributions.contains(model.getDistribution()))
+ && (!model.isPlusF() || plusF)
+ && (model.checkAlignment(options.getAlignment())))
+ return false;
+ if (!model.checkAlignment(options.getAlignment())) {
+ // sets up the same alignment instance, once equality have been tested
+ model.setAlignment(options.getAlignment());
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isCompatible(ApplicationStatus other) {
+ if (other instanceof ProtTestStatus) {
+ ProtTestStatus otherStatus = (ProtTestStatus)other;
+ if (otherStatus.getApplicationOptions().equals(getApplicationOptions()))
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/package.html b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/package.html
new file mode 100755
index 0000000..a0613c3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/checkpoint/status/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the application status.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/collection/ModelCollection.java b/src/main/java/es/uvigo/darwin/prottest/util/collection/ModelCollection.java
new file mode 100755
index 0000000..a95e594
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/collection/ModelCollection.java
@@ -0,0 +1,349 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.collection;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Properties;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+
+/**
+ * An common interface for substitution models, that includes
+ * some specific operations to work with model collections.
+ *
+ * @author Diego Darriba
+ * @version 3.0
+ */
+public abstract class ModelCollection implements List<Model>, Serializable {
+
+ protected Alignment alignment;
+ /** The serialVersionUID. */
+ private static final long serialVersionUID = 515892620727410572L;
+ /** The set of all models inside the collection. */
+ protected List<Model> allModels;
+
+ public Alignment getAlignment() {
+ return alignment;
+ }
+
+ /**
+ * Instantiates a new model collection.
+ */
+ public ModelCollection(Alignment alignment) {
+ this.alignment = alignment;
+ allModels = new ArrayList<Model>();
+ }
+
+ /**
+ * Instantiates a new model collection with the array of models.
+ */
+ public ModelCollection(Model[] models, Alignment alignment) {
+ this.alignment = alignment;
+ for (Model model : models) {
+ checkAlignment(model);
+ }
+ allModels = new ArrayList<Model>();
+ allModels.addAll(Arrays.asList(models));
+ }
+
+ /**
+ * Instantiates a new model collection with another model collection.
+ */
+ public ModelCollection(ModelCollection mc) {
+ this.alignment = mc.getAlignment();
+ allModels = new ArrayList<Model>();
+ allModels.addAll(mc);
+ }
+
+ /**
+ * Creates a new model and adds it to the collection.
+ *
+ * @param matrix the substitution matrix name
+ * @param distribution the distribution of the model
+ * @param modelProperties the model specific properties
+ *
+ * @return true, if successfully added the model to the iterator
+ */
+ public boolean addModel(String matrix, int distribution, Properties modelProperties,
+ Alignment alignment, Tree tree, int ncat) {
+ Model model = ProtTestFactory.getInstance().createModel(matrix, distribution, modelProperties,
+ alignment, tree, ncat);
+
+ boolean toAdd = !allModels.contains(model);
+ if (toAdd) {
+ checkAlignment(model);
+ toAdd &= allModels.add(model);
+ }
+
+ return toAdd;
+ }
+
+ /**
+ * Adds a substitution model to the collection.
+ *
+ * @param model the substitution model to add
+ *
+ * @return true, if successfully added the model to the iterator
+ */
+ public boolean addModel(Model model) {
+ boolean toAdd = !allModels.contains(model);
+ if (toAdd) {
+ checkAlignment(model);
+ toAdd &= allModels.add(model);
+ }
+
+ return toAdd;
+ }
+
+ /**
+ * Adds the models result of combine each matrix with each distribution.
+ * There will be MxD new models in the iterator, where
+ * M is the number of matrices
+ * D is the number of distributions
+ *
+ * @param matrices collection of all the substitution matrices
+ * @param distributions collection of all the distributions
+ * @param modelProperties the model properties
+ *
+ * @return true, if successfully added all models
+ */
+ public boolean addModelCartesian(Collection<String> matrices, Collection<Integer> distributions,
+ Properties modelProperties, Alignment alignment, Tree tree, int ncat) {
+ boolean allDone = true;
+ boolean plusF = Boolean.parseBoolean(
+ modelProperties.getProperty(
+ Model.PROP_PLUS_F, "false"));
+ Properties modelPropertiesFalse = new Properties();
+ Properties modelPropertiesTrue = new Properties();
+ modelPropertiesFalse.setProperty(Model.PROP_PLUS_F, "false");
+ modelPropertiesTrue.setProperty(Model.PROP_PLUS_F, "true");
+ for (String matrix : matrices) {
+ for (Integer distribution : distributions) {
+ allDone &= addModel(matrix, distribution, modelPropertiesFalse,
+ alignment, tree, ncat);
+ if (plusF) {
+ allDone &= addModel(matrix, distribution, modelPropertiesTrue,
+ alignment, tree, ncat);
+ }
+ }
+ }
+ return allDone;
+ }
+
+ /**
+ * Gets the weight of the collection. This attribute is only used in
+ * order to heuristically sort models.
+ *
+ * @return the whole weight of the collection
+ */
+ public int getWeight(ModelWeightComparator mwc) {
+ int weight = 0;
+ for (Model model : allModels) {
+ weight += mwc.getWeight(model);
+ }
+ return weight;
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#size()
+ */
+ public int size() {
+ return allModels.size();
+ }
+
+// public abstract void printModelsSorted(char sortBy, PrintWriter out)
+// throws ProtTestInternalException;
+
+ /* (non-Javadoc)
+ * @see java.util.List#add(java.lang.Object)
+ */
+ public boolean add(Model e) {
+ return allModels.add(e);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#add(int, java.lang.Object)
+ */
+ public void add(int index, Model element) {
+ allModels.add(index, element);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#addAll(java.util.Collection)
+ */
+ public boolean addAll(Collection<? extends Model> c) {
+ return allModels.addAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#addAll(int, java.util.Collection)
+ */
+ public boolean addAll(int index, Collection<? extends Model> c) {
+ return allModels.addAll(index, c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#clear()
+ */
+ public void clear() {
+ allModels.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#contains(java.lang.Object)
+ */
+ public boolean contains(Object o) {
+ return allModels.contains(o);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#containsAll(java.util.Collection)
+ */
+ public boolean containsAll(Collection<?> c) {
+ return allModels.containsAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#get(int)
+ */
+ public Model get(int index) {
+ return allModels.get(index);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#indexOf(java.lang.Object)
+ */
+ public int indexOf(Object o) {
+ return allModels.indexOf(o);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#isEmpty()
+ */
+ public boolean isEmpty() {
+ return allModels.isEmpty();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#iterator()
+ */
+ public Iterator<Model> iterator() {
+ return allModels.iterator();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#lastIndexOf(java.lang.Object)
+ */
+ public int lastIndexOf(Object o) {
+ return allModels.lastIndexOf(o);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#listIterator()
+ */
+ public ListIterator<Model> listIterator() {
+ return allModels.listIterator();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#listIterator(int)
+ */
+ public ListIterator<Model> listIterator(int index) {
+ return allModels.listIterator(index);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#remove(java.lang.Object)
+ */
+ public boolean remove(Object o) {
+ return allModels.remove(o);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#remove(int)
+ */
+ public Model remove(int index) {
+ return allModels.remove(index);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#removeAll(java.util.Collection)
+ */
+ public boolean removeAll(Collection<?> c) {
+ return allModels.removeAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#retainAll(java.util.Collection)
+ */
+ public boolean retainAll(Collection<?> c) {
+ return allModels.retainAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#set(int, java.lang.Object)
+ */
+ public Model set(int index, Model element) {
+ return allModels.set(index, element);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#subList(int, int)
+ */
+ public List<Model> subList(int fromIndex, int toIndex) {
+ return allModels.subList(fromIndex, toIndex);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#toArray()
+ */
+ public Object[] toArray() {
+ return allModels.toArray();
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#toArray(T[])
+ */
+ public <T> T[] toArray(T[] a) {
+ return allModels.toArray(a);
+ }
+
+ private void checkAlignment(Model model) {
+ if (this.alignment == null) {
+ throw new ProtTestInternalException("Internal error: Alignment is not initialized");
+ } else if (!model.checkAlignment(this.alignment)) {
+ throw new ProtTestInternalException("Different alignments among model collection");
+ }
+ }
+
+ @Override
+ public ModelCollection clone() {
+ return new SingleModelCollection(this);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelCollection.java b/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelCollection.java
new file mode 100755
index 0000000..628cde6
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelCollection.java
@@ -0,0 +1,269 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.collection;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator;
+
+/**
+ * A complex implementation of model collection, which is able to
+ * distribute whole set of substitution models amongst a certain
+ * number of groups, generally amongst the number of processors.
+ *
+ * This class is a composition of model collections, that will have
+ * disjunction and completeness properties.
+ */
+public class ParallelModelCollection extends ModelCollection {
+
+ /** The serialVersionUID. */
+ private static final long serialVersionUID = 20090903L;
+
+ /** The list of model collections. */
+ private List<ModelCollection> modelCollections;
+
+ /** The number of groups. */
+ private int groups;
+
+ /** Defines if the current distribution is valid. */
+ private boolean validDistribution = false;
+
+ /** The heuristic algorithm to compare models. */
+ private ModelWeightComparator comparator;
+
+ /**
+ * Instantiates a new parallel model collection.
+ *
+ * @param allModels the whole set of models
+ * @param groups the number of groups, typically the size of the MPJ communicator
+ */
+ public ParallelModelCollection(Model[] allModels, int groups, ModelWeightComparator comparator, Alignment alignment) {
+ super(alignment);
+ ArrayList<Model> models = new ArrayList<Model>(Arrays.asList(allModels));
+ this.comparator = comparator;
+ Collections.sort(models, comparator);
+ initialize(models, groups);
+ }
+
+ /**
+ * Instantiates a new parallel model collection.
+ *
+ * @param allModels the whole set of models.
+ * @param groups the number of groups, typically the size of the MPJ communicator
+ */
+ public ParallelModelCollection(ModelCollection allModels, int groups, ModelWeightComparator comparator) {
+ super(allModels.getAlignment());
+ List<Model> models = new ArrayList<Model>(allModels);
+ this.comparator = comparator;
+ Collections.sort(models, comparator);
+ initialize(models, groups);
+ }
+
+ /**
+ * Initialize.
+ *
+ * @param allModels the whole set of models
+ * @param groups the number of groups, typically the size of the MPJ communicator
+ */
+ private void initialize(List<Model> allModels, int groups) {
+ this.allModels = allModels;
+ this.groups = groups;
+ modelCollections = new ArrayList<ModelCollection>();
+ distributeModels(this.allModels, this.groups);
+ }
+
+ /**
+ * Distribute models amongst groups. This method grants completeness
+ * and disjunction of single collections.
+ *
+ * @param allModels the whole set of models.
+ * @param groups the number of groups to distribute models into
+ */
+ private void distributeModels(List<Model> allModels, int groups) {
+
+ modelCollections.clear();
+
+ // initialize
+ for (int i = 0; i < groups; i++)
+ modelCollections.add(new SingleModelCollection(getAlignment()));
+
+ int maxWeight = 1;
+ int currentGroup = 0;
+ boolean modelAdded = false;
+
+ for (Model model : allModels) {
+ modelAdded = false;
+ ModelCollection minModelGroup = modelCollections.get(0);
+ for (currentGroup = 0; currentGroup < groups; currentGroup++) {
+ ModelCollection currentModelGroup = modelCollections.get(currentGroup);
+ if (currentModelGroup.getWeight(comparator) + comparator.getWeight(model) <= maxWeight)
+ {
+ modelAdded = currentModelGroup.addModel(model);
+ maxWeight = currentModelGroup.getWeight(comparator);
+ break;
+ } else if (currentModelGroup.getWeight(comparator) < minModelGroup.getWeight(comparator))
+ minModelGroup = currentModelGroup;
+ }
+ if (!modelAdded) {
+ minModelGroup.addModel(model);
+ maxWeight = minModelGroup.getWeight(comparator);
+ }
+ }
+
+ validDistribution = true;
+ }
+
+ /**
+ * Gets a single model collection. This method will return null
+ * if the group parameter is out of rank.
+ *
+ * @param group the group
+ *
+ * @return the model iterator
+ */
+ public ModelCollection getModelCollection(int group) {
+
+ if (!validDistribution)
+ distributeModels(this.allModels, this.groups);
+
+ if (group < 0 || group > groups)
+ return null;
+
+ return modelCollections.get(group);
+ }
+
+ /* (non-Javadoc)
+ * @see java.util.List#add(int, java.lang.Object)
+ */
+ @Override
+ public void add(int index, Model element) {
+ validDistribution = false;
+ super.add(index, element);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#add(es.uvigo.darwin.prottest.model.Model)
+ */
+ @Override
+ public boolean add(Model e) {
+ validDistribution = false;
+ return super.add(e);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#addModel(java.lang.String, int, java.util.Properties)
+ */
+ @Override
+ public boolean addModel(String matrix, int distribution, Properties modelProperties,
+ Alignment alignment, Tree tree, int ncat) {
+ validDistribution = false;
+ return super.addModel(matrix, distribution, modelProperties,
+ alignment, tree, ncat);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#addModel(es.uvigo.darwin.prottest.model.Model)
+ */
+ @Override
+ public boolean addModel(Model model) {
+ validDistribution = false;
+ return super.addModel(model);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#addModelCartesian(java.util.Collection, java.util.Collection, java.util.Properties)
+ */
+ @Override
+ public boolean addModelCartesian(Collection<String> matrices, Collection<Integer> distributions,
+ Properties modelProperties, Alignment alignment, Tree tree, int ncat) {
+ validDistribution = false;
+ return super.addModelCartesian(matrices, distributions, modelProperties,
+ alignment, tree, ncat);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#addAll(java.util.Collection)
+ */
+ @Override
+ public boolean addAll(Collection<? extends Model> c) {
+ validDistribution = false;
+ return super.addAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#addAll(int, java.util.Collection)
+ */
+ @Override
+ public boolean addAll(int index, Collection<? extends Model> c) {
+ validDistribution = false;
+ return super.addAll(index, c);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#clear()
+ */
+ @Override
+ public void clear() {
+ validDistribution = false;
+ super.clear();
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#remove(java.lang.Object)
+ */
+ @Override
+ public boolean remove(Object o) {
+ validDistribution = false;
+ return super.remove(o);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#remove(int)
+ */
+ @Override
+ public Model remove(int index) {
+ validDistribution = false;
+ return super.remove(index);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#removeAll(java.util.Collection)
+ */
+ @Override
+ public boolean removeAll(Collection<?> c) {
+ validDistribution = false;
+ return super.removeAll(c);
+ }
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.collection.ModelCollection#set(int, es.uvigo.darwin.prottest.model.Model)
+ */
+ @Override
+ public Model set(int index, Model element) {
+ validDistribution = false;
+ return super.set(index, element);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelQueue.java b/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelQueue.java
new file mode 100755
index 0000000..e2099bc
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/collection/ParallelModelQueue.java
@@ -0,0 +1,81 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.collection;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.comparator.ModelDistributionHeuristic;
+import java.util.Collections;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class ParallelModelQueue {
+
+ /** List of models */
+ private ModelCollection sortedModelList;
+ /** Number of threads to schedule */
+ private int maxAvThreads;
+ /** Available threads */
+ private int availableThreads;
+
+ public ParallelModelQueue(int maxAvThreads, ModelCollection modelList) {
+
+ this.maxAvThreads = maxAvThreads;
+ this.availableThreads = maxAvThreads;
+
+ this.sortedModelList = modelList;
+ Collections.sort(this.sortedModelList, new ModelDistributionHeuristic());
+
+ }
+
+ public synchronized Model getNextModel() {
+
+ if (availableThreads < 1) {
+ return null;
+ }
+
+ Model nextModel = null;
+ for (Model model : sortedModelList) {
+
+ if (getNumberOfThreads(model) <= availableThreads) {
+ nextModel = model;
+ break;
+ }
+
+ }
+ availableThreads -= getNumberOfThreads(nextModel);
+ sortedModelList.remove(nextModel);
+ return nextModel;
+
+ }
+
+ private int getNumberOfThreads(Model model) {
+
+ int numberOfProcessors;
+ if (!model.isGamma()) {
+ numberOfProcessors = 1;
+ } else if (!model.isInv()) {
+ numberOfProcessors = 2;
+ } else {
+ numberOfProcessors = 4;
+ }
+ return Math.min(numberOfProcessors, maxAvThreads);
+
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/collection/SingleModelCollection.java b/src/main/java/es/uvigo/darwin/prottest/util/collection/SingleModelCollection.java
new file mode 100755
index 0000000..f8d7b73
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/collection/SingleModelCollection.java
@@ -0,0 +1,56 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.collection;
+
+import es.uvigo.darwin.prottest.model.Model;
+import pal.alignment.Alignment;
+
+/**
+ * A single implementation of ModelCollection.
+ */
+public class SingleModelCollection extends ModelCollection {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090804L;
+
+ /**
+ * Instantiates a new single model collection.
+ */
+ public SingleModelCollection(Alignment alignment) {
+ super(alignment);
+ }
+
+ /**
+ * Instantiates a new single model collection.
+ *
+ * @param models the models
+ */
+ public SingleModelCollection(Model[] models, Alignment alignment) {
+ super(models, alignment);
+ }
+
+ /**
+ * Instantiates a new single model collection.
+ *
+ * @param models the models
+ */
+ public SingleModelCollection(ModelCollection models) {
+ super(models);
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/collection/package.html b/src/main/java/es/uvigo/darwin/prottest/util/collection/package.html
new file mode 100755
index 0000000..9e6323f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/collection/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains utilities to manage substitution model collections with group operations.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/comparator/AminoAcidModelNaturalComparator.java b/src/main/java/es/uvigo/darwin/prottest/util/comparator/AminoAcidModelNaturalComparator.java
new file mode 100755
index 0000000..b3f8cd5
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/comparator/AminoAcidModelNaturalComparator.java
@@ -0,0 +1,63 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.comparator;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static es.uvigo.darwin.prottest.global.AminoAcidApplicationGlobals.*;
+import es.uvigo.darwin.prottest.model.AminoAcidModel;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+public class AminoAcidModelNaturalComparator implements Comparator<Model> {
+
+ @Override
+ public int compare(Model model0, Model model1) {
+
+ if (model0 instanceof AminoAcidModel && model1 instanceof AminoAcidModel) {
+ AminoAcidModel arg0 = (AminoAcidModel) model0;
+ AminoAcidModel arg1 = (AminoAcidModel) model1;
+ int value = 0;
+ if (!arg0.getMatrix().equals(arg1.getMatrix())) {
+ List<String> matrices = Arrays.asList(ALL_MATRICES);
+ int pos0 = matrices.indexOf(arg0.getMatrix());
+ int pos1 = matrices.indexOf(arg1.getMatrix());
+ if ( pos0 < pos1 )
+ value = -1;
+ else
+ value = 1;
+ } else if (arg0.getDistribution() != arg1.getDistribution()) {
+ if (arg0.getDistribution() < arg1.getDistribution())
+ value = -1;
+ else if (arg1.getDistribution() < arg0.getDistribution())
+ value = 1;
+ } else if (arg0.isPlusF() != arg1.isPlusF()) {
+ if (arg0.isPlusF())
+ value = 1;
+ else
+ value = -1;
+ } else
+ value = 0;
+ return value;
+ } else
+ throw new ProtTestInternalException("Wrong use of Amino-acid Model Comparator");
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/comparator/LKComparator.java b/src/main/java/es/uvigo/darwin/prottest/util/comparator/LKComparator.java
new file mode 100755
index 0000000..86c9643
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/comparator/LKComparator.java
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.comparator;
+
+import java.util.Comparator;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class LKComparator.
+ */
+public class LKComparator implements Comparator<Model> {
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Model arg0, Model arg1) {
+
+ int value = 0;
+ if (arg0.getLk() > arg1.getLk())
+ value = 1;
+ else if (arg0.getLk() < arg1.getLk())
+ value = -1;
+ return value;
+
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelDistributionHeuristic.java b/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelDistributionHeuristic.java
new file mode 100755
index 0000000..65f8cc1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelDistributionHeuristic.java
@@ -0,0 +1,55 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.comparator;
+
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class ModelDistributionHeuristic.
+ */
+public class ModelDistributionHeuristic extends ModelWeightComparator {
+
+ /* (non-Javadoc)
+ * @see es.uvigo.darwin.prottest.util.comparator.ModelWeightComparator#getWeight(es.uvigo.darwin.prottest.model.Model)
+ */
+ public int getWeight(Model model) {
+
+ int weight;
+ switch (model.getDistribution()) {
+ case 0:
+ weight = 1;
+ break;
+ case 1:
+ weight = 2;
+ break;
+ case 2:
+ weight = 6;
+ break;
+ case 3:
+ weight = 30;
+ break;
+ default:
+ throw new ProtTestInternalException("Invalid model distribution " + model.getDistribution());
+ }
+
+ return weight;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelWeightComparator.java b/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelWeightComparator.java
new file mode 100755
index 0000000..534e27c
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/comparator/ModelWeightComparator.java
@@ -0,0 +1,48 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.comparator;
+
+import java.util.Comparator;
+
+import es.uvigo.darwin.prottest.model.Model;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class ModelWeightComparator.
+ */
+public abstract class ModelWeightComparator implements Comparator<Model> {
+
+ /* (non-Javadoc)
+ * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+ */
+ public int compare(Model model1, Model model2) {
+ int value = 0;
+ if (model1 != null && model2 != null)
+ value = getWeight(model2) - getWeight(model1);
+ return value;
+ }
+
+ /**
+ * Gets the weight.
+ *
+ * @param model the model
+ *
+ * @return the weight
+ */
+ public abstract int getWeight(Model model);
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/comparator/package.html b/src/main/java/es/uvigo/darwin/prottest/util/comparator/package.html
new file mode 100755
index 0000000..52b9784
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/comparator/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains utilities to compare models, like sorting heuristics.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/AlignmentParseException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/AlignmentParseException.java
new file mode 100755
index 0000000..67534c0
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/AlignmentParseException.java
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.exception;
+
+/**
+ * The Class AlignmentParseException.
+ *
+ * @author Diego Darriba
+ */
+public class AlignmentParseException extends ProtTestCheckedException {
+
+ private static final String MESSAGE = "Alignment parse exception";
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new alignment format exception.
+ */
+ public AlignmentParseException() {
+ super(MESSAGE);
+ }
+
+ /**
+ * Instantiates a new alignment format exception.
+ *
+ * @param description the description
+ */
+ public AlignmentParseException(String description) {
+ super(MESSAGE + ": " + description);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/ImportException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/ImportException.java
new file mode 100755
index 0000000..6e835d3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/ImportException.java
@@ -0,0 +1,59 @@
+package es.uvigo.darwin.prottest.util.exception;
+
+/**
+ * @author Andrew Rambaut
+ * @author Alexei Drummond
+ *
+ * @version $Id: ImportException.java 609 2007-01-08 00:40:49Z pepster $
+ */
+public class ImportException extends Exception {
+ public ImportException() { super(); }
+ public ImportException(String message) { super(message); }
+ public String userMessage() { return getMessage(); }
+
+ public static class DuplicateFieldException extends ImportException {
+ public DuplicateFieldException() { super(); }
+ public DuplicateFieldException(String message) { super(message); }
+ }
+
+ public static class BadFormatException extends ImportException {
+ public BadFormatException() { super(); }
+ public BadFormatException(String message) { super(message); }
+ }
+
+ public static class UnparsableDataException extends ImportException {
+ public UnparsableDataException() { super(); }
+ public UnparsableDataException(String message) { super(message); }
+ }
+
+ public static class MissingFieldException extends ImportException {
+ public MissingFieldException() { super(); }
+ public MissingFieldException(String message) { super(message); }
+ public String userMessage() { return "Unsupported value for field " + getMessage(); }
+ }
+
+ public static class ShortSequenceException extends ImportException {
+ public ShortSequenceException() { super(); }
+ public ShortSequenceException(String message) { super(message); }
+ public String userMessage() { return "Sequence is too short: " + getMessage(); }
+ }
+
+ public static class TooFewTaxaException extends ImportException {
+ public TooFewTaxaException() { super(); }
+ public TooFewTaxaException(String message) { super(message); }
+ public String userMessage() { return "Number of taxa is less than expected: " +
+ (getMessage() != null ? getMessage() : ""); }
+ }
+
+ public static class DuplicateTaxaException extends ImportException {
+ public DuplicateTaxaException() { super(); }
+ public DuplicateTaxaException(String message) { super(message); }
+ }
+
+ public static class UnknownTaxonException extends ImportException {
+ public UnknownTaxonException() { super(); }
+ public UnknownTaxonException(String message) { super(message); }
+ }
+
+}
+
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/ModelOptimizationException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/ModelOptimizationException.java
new file mode 100755
index 0000000..d0dabdc
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/ModelOptimizationException.java
@@ -0,0 +1,165 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.exception;
+
+/**
+ * Generic exception when model optimization
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+public class ModelOptimizationException extends ProtTestCheckedException {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new external execution exception.
+ */
+ public ModelOptimizationException() {
+ super("Model optimization exception");
+ }
+
+ /**
+ * Instantiates a new external execution exception.
+ *
+ * @param description the description
+ */
+ public ModelOptimizationException(String description) {
+ super("Model optimization exception: " + description);
+ }
+
+ /**
+ * Exception which occurs while execution a third-party application
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+ public static class ExternalExecutionException extends ModelOptimizationException {
+
+ public ExternalExecutionException() {
+ super();
+ }
+
+ public ExternalExecutionException(String application) {
+ super("there was an error while executing " + application);
+ }
+
+ public ExternalExecutionException(String application, String message) {
+ super("there was an error while executing " + application + ": " + message);
+ }
+ }
+
+ /**
+ * Exception which occurs when the current operating system is not supported
+ * (only when running non-portable applications)
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+ public static class OSNotSupportedException extends ExternalExecutionException {
+
+ /**
+ * Instantiates a new oS not supported exception.
+ */
+ public OSNotSupportedException(String application) {
+ super(application, "this operating system (" + System.getProperty("os.name") + ") is not supported.");
+ }
+ }
+
+ /**
+ * Exception while parsing the stats file provided by a third-party application
+ *
+ * @author Diego Darriba
+ * @since 3.0
+ */
+ public static class StatsFileFormatException extends ExternalExecutionException {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new stats file format exception.
+ *
+ * @param application the external model optimizer
+ */
+ public StatsFileFormatException(String application) {
+ super("there was an error parsing " + application + " stats file");
+ }
+
+ /**
+ * Instantiates a new stats file format exception.
+ *
+ * @param application the external model optimizer
+ * @param description the description
+ */
+ public StatsFileFormatException(String application, String description) {
+ super("there was an error parsing " + application + " stats file: " + description);
+ }
+ }
+
+ /**
+ * Exception while a required model matrix is not found
+ *
+ * @author diego
+ * @since 3.0
+ */
+ public static class ModelNotFoundException extends ExternalExecutionException {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new model not found exception.
+ *
+ * @param model the non existent model name
+ */
+ public ModelNotFoundException(String model) {
+ super("cannot find " + model + " matrix description");
+ }
+
+ /**
+ * Instantiates a new model not found exception.
+ *
+ * @param model the non existent model name
+ * @param description the description
+ */
+ public ModelNotFoundException(String model, String description) {
+ super("cannot find " + model + " matrix description: " + description);
+ }
+ }
+
+ /**
+ * External execution exception localized in PhyML
+ *
+ * @author diego
+ * @since 3.0
+ */
+ public static class PhyMLExecutionException extends ExternalExecutionException {
+
+ private static final String applicationName = "PhyML";
+
+ public PhyMLExecutionException() {
+ super(applicationName);
+ }
+
+ public PhyMLExecutionException(String message) {
+ super(applicationName, message);
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestCheckedException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestCheckedException.java
new file mode 100755
index 0000000..ca4ea71
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestCheckedException.java
@@ -0,0 +1,42 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.exception;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class ProtTestCheckedException extends Exception {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20100525L;
+
+ /**
+ * Instantiates a new prot test internal exception.
+ */
+ public ProtTestCheckedException() {}
+
+ /**
+ * Instantiates a new prot test internal exception.
+ *
+ * @param description the description
+ */
+ public ProtTestCheckedException(String description) {
+ super(description);
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestInternalException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestInternalException.java
new file mode 100755
index 0000000..2c29288
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/ProtTestInternalException.java
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.exception;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class ProtTestInternalException.
+ *
+ * @author Diego Darriba López
+ */
+public class ProtTestInternalException extends RuntimeException {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new prot test internal exception.
+ */
+ public ProtTestInternalException() {}
+
+ /**
+ * Instantiates a new prot test internal exception.
+ *
+ * @param description the description
+ */
+ public ProtTestInternalException(String description) {
+ super(description);
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/exception/TreeFormatException.java b/src/main/java/es/uvigo/darwin/prottest/util/exception/TreeFormatException.java
new file mode 100755
index 0000000..fd51901
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/exception/TreeFormatException.java
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.exception;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class TreeFormatException.
+ *
+ * @author Diego Darriba López
+ */
+public class TreeFormatException extends ProtTestInternalException {
+
+ /** The Constant serialVersionUID. */
+ private static final long serialVersionUID = 20090728L;
+
+ /**
+ * Instantiates a new tree format exception.
+ */
+ public TreeFormatException() {}
+
+ /**
+ * Instantiates a new tree format exception.
+ *
+ * @param description the description
+ */
+ public TreeFormatException(String description) {
+ super(description);
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/factory/ProtTestFactory.java b/src/main/java/es/uvigo/darwin/prottest/util/factory/ProtTestFactory.java
new file mode 100755
index 0000000..d784a98
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/factory/ProtTestFactory.java
@@ -0,0 +1,317 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.prottest.util.factory;
+
+import static es.uvigo.darwin.prottest.global.ApplicationGlobals.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+import java.util.Calendar;
+import java.text.SimpleDateFormat;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.exe.PhyMLv3AminoAcidRunEstimator;
+import es.uvigo.darwin.prottest.exe.RaxMLAminoAcidRunEstimator;
+import es.uvigo.darwin.prottest.exe.RunEstimator;
+import es.uvigo.darwin.prottest.global.AminoAcidApplicationGlobals;
+import es.uvigo.darwin.prottest.global.ApplicationGlobals;
+import es.uvigo.darwin.prottest.global.RaxmlAminoAcidApplicationGlobals;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.AminoAcidModel;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.printer.AminoAcidPrintFramework;
+import es.uvigo.darwin.prottest.selection.printer.PrintFramework;
+import es.uvigo.darwin.prottest.util.argumentparser.AminoAcidArgumentParser;
+import es.uvigo.darwin.prottest.util.argumentparser.ProtTestArgumentParser;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogFormatter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.StreamHandler;
+
+/**
+ * A factory for creating ProtTest objects.
+ */
+public class ProtTestFactory {
+
+ /** The Constant PROTEIC. */
+ public static final int PROTEIC = 1;
+ /** The Constant NUCLEIC. */
+ public static final int NUCLEIC = 2;
+ /** The Constant MAX_SORT. */
+ private static final int MAX_SORT = 2;
+ /** The instance. */
+ private static ProtTestFactory instance;
+ /** The sort. */
+ private int sort;
+ /** Unique log handler. */
+ private Handler logHandler;
+
+ /**
+ * Instantiates a new prot test factory.
+ *
+ * @param sort the sort
+ *
+ * @throws IllegalArgumentException the illegal argument exception
+ */
+ private ProtTestFactory(int sort)
+ throws IllegalArgumentException {
+ if (sort <= 0 || sort > MAX_SORT) {
+ throw new IllegalArgumentException(
+ "Cannot create factory (unexistent sort : " + sort + ")");
+ }
+ this.sort = sort;
+ }
+
+ /**
+ * Initialize.
+ *
+ * @param args the args
+ *
+ * @return the string[]
+ */
+ public static String[] initialize(String[] args) {
+ if (instance == null) {
+ int sort;
+ List<String> argList = new ArrayList<String>(Arrays.asList(args));
+ int index = argList.indexOf(ProtTestArgumentParser.ARG_TOKEN + ProtTestArgumentParser.PARAM_DATA_TYPE);
+ if (index < 0) //set default
+ {
+ sort = PROTEIC;
+ } else {
+ String value = argList.get(index + 1);
+ argList.remove(index + 1);
+ argList.remove(index);
+ args = argList.toArray(new String[0]);
+ if (value.equals(ProtTestArgumentParser.DATA_TYPE_AMINOACID)) {
+ sort = PROTEIC;
+ } else if (value.equals(ProtTestArgumentParser.DATA_TYPE_NUCLEOTIDE)) {
+ sort = NUCLEIC;
+ } else {
+ throw new IllegalArgumentException("Invalid data type " + value);
+ }
+ }
+ instance = new ProtTestFactory(sort);
+ return args;
+ } else {
+ throw new ProtTestInternalException("ModelTestFactory was already initialized");
+ }
+ }
+
+ /**
+ * Gets the single instance of ProtTestFactory.
+ *
+ * @return single instance of ProtTestFactory
+ */
+ public static ProtTestFactory getInstance() {
+ if (instance == null) {
+ initialize(new String[0]);
+ }
+// throw new ProtTestInternalException("ModelTestFactory should be initialized");
+
+ return instance;
+ }
+
+ /**
+ * Creates a new ProtTest object.
+ *
+ * @param args the args
+ * @param options the options
+ *
+ * @return the prot test argument parser
+ */
+ public ProtTestArgumentParser createProtTestArgumentParser(String[] args, ApplicationOptions options)
+ throws IllegalArgumentException{
+ ProtTestArgumentParser mtap = null;
+ switch (sort) {
+ case PROTEIC:
+ mtap = new AminoAcidArgumentParser(args, options);
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+ return mtap;
+ }
+
+ /**
+ * Gets the application globals.
+ *
+ * @return the application globals
+ */
+ public ApplicationGlobals getApplicationGlobals() {
+ ApplicationGlobals ap = null;
+ String analyzer = APPLICATION_PROPERTIES.getProperty("analyzer");
+ switch (sort) {
+ case PROTEIC:
+ if (analyzer.equals(ANALYZER_RAXML)) {
+ ap = new RaxmlAminoAcidApplicationGlobals();
+ } else if (analyzer.equals(ANALYZER_PHYML)) {
+ ap = new AminoAcidApplicationGlobals();
+ } else {
+ throw new ProtTestInternalException("Analyzer " + analyzer + " not supported by RunEstimator. Check your prottest.properties file");
+ }
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+ return ap;
+ }
+
+ /**
+ * Creates a new ProtTest object.
+ *
+ * @param matrix the matrix
+ * @param distribution the distribution
+ * @param modelProperties the model APPLICATION_PROPERTIES
+ *
+ * @return the model
+ */
+ public Model createModel(String matrix, int distribution, Properties modelProperties,
+ Alignment alignment, Tree tree, int ncat) {
+ Model model = null;
+ boolean plusF;
+ if (modelProperties != null) {
+ plusF = Boolean.parseBoolean(
+ modelProperties.getProperty(
+ AminoAcidModel.PROP_PLUS_F, "false"));
+ } else {
+ plusF = false;
+ }
+ switch (sort) {
+ case PROTEIC:
+ model = new AminoAcidModel(matrix, distribution, plusF,
+ alignment, tree, ncat);
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+ return model;
+ }
+
+ /**
+ * Creates a new ProtTest object.
+ *
+ * @param options the options
+ * @param model the model
+ *
+ * @return the run estimator
+ */
+ public RunEstimator createRunEstimator(ApplicationOptions options, Model model) {
+ return createRunEstimator(options, model, 1);
+ }
+
+ /**
+ * Creates a new ProtTest object.
+ *
+ * @param options the options
+ * @param model the model
+ *
+ * @return the run estimator
+ */
+ public RunEstimator createRunEstimator(ApplicationOptions options, Model model, int numberOfThreads) {
+ RunEstimator runEstimator = null;
+ String analyzer = APPLICATION_PROPERTIES.getProperty("analyzer");
+ if (analyzer.equals(ANALYZER_PHYML)) {
+ switch (sort) {
+ case PROTEIC:
+ runEstimator = new PhyMLv3AminoAcidRunEstimator(options, model, numberOfThreads);
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+ } else if (analyzer.equals(ANALYZER_RAXML)) {
+ switch (sort) {
+ case PROTEIC:
+ runEstimator = new RaxMLAminoAcidRunEstimator(options, model);
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+ } else {
+ throw new ProtTestInternalException("Analyzer " + analyzer + " not supported by RunEstimator");
+ }
+ return runEstimator;
+ }
+
+ public Handler createLogHandler() throws IOException {
+ // Log level is configurable:
+ // 'info' Only general information messages are logged (default)
+ // 'fine' General debug information is also logged
+ // 'finer' More complex debug information is logged
+ // 'finest' All activity is tracked
+
+ if (logHandler == null) {
+
+ String[] supportedLevels = {"INFO", "FINE", "FINER", "FINEST"};
+
+ String logDirName = APPLICATION_PROPERTIES.getProperty("log_dir");
+ String level = APPLICATION_PROPERTIES.getProperty("log_level", "info").toUpperCase();
+ boolean supported = false;
+ for (String testLevel : supportedLevels) {
+ supported |= testLevel.equals(level);
+ }
+
+ if (logDirName != null && supported) {
+ File logDir = new File(logDirName);
+ if (!logDir.isAbsolute()) {
+ logDir = new File(ApplicationGlobals.PATH + File.separator + logDir);
+ }
+ if (!logDir.exists()) {
+ logDir.mkdirs();
+ }
+
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+ //File logFile = new File(logDir.getAbsolutePath() + File.separator + "prottest3_" +
+ // sdf.format(Calendar.getInstance().getTime()));
+ File logFile = File.createTempFile("prottest3_"+sdf.format(Calendar.getInstance().getTime())+"_",
+ ".log", logDir);
+ FileOutputStream fos = new FileOutputStream(logFile);
+ logHandler = new StreamHandler(fos, new ProtTestLogFormatter());
+ logHandler.setLevel(Level.parse(level));
+ }
+
+ }
+ return logHandler;
+
+ }
+
+ /**
+ * Creates a new ProtTest object.
+ *
+ * @return the prints the framework
+ */
+ public PrintFramework createPrintFramework() {
+ PrintFramework pf = null;
+
+ switch (sort) {
+ case PROTEIC:
+ pf = new AminoAcidPrintFramework();
+ break;
+ case NUCLEIC:
+ throw new ProtTestInternalException("Unsupported operation: nucleic data");
+ }
+
+ return pf;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/factory/package.html b/src/main/java/es/uvigo/darwin/prottest/util/factory/package.html
new file mode 100755
index 0000000..da0f30b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/factory/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains the application factory.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/AlignmentReader.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/AlignmentReader.java
new file mode 100755
index 0000000..b39a4c1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/AlignmentReader.java
@@ -0,0 +1,285 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.fileio;
+
+import converter.Converter;
+import converter.DefaultFactory;
+import converter.Factory;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.PushbackReader;
+
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import pal.alignment.Alignment;
+import pal.alignment.ReadAlignment;
+import pal.tree.ReadTree;
+import pal.tree.Tree;
+import pal.tree.TreeParseException;
+
+// TODO: Auto-generated Javadoc
+import parser.ParseException;
+/**
+ * The Class AlignmentReader.
+ */
+public class AlignmentReader {
+
+ /**
+ * Instantiates a new alignment reader.
+ */
+ public AlignmentReader() {
+
+ }
+
+ /**
+ * Read alignment.
+ *
+ * @param output the output writer
+ * @param filename the filename
+ * @param debug the debug
+ *
+ * @return the alignment
+ *
+ * @throws AlignmentParseException the alignment parse exception.
+ * @throws FileNotFoundException Signals that the input filename does not exist.
+ * @throws IOException Signals that an I/O exception has occured.
+ */
+ public static Alignment readAlignment(PrintWriter output, String filename, boolean debug)
+ throws AlignmentParseException, FileNotFoundException, IOException {
+
+ Alignment alignment;
+ StringBuilder text = new StringBuilder();
+
+ BufferedReader br = new BufferedReader(new FileReader(filename));
+ String s;
+ while ((s = br.readLine()) != null) {
+ text.append(s).append("\r\n");
+ }
+ br.close();
+
+
+ //Get options
+ String in = text.toString();
+ String inO = "";
+ String inP = "";
+ String inF = "";
+ boolean autodetect = true;
+ boolean collapse = false;
+ boolean gaps = false;
+ boolean missing = false;
+ int limit = 0;
+ String out = "";
+ String outO = "Linux";
+ String os = System.getProperty("os.name");
+ if (os.startsWith("Mac")) {
+ outO = "MacOS";
+ } else if (os.startsWith("Linux")) {
+ outO = "Linux";
+ } else if (os.startsWith("Win")) {
+ outO = "Windows";
+ }
+ String outP = "ProtTest";
+ String outF = "PHYLIP";
+ boolean lower = false;
+ boolean numbers = false;
+ boolean sequential = true;
+ boolean match = false;
+
+ //Get converter and convert MSA
+ Factory factory = new DefaultFactory();
+ Converter converter;
+
+ //Inicializar logger
+ Logger logger = Logger.getLogger("alter" + System.currentTimeMillis());
+ logger.setUseParentHandlers(false);
+ logger.setLevel(Level.ALL);
+ for (Handler handler : ProtTestLogger.getDefaultLogger().getHandlers()) {
+ logger.addHandler(handler);
+ }
+
+ try {
+ converter = factory.getConverter(inO, inP, inF, autodetect,
+ collapse, gaps, missing, limit,
+ outO, outP, outF, lower, numbers, sequential, match, logger.getName());
+ out = converter.convert(in);
+ } catch (UnsupportedOperationException ex) {
+ throw new AlignmentParseException("There's some error in your data: " + ex.getMessage());
+ } catch (ParseException ex) {
+ throw new AlignmentParseException("There's some error in your data: " + ex.getMessage());
+ }
+
+ try {
+ PushbackReader pr = new PushbackReader(new StringReader(out));
+ alignment = readAlignment(output, pr, debug);
+ } catch (AlignmentParseException ex) {
+ sequential = false;
+ try {
+ converter = factory.getConverter(inO, inP, inF, autodetect,
+ collapse, gaps, missing, limit,
+ outO, outP, outF, lower, numbers, sequential, match, logger.getName());
+ out = converter.convert(in);
+ } catch (UnsupportedOperationException exUO) {
+ throw new AlignmentParseException("There's some error in your data: " + ex.getMessage());
+ } catch (ParseException exP) {
+ throw new AlignmentParseException("There's some error in your data: " + ex.getMessage());
+ }
+ PushbackReader pr = new PushbackReader(new StringReader(out));
+ alignment = readAlignment(output, pr, debug);
+ }
+
+ if (alignment == null) {
+ throw new AlignmentParseException("There's some error in your data, exiting...");
+ }
+
+ return alignment;
+ }
+
+ /**
+ * Read alignment.
+ *
+ * @param out the out
+ * @param pr the pushback reader which contains the alignment
+ * @param debug the debug state
+ *
+ * @return the alignment
+ *
+ * @throws AlignmentParseException the alignment parse exception
+ * @throws IOException Signals that an I/O exception has occured.
+ */
+ public static Alignment readAlignment(PrintWriter out, PushbackReader pr, boolean debug)
+ throws AlignmentParseException, IOException {
+
+ if (debug) {
+ out.println("");
+ out.println("**********************************************************");
+ out.println(" Reading alignment...");
+ }
+ Alignment alignment = null;
+ try {
+ alignment = new ReadAlignment(pr);
+ } catch (pal.alignment.AlignmentParseException e) {
+ throw new AlignmentParseException(e.getMessage());
+ }
+
+ List<String> seqNames = new ArrayList<String>(alignment.getSequenceCount());
+ for (int i = 0; i < alignment.getSequenceCount(); i++) {
+ seqNames.add(alignment.getIdentifier(i).getName());
+ }
+
+ String currString;
+ int size = alignment.getSequenceCount();
+ for (int i = 0; i < size; i++) {
+ currString = (String) seqNames.get(i);
+ for (int j = i + 1; j < size; j++) {
+ if (seqNames.get(j).equals(currString)) {
+ throw new AlignmentParseException("ERROR: There are duplicated taxa names in the alignment: " + currString);
+ }
+ }
+ }
+
+ //TODO: print TAXA and check if data is in correct format
+ if (debug) {
+ for (int i = 0; i < alignment.getSequenceCount(); i++) {
+ out.println(" Sequence #" + (i + 1) + ": " + alignment.getIdentifier(i).getName());
+ }
+ out.println(" Alignment contains " + alignment.getSequenceCount() + " sequences of length " + alignment.getSiteCount());
+ out.println("");
+ out.println("**********************************************************");
+ out.println("");
+ }
+
+ return alignment;
+ }
+
+ /**
+ * Read tree.
+ *
+ * @param out the out
+ * @param filename the filename
+ * @param debug the debug
+ *
+ * @return the tree
+ *
+ * @throws TreeFormatException When the input filename is not in the right format
+ * @throws FileNotFoundException Signals that the input filename does not exist.
+ * @throws IOException Signals that an I/O exception has occured.
+ */
+ public static Tree readTree(PrintWriter out, String filename, boolean debug)
+ throws TreeFormatException, FileNotFoundException, IOException {
+ //FOR PHYML:
+ //if tree is not in newick format, reformat and save to a new file:
+ //TreeUtils: public static void printNH(Tree tree, java.io.PrintWriter out)
+ if (debug) {
+ out.println("Reading tree...");
+ }
+ Tree tree;
+ try {
+ tree = new ReadTree(filename);
+ } catch (TreeParseException e) {
+ throw new TreeFormatException("Error: Wrong tree format : " + e.getMessage());
+ }
+ if (debug) {
+ out.println("Tree contains " + tree.getExternalNodeCount() + " external nodes");
+ out.println("");
+ }
+ return tree;
+ }
+
+ /**
+ * Read tree.
+ *
+ * @param out the out
+ * @param in the tree pushback reader
+ * @param debug the debug
+ *
+ * @return the tree
+ *
+ * @throws TreeFormatException the tree format exception
+ */
+ public static Tree readTree(PrintWriter out, PushbackReader in, boolean debug)
+ throws TreeFormatException {
+ //FOR PHYML:
+ //if tree is not in newick format, reformat and save to a new file:
+ //TreeUtils: public static void printNH(Tree tree, java.io.PrintWriter out)
+ if (debug) {
+ out.println("Reading tree...");
+ }
+ Tree tree;
+ try {
+ tree = new ReadTree(in);
+ } catch (TreeParseException e) {
+ throw new TreeFormatException("Error: Wrong tree format : " + e.getMessage());
+ }
+ if (debug) {
+ out.println("Tree contains " + tree.getExternalNodeCount() + " external nodes");
+ out.println("");
+ }
+ return tree;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/ImportHelper.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/ImportHelper.java
new file mode 100755
index 0000000..05023c1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/ImportHelper.java
@@ -0,0 +1,573 @@
+/*
+ * ImportHelper.java
+ *
+ * (c) 2002-2005 BEAST Development Core Team
+ *
+ * This package may be distributed under the
+ * Lesser Gnu Public Licence (LGPL)
+ */
+package es.uvigo.darwin.prottest.util.fileio;
+
+import es.uvigo.darwin.prottest.util.exception.ImportException;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.io.Reader;
+import java.io.Writer;
+
+/**
+ * A helper class for phylogenetic file format importers
+ *
+ * @author Andrew Rambaut
+ * @author Alexei Drummond
+ *
+ * @version $Id: ImportHelper.java 699 2007-04-28 07:07:49Z matthew_cheung $
+ */
+public class ImportHelper {
+ private long totalCharactersRead = 0;
+
+ // Expected length of input in bytes, or 0 if unknown
+ private long expectedInputLength = 0;
+
+ /**
+ * ATTENTION: The ImportHelper never closes the reader passed to the constructor.
+ * If the reader holds resources (e.g. a FileReader, which holds an open file),
+ * then it is the client class' responsibility to close the reader when it has
+ * finished using it.
+ * @param reader
+ */
+ public ImportHelper(Reader reader) {
+ this.reader = new LineNumberReader(reader);
+ this.commentWriter = null;
+ }
+
+ public void setExpectedInputLength(long l) {
+ this.expectedInputLength = l;
+ }
+
+ public ImportHelper(Reader reader, Writer commentWriter) {
+ this.reader = new LineNumberReader(reader);
+ this.commentWriter = commentWriter;
+ }
+
+ /**
+ * @return If the length of the input is known (because a file was
+ * passed to the constructor), this reports a value between 0.0 and 1.0
+ * indicating the relative read position in the file. Otherwise, this
+ * always returns 0.0.
+ *
+ * This method assumes that all characters in the input are one byte
+ * long (to get its estimate, it divides the number of *characters* read
+ * by the number of *bytes* in the file). If there is an efficient way
+ * to fix this, we should do so :)
+ */
+ public double getProgress() {
+ if (expectedInputLength == 0) {
+ return 0.0;
+ } else {
+ return (double) totalCharactersRead / expectedInputLength;
+ }
+ }
+
+ public void closeReader() throws IOException {
+ reader.close();
+ }
+
+ public void setCommentDelimiters(char line) {
+ hasComments = true;
+ this.lineComment = line;
+ }
+
+ public void setCommentDelimiters(char start, char stop) {
+ hasComments = true;
+ this.startComment = start;
+ this.stopComment = stop;
+ }
+
+ public void setCommentDelimiters(char start, char stop, char line) {
+ hasComments = true;
+ this.startComment = start;
+ this.stopComment = stop;
+ this.lineComment = line;
+ }
+
+ public void setCommentDelimiters(char start, char stop, char line, char write, char meta) {
+ hasComments = true;
+ this.startComment = start;
+ this.stopComment = stop;
+ this.lineComment = line;
+ this.writeComment = write;
+ this.metaComment = meta;
+ }
+
+ public void setCommentWriter(Writer commentWriter) {
+ this.commentWriter = commentWriter;
+ }
+
+ public int getLineNumber() {
+ return reader.getLineNumber();
+ }
+
+ public int getLastDelimiter() {
+ return lastDelimiter;
+ }
+
+ public char nextCharacter() throws IOException {
+ if (lastChar == '\0') {
+ lastChar = readCharacter();
+ }
+ return (char)lastChar;
+ }
+
+ public char readCharacter() throws IOException {
+
+ skipSpace();
+
+ char ch = read();
+
+ while (hasComments && (ch == startComment || ch == lineComment)) {
+ skipComments(ch);
+ skipSpace();
+ ch = read();
+ }
+
+ return ch;
+ }
+
+ public void unreadCharacter(char ch) {
+ lastChar = ch;
+ }
+
+ public char next() throws IOException {
+ if (lastChar == '\0') {
+ lastChar = read();
+ }
+ return (char)lastChar;
+ }
+
+ /**
+ * All read attempts pass through this function.
+ *
+ * @return the next char
+ * @throws IOException
+ */
+ public char read() throws IOException {
+ int ch;
+ if (lastChar == '\0') {
+ // this is the only point where anything is read from the reader
+ ch = reader.read();
+ if (ch != -1) {
+ totalCharactersRead++;
+ } else {
+ throw new EOFException();
+ }
+ } else {
+ ch = lastChar;
+ lastChar = '\0';
+ }
+ return (char)ch;
+ }
+
+ /**
+ * Reads a line, skipping over any comments.
+ */
+ public String readLine() throws IOException {
+
+ StringBuffer line = new StringBuffer();
+ char ch = read();
+ try {
+ while (ch != '\n' && ch != '\r') {
+ if (hasComments) {
+ if (ch == lineComment) {
+ skipComments(ch);
+ break;
+ }
+ if (ch == startComment) {
+ skipComments(ch);
+ ch = read();
+ }
+ }
+ line.append(ch);
+ ch = read();
+ }
+
+ // accommodate DOS line endings..
+ if (ch == '\r') {
+ if (next() == '\n') read();
+ }
+ lastDelimiter = ch;
+
+ } catch (EOFException e) {
+ // We catch an EOF and return the line we have so far
+// encounteredEndOfFile();
+ }
+
+ return line.toString();
+ }
+
+ /**
+ * Attempts to read and parse an integer delimited by whitespace.
+ */
+ public int readInteger() throws IOException, ImportException {
+ String token = readToken();
+ try {
+ return Integer.parseInt(token);
+ } catch (NumberFormatException nfe) {
+ throw new ImportException("Number format error: " + nfe.getMessage());
+ }
+ }
+
+ /**
+ * Attempts to read and parse an integer delimited by whitespace or by
+ * any character in delimiters.
+ */
+ public int readInteger(String delimiters) throws IOException, ImportException {
+ String token = readToken(delimiters);
+ try {
+ return Integer.parseInt(token);
+ } catch (NumberFormatException nfe) {
+ throw new ImportException("Number format error: " + nfe.getMessage());
+ }
+ }
+
+ /**
+ * Attempts to read and parse a double delimited by whitespace.
+ */
+ public double readDouble() throws IOException, ImportException {
+ String token = readToken();
+ try {
+ return Double.parseDouble(token);
+ } catch (NumberFormatException nfe) {
+ throw new ImportException("Number format error: " + nfe.getMessage());
+ }
+ }
+
+ /**
+ * Attempts to read and parse a double delimited by whitespace or by
+ * any character in delimiters.
+ */
+ public double readDouble(String delimiters) throws IOException, ImportException {
+ String token = readToken(delimiters);
+ try {
+ return Double.parseDouble(token);
+ } catch (NumberFormatException nfe) {
+ throw new ImportException("Number format error: " + nfe.getMessage());
+ }
+ }
+
+ /**
+ * Reads a token stopping when any whitespace or a comment is found.
+ * If the token begins with a quote char then all characters will be
+ * included in token until a matching quote is found (including whitespace or comments).
+ */
+ public String readToken() throws IOException {
+ return readToken("");
+ }
+
+ /**
+ * Reads a token stopping when any whitespace, a comment or when any character
+ * in delimiters is found. If the token begins with a quote char
+ * then all characters will be included in token until a matching
+ * quote is found (including whitespace or comments).
+ */
+ public String readToken(String delimiters) throws IOException {
+ int space = 0;
+ char ch, ch2, quoteChar = '\0';
+ boolean done = false, first = true, quoted = false, isSpace;
+
+ nextCharacter();
+
+ StringBuffer token = new StringBuffer();
+
+ while (!done) {
+ ch = read();
+
+ try {
+ isSpace = Character.isWhitespace(ch);
+
+ if (quoted && ch == quoteChar) { // Found the closing quote
+ ch2 = read();
+
+ if (ch == ch2) {
+ // A repeated quote character so add this to the token
+ token.append(ch);
+ } else {
+ // otherwise it terminates the token
+
+ lastDelimiter = ' ';
+
+ if (hasComments && (ch2 == startComment || ch2 == lineComment)) {
+ skipComments(ch2, startComment!= '\"' && startComment != '\'');
+ } else {
+ unreadCharacter(ch2);
+ }
+ done = true;
+ quoted = false;
+ }
+ } else if (first && (ch == '\'' || ch == '"')) {
+ // if the opening character is a quote
+ // read everything up to the closing quote
+ quoted = true;
+ quoteChar = ch;
+ first = false;
+ space = 0;
+ } else if (!quoted && (ch == startComment || ch == lineComment) ) {
+ // comment markers don't count if we are quoted
+ skipComments(ch, startComment!= '\"' && startComment != '\'');
+ lastDelimiter = ' ';
+ done = true;
+ } else {
+ if (quoted) {
+ token.append(ch);
+ } else if (isSpace) {
+ lastDelimiter = ' ';
+ done = true;
+ } else if (delimiters.indexOf(ch) != -1) {
+ done = true;
+ lastDelimiter = ch;
+ } else {
+ token.append(ch);
+ first = false;
+ }
+ }
+ } catch (EOFException e) {
+ // We catch an EOF and return the token we have so far
+ done = true;
+ }
+ }
+
+ if (Character.isWhitespace((char)lastDelimiter)) {
+ ch = nextCharacter();
+ while (Character.isWhitespace(ch)) {
+ read();
+ ch = nextCharacter();
+ }
+
+ if (delimiters.indexOf(ch) != -1) {
+ lastDelimiter = readCharacter();
+ }
+ }
+
+ return token.toString();
+ }
+
+ /**
+ * Skips over any comments. The opening comment delimiter is passed.
+ * @param delimiter
+ * @throws java.io.IOException
+ */
+ protected void skipComments(char delimiter) throws IOException {
+ skipComments(delimiter, false);
+ }
+
+ /**
+ * Skips over any comments. The opening comment delimiter is passed.
+ * @param delimiter
+ * @param gobbleStrings
+ * @throws java.io.IOException
+ */
+ protected void skipComments(char delimiter, boolean gobbleStrings) throws IOException {
+
+ char ch;
+ int n=1;
+ boolean write = true;
+ StringBuffer meta = null;
+
+ if (lastComment == null) {
+ lastComment = new StringBuffer();
+ }
+ if (nextCharacter() == writeComment) {
+ read();
+// if (commentWriter != null) {
+// commentWriter.write(writeComment);
+// }
+ } else if (nextCharacter() == metaComment) {
+ read();
+ meta = new StringBuffer();
+ write = false;
+ }
+ lastMetaComment = null;
+
+ if (delimiter == lineComment) {
+ String line = readLine();
+ if (write && commentWriter != null) {
+ commentWriter.write(line, 0, line.length());
+ commentWriter.write('\n');//.newLine();
+ } else if (meta != null) {
+ meta.append(line);
+ }
+ } else {
+ Character inString = null;
+ do {
+ ch = read();
+
+ if( ch == '\"' || ch == '\'' ) {
+ if( gobbleStrings ) {
+ if( inString == null ) {
+ inString = ch;
+ } else if( inString == ch ) {
+ inString = null;
+ }
+ }
+ }
+ if( inString == null ) {
+ if (ch == startComment) {
+ lastComment = new StringBuffer();
+ n++;
+ continue;
+ } else if (ch == stopComment) {
+ if (write && commentWriter != null) {
+ if (lastComment.toString().contains("ID")) {
+ commentWriter.write(lastComment.toString());
+ }
+ lastComment = new StringBuffer();
+ }
+// if (write && commentWriter != null) {
+// commentWriter.write('\n');//.newLine();
+// }
+ n--;
+ continue;
+ }
+ }
+
+ if (write && commentWriter != null) {
+ lastComment.append(ch);
+// commentWriter.write(ch);
+ } else if (meta != null) {
+ meta.append(ch);
+ }
+ } while (n > 0);
+
+ }
+
+ if (meta != null) {
+ lastMetaComment = meta.toString();
+ }
+ }
+
+ /**
+ * Skips to the end of the line. If a comment is found then this is read.
+ */
+ public void skipToEndOfLine() throws IOException {
+
+ char ch;
+
+ do {
+ ch = read();
+ if (hasComments) {
+ if (ch == lineComment) {
+ skipComments(ch);
+ break;
+ }
+ if (ch == startComment) {
+ skipComments(ch);
+ ch = read();
+ }
+ }
+
+ } while (ch != '\n' && ch != '\r');
+
+ if (ch == '\r') {
+ if (nextCharacter() == '\n') read();
+ }
+ }
+
+ /**
+ * Skips char any contiguous characters in skip. Will also skip
+ * comments.
+ */
+ public void skipWhile(String skip) throws IOException {
+
+ char ch;
+
+ do {
+ ch = read();
+ } while ( skip.indexOf(ch) > -1 );
+
+ unreadCharacter(ch);
+ }
+
+ /**
+ * Skips over any space (plus tabs and returns) in the file. Will also skip
+ * comments.
+ */
+ public void skipSpace() throws IOException {
+ skipWhile(" \t\r\n");
+ }
+
+ /**
+ * Skips over any contiguous characters in skip. Will also skip
+ * comments and space.
+ */
+ public void skipCharacters(String skip) throws IOException {
+ skipWhile(skip + " \t\r\n");
+ }
+
+ /**
+ * Skips over the file until a character from delimiters is found. Returns
+ * the delimiter found. Will skip comments and will ignore delimiters within
+ * comments.
+ */
+ public char skipUntil(String skip) throws IOException {
+ char ch;
+
+ do {
+ ch = readCharacter();
+ } while ( skip.indexOf(ch) == -1 );
+
+ return ch;
+ }
+
+ public String getLastMetaComment() {
+ return lastMetaComment;
+ }
+
+ public void clearLastMetaComment() {
+ lastMetaComment = null;
+ }
+
+ static String safeName(String name) {
+ if( ! name.matches("[a-zA-Z0-9_.]+") ) {
+ name = "\"" + name + "\"";
+ }
+ return name;
+ }
+
+ /**
+ * Convert control (unprintable) characters to something printable
+ * @param token
+ * @return token printable version
+ */
+ static String convertControlsChars(String token) {
+ if( ! token.matches("[^\\p{Cntrl}]+") ) {
+ StringBuilder b = new StringBuilder();
+ for( char c : token.toCharArray() ) {
+ if( c < 0x20 || c >= 0xfe ) {
+ b.append("#").append(Integer.toHexString(c));
+ } else {
+ b.append(c);
+ }
+ }
+ return b.toString();
+ }
+ return token;
+ }
+
+ // Private stuff
+
+ private LineNumberReader reader;
+ private Writer commentWriter = null;
+
+ private int lastChar = '\0';
+ private int lastDelimiter = '\0';
+
+ private boolean hasComments = false;
+ private char startComment = (char)-1;
+ private char stopComment = (char)-1;
+ private char lineComment = (char)-1;
+ private char writeComment = (char)-1;
+ private char metaComment = (char)-1;
+
+ private StringBuffer lastComment;
+ private String lastMetaComment = null;
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusExporter.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusExporter.java
new file mode 100755
index 0000000..9250c53
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusExporter.java
@@ -0,0 +1,248 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.fileio;
+
+import es.uvigo.darwin.prottest.tree.TreeUtils;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import pal.tree.Tree;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class NexusExporter {
+
+ private static final String HEADER = "#NEXUS";
+ private File outFile;
+ private PrintWriter outputWriter;
+
+ private enum NexusBlock {
+
+ TAXA {
+
+ public void beginSection(PrintWriter outputWriter) {
+ outputWriter.println("begin taxa;");
+ }
+
+ public void endSection(PrintWriter outputWriter) {
+ outputWriter.println("end taxa;");
+ }
+
+ public String getSectionName() {
+ return "taxa";
+ }
+
+ public void export(PrintWriter outputWriter, List taxa, Properties properties) {
+
+ }
+ },
+ TREES {
+
+ public void beginSection(PrintWriter outputWriter) {
+ outputWriter.println("begin trees;");
+ }
+
+ public void endSection(PrintWriter outputWriter) {
+ outputWriter.println("end trees;");
+ }
+
+ public String getSectionName() {
+ return "trees";
+ }
+
+ public void export(PrintWriter outputWriter, List trees, Properties properties) {
+
+ printBlankLine(outputWriter);
+ for (Object o : trees) {
+ if (!(o instanceof Tree)) {
+ throw new TypeMismatchException(Tree.class, o.getClass());
+ }
+
+ Tree tree = (Tree) o;
+
+ boolean printCladeSupport = properties.getProperty(PRINT_CLADE_SUPPORT, "false").equalsIgnoreCase("true");
+ String treeName = (String) tree.getAttribute(tree.getRoot(), TreeUtils.TREE_NAME_ATTRIBUTE);
+ String treeNewick = TreeUtils.toNewick(tree, true, true, printCladeSupport);
+
+ outputWriter.print(" " + treeName + " = ");
+ outputWriter.println(treeNewick);
+ }
+ printBlankLine(outputWriter);
+
+ }
+ },
+ CONSENSUS {
+
+ public void beginSection(PrintWriter outputWriter) {
+ TREES.beginSection(outputWriter);
+ }
+
+ public void endSection(PrintWriter outputWriter) {
+ TREES.endSection(outputWriter);
+ }
+
+ public void export(PrintWriter outputWriter, List trees, Properties properties) {
+
+ printBlankLine(outputWriter);
+ String fullTreeComment = "Note: This tree contains information on the topology," +
+ " branch lengths (if present), and the probability " +
+ " of the partition indicated by the branch.";
+ addComment(outputWriter, fullTreeComment, 0);
+
+ properties.setProperty(PRINT_CLADE_SUPPORT, "true");
+ TREES.export(outputWriter, trees, properties);
+
+ String simpleTreeComment = "Note: This tree contains information only on the topology" +
+ " and branch lengths (mean of the posterior probability density).";
+ addComment(outputWriter, simpleTreeComment, 0);
+
+ properties.setProperty(PRINT_CLADE_SUPPORT, "false");
+ TREES.export(outputWriter, trees, properties);
+ printBlankLine(outputWriter);
+ }
+ },
+ DEFAULT {
+
+ public void beginSection(PrintWriter outputWriter) {
+ throw new UndefinedBlockException();
+ }
+
+ public void endSection(PrintWriter outputWriter) {
+ throw new UndefinedBlockException();
+ }
+
+ public void export(PrintWriter outputWriter, List objects, Properties properties) {
+ throw new UndefinedBlockException();
+ }
+ };
+ public static final String PRINT_CLADE_SUPPORT = "pcs";
+
+ public void addComment(PrintWriter outputWriter, String comment, int lineWidth) {
+
+ comment = "[" + comment + "] ";
+ int commentLength = comment.length();
+
+ if (lineWidth <= 0) {
+ lineWidth = comment.length();
+ }
+
+ int column = 0;
+ while (column < commentLength) {
+ String toWrite;
+ if (column + lineWidth + 1 < comment.length()) {
+ toWrite = comment.substring(column, column + lineWidth + 1);
+ } else {
+ toWrite = comment.substring(column);
+ }
+ int toWriteLength = toWrite.lastIndexOf(" ");
+ if (toWriteLength > 0 && toWriteLength < toWrite.length()) {
+ outputWriter.println(toWrite.substring(0, toWriteLength));
+ } else {
+ toWriteLength = lineWidth;
+ outputWriter.println(toWrite);
+ }
+ column += toWriteLength;
+ }
+
+ }
+
+ public void printBlankLine(PrintWriter outputWriter) {
+ outputWriter.println(" ");
+ }
+
+ public abstract void beginSection(PrintWriter outputWriter);
+
+ public abstract void endSection(PrintWriter outputWriter);
+
+ public abstract void export(PrintWriter outputWriter, List objects, Properties properties);
+
+ private static class TypeMismatchException extends ProtTestInternalException {
+
+ public TypeMismatchException(Class classRequired, Class classObtained) {
+ super("Required class " + classRequired + " but obtained " + classObtained);
+ }
+
+ }
+
+ private static class UndefinedBlockException extends ProtTestInternalException {
+
+ public UndefinedBlockException() {
+ super("No Nexus block is defined");
+ }
+
+ }
+ }
+
+ public NexusExporter(File outFile) throws IOException {
+
+ this.outFile = outFile;
+ if (!outFile.exists()) {
+ outFile.createNewFile();
+ }
+
+ this.outputWriter = new PrintWriter(outFile);
+
+ initStructure(this.outputWriter);
+
+ }
+
+ public void printTreeBlock(List<Tree> trees) {
+ NexusBlock treeBlock = NexusBlock.TREES;
+
+ treeBlock.beginSection(outputWriter);
+ treeBlock.export(outputWriter, trees, new Properties());
+ treeBlock.endSection(outputWriter);
+
+ }
+
+ public void printConsensusBlock(Tree tree, String id) {
+ NexusBlock treeBlock = NexusBlock.CONSENSUS;
+
+ List<Tree> trees = new ArrayList<Tree>();
+ trees.add(tree);
+
+ if (id != null) {
+ treeBlock.addComment(outputWriter, id, 0);
+ }
+ treeBlock.beginSection(outputWriter);
+ treeBlock.export(outputWriter, trees, new Properties());
+ treeBlock.endSection(outputWriter);
+
+ }
+
+ public void printComment(String msg, int colWidth) {
+ NexusBlock.DEFAULT.addComment(outputWriter, msg, colWidth);
+ }
+
+ public void close() {
+ outputWriter.close();
+ }
+
+ private void initStructure(PrintWriter outputWriter) {
+
+ outputWriter.println(HEADER);
+ outputWriter.println(" ");
+
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusImporter.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusImporter.java
new file mode 100755
index 0000000..92cd9ea
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusImporter.java
@@ -0,0 +1,686 @@
+package es.uvigo.darwin.prottest.util.fileio;
+
+/*
+ * NexusImporter.java
+ *
+ * (c) 2002-2005 JEBL development team
+ *
+ * This package may be distributed under the
+ * Lesser Gnu Public Licence (LGPL)
+ */
+import es.uvigo.darwin.prottest.util.attributable.Attributable;
+import es.uvigo.darwin.prottest.taxa.Taxon;
+import es.uvigo.darwin.prottest.tree.TreeUtils;
+import es.uvigo.darwin.prottest.util.exception.ImportException;
+import pal.tree.SimpleTree;
+import pal.tree.Tree;
+
+import java.awt.*;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.*;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import pal.misc.Identifier;
+import pal.tree.Node;
+import pal.tree.NodeFactory;
+
+/**
+ * Class for importing NEXUS file format
+ *
+ * @version $Id: NexusImporter.java 723 2007-06-11 05:40:44Z matt_kearse $
+ *
+ * @author Andrew Rambaut
+ * @author Alexei Drummond
+ */
+public class NexusImporter {
+
+ public enum NexusBlock {
+
+ UNKNOWN,
+ TAXA,
+ CHARACTERS,
+ DATA,
+ UNALIGNED,
+ DISTANCES,
+ TREES
+ }
+
+ private boolean compactTrees = false;
+ private Writer commentWriter;
+ private String nexusId;
+
+ public String getNexusId() {
+ return nexusId;
+ }
+
+ // NEXUS specific ImportException classes
+ public static class MissingBlockException extends ImportException {
+
+ public MissingBlockException() {
+ super();
+ }
+
+ public MissingBlockException(String message) {
+ super(message);
+ }
+ }
+
+ /**
+ * Constructor
+ */
+ public NexusImporter(Reader reader, long expectedLength) {
+ helper = new ImportHelper(reader);
+ helper.setExpectedInputLength(expectedLength);
+ initHelper();
+ }
+
+ /**
+ * Constructor
+ */
+ public NexusImporter(Reader reader) {
+ this(reader, 0);
+ }
+
+ public NexusImporter(Reader reader, boolean compactTrees, long expectedInputLength) {
+ this(reader, expectedInputLength);
+ this.compactTrees = compactTrees;
+ }
+
+ private void initHelper() {
+ // ! defines a comment to be written out to a log file
+ // & defines a meta comment
+ helper.setCommentDelimiters('[', ']', '\0', '!', '&');
+ commentWriter = new StringWriter();
+ helper.setCommentWriter(commentWriter);
+ }
+
+// public long findId() {
+//
+// }
+
+ /**
+ * This function returns an integer to specify what the
+ * next block in the file is. The internal variable nextBlock is also set to this
+ * value. This should be overridden to provide support for other blocks. Once
+ * the block is read in, nextBlock is automatically set to UNKNOWN_BLOCK by
+ * findEndBlock.
+ */
+ public NexusBlock findNextBlock() throws IOException {
+ findToken("BEGIN", true);
+ nextBlockName = helper.readToken(";").toUpperCase();
+ return findBlockName(nextBlockName);
+ }
+
+ /**
+ * This function returns an enum class to specify what the
+ * block given by blockName is.
+ */
+ private NexusBlock findBlockName(String blockName) {
+ try {
+ nextBlock = NexusBlock.valueOf(blockName);
+ } catch (IllegalArgumentException e) {
+ // handle unknown blocks. java 1.5 throws an exception in valueOf
+ nextBlock = null;
+ }
+
+ if (nextBlock == null) {
+ nextBlock = NexusBlock.UNKNOWN;
+ }
+
+ return nextBlock;
+ }
+
+ public String getNextBlockName() {
+ return nextBlockName;
+ }
+
+ /**
+ * Returns an iterator over a set of elements of type T.
+ *
+ * @return an Iterator.
+ */
+ public Iterator<Tree> iterator() {
+ return new Iterator<Tree>() {
+
+ public boolean hasNext() {
+ boolean hasNext = false;
+ try {
+ hasNext = hasTree();
+ } catch (IOException e) {
+ // deal with errors by stopping the iteration
+ } catch (ImportException e) {
+ // deal with errors by stopping the iteration
+ }
+ return hasNext;
+ }
+
+ public Tree next() {
+ Tree tree = null;
+ try {
+ tree = importNextTree();
+ } catch (IOException e) {
+ // deal with errors by stopping the iteration
+ } catch (ImportException e) {
+ // deal with errors by stopping the iteration
+ }
+ if (tree == null) {
+ throw new NoSuchElementException("No more trees in this file");
+ }
+ return tree;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException("operation is not supported by this Iterator");
+ }
+ };
+ }
+
+ /**
+ * Parses a 'TREES' block.
+ */
+ public List<Tree> parseTreesBlock(List<Taxon> taxonList) throws ImportException, IOException {
+ return readTreesBlock(taxonList);
+ }
+
+ // **************************************************************
+ // TreeImporter IMPLEMENTATION
+ // **************************************************************
+ private boolean isReadingTreesBlock = false;
+ private List<Taxon> treeTaxonList = null;
+ private Map<String, Taxon> translationList = Collections.emptyMap();
+ private Tree nextTree = null;
+ private String[] lastToken = new String[1];
+
+ /**
+ * return whether another tree is available.
+ */
+ public boolean hasTree() throws IOException, ImportException {
+ if (!isReadingTreesBlock) {
+ isReadingTreesBlock = startReadingTrees();
+ translationList = readTranslationList(treeTaxonList, lastToken);
+ }
+
+ if (!isReadingTreesBlock) {
+ return false;
+ }
+
+ if (nextTree == null) {
+ nextTree = readNextTree(lastToken);
+ }
+
+ return (nextTree != null);
+ }
+
+ /**
+ * import the next tree.
+ * return the tree or null if no more trees are available
+ */
+ public Tree importNextTree() throws IOException, ImportException {
+ // call hasTree to do the hard work...
+ if (!hasTree()) {
+ isReadingTreesBlock = false;
+ return null;
+ }
+
+ Tree tree = nextTree;
+ nextTree = null;
+
+ return tree;
+ }
+
+ public List<Tree> importTrees() throws IOException, ImportException {
+ isReadingTreesBlock = false;
+ if (!startReadingTrees()) {
+ throw new MissingBlockException("TREES block is missing");
+ }
+ List<Tree> treesBlock = readTreesBlock(treeTaxonList);
+ helper.closeReader();
+ nexusId = commentWriter.toString();
+ commentWriter.close();
+ return treesBlock;
+ }
+
+ public boolean startReadingTrees() throws IOException, ImportException {
+ treeTaxonList = null;
+
+ while (true) {
+ try {
+ NexusBlock block = findNextBlock();
+ switch (block) {
+// case TAXA: treeTaxonList = readTaxaBlock(); break;
+ case TREES:
+ return true;
+ // Ignore the block..
+ default:
+ break;
+ }
+ } catch (EOFException ex) {
+ break;
+ }
+ }
+
+ return false;
+ }
+
+ // **************************************************************
+ // DistanceMatrixImporter IMPLEMENTATION
+ // **************************************************************
+
+ // **************************************************************
+ // PRIVATE Methods
+ // **************************************************************
+ /**
+ * Finds the end of the current block.
+ */
+ private void findToken(String query, boolean ignoreCase) throws IOException {
+ String token;
+ boolean found = false;
+
+ do {
+ token = helper.readToken();
+
+ if ((ignoreCase && token.equalsIgnoreCase(query)) || token.equals(query)) {
+ found = true;
+ }
+ } while (!found);
+ }
+
+ /**
+ * Finds the end of the current block.
+ */
+ public void findEndBlock() throws IOException {
+ try {
+ String token;
+
+ do {
+ token = helper.readToken(";");
+ } while (!token.equalsIgnoreCase("END") && !token.equalsIgnoreCase("ENDBLOCK"));
+ } catch (EOFException e) {
+ // Doesn't matter if the End is missing
+ }
+
+ nextBlock = NexusBlock.UNKNOWN;
+ }
+
+ /**
+ * Reads a 'TREES' block.
+ */
+ private List<Tree> readTreesBlock(List<Taxon> taxonList) throws ImportException, IOException {
+ List<Tree> trees = new ArrayList<Tree>();
+ double cumWeight = 0.0;
+
+ String[] localLastToken = new String[1];
+ translationList = readTranslationList(taxonList, localLastToken);
+
+ while (true) {
+
+ SimpleTree tree = readNextTree(localLastToken);
+
+ if (tree == null) {
+ break;
+ }
+
+ cumWeight += (Double) tree.getAttribute(tree.getRoot(), TreeUtils.TREE_WEIGHT_ATTRIBUTE);
+ trees.add(tree);
+
+ }
+
+ if (trees.size() == 0) {
+ throw new ImportException.BadFormatException("No trees defined in TREES block");
+ }
+
+ if (cumWeight > 1.0) {
+ // normalization is required
+ for (Tree tree : trees) {
+ double treeWeight = (Double) tree.getAttribute(tree.getRoot(), TreeUtils.TREE_WEIGHT_ATTRIBUTE);
+ treeWeight /= cumWeight;
+ tree.setAttribute(tree.getRoot(), TreeUtils.TREE_WEIGHT_ATTRIBUTE, treeWeight);
+ }
+ }
+
+ nextBlock = NexusBlock.UNKNOWN;
+
+ return trees;
+ }
+
+ private Map<String, Taxon> readTranslationList(List<Taxon> taxonList, String[] lastToken) throws ImportException, IOException {
+ Map<String, Taxon> localTranslationList = new HashMap<String, Taxon>();
+
+ String token = helper.readToken(";");
+
+ if (token.equalsIgnoreCase("TRANSLATE")) {
+
+ do {
+ String token2 = helper.readToken(",;");
+
+ if (helper.getLastDelimiter() == ',' || helper.getLastDelimiter() == ';') {
+ if (token2.length() == 0 && (char) helper.getLastDelimiter() == ';') {
+ //assume an extra comma at end of list
+ break;
+
+ }
+ throw new ImportException.BadFormatException("Missing taxon label in TRANSLATE command of TREES block");
+ }
+
+ String token3 = helper.readToken(",;");
+
+ if (helper.getLastDelimiter() != ',' && helper.getLastDelimiter() != ';') {
+ throw new ImportException.BadFormatException("Expecting ',' or ';' after taxon label in TRANSLATE command of TREES block");
+ }
+
+ Taxon taxon = Taxon.getTaxon(token3);
+
+ if (taxonList != null && !taxonList.contains(taxon)) {
+ // taxon not found in taxon list...
+ // ...perhaps it is a numerical taxon reference?
+ throw new ImportException.UnknownTaxonException(token3);
+ }
+ localTranslationList.put(token2, taxon);
+
+ } while (helper.getLastDelimiter() != ';');
+
+ token = helper.readToken(";");
+
+ } else if (taxonList != null) {
+ for (Taxon taxon : taxonList) {
+ localTranslationList.put(taxon.getName(), taxon);
+ }
+ }
+
+ lastToken[0] = token;
+
+ return localTranslationList;
+ }
+
+ private SimpleTree readNextTree(String[] lastToken) throws ImportException, IOException {
+ try {
+ SimpleTree tree = null;
+ String token = lastToken[0];
+ double weight;
+ String treeName;
+
+ boolean isUnrooted = token.equalsIgnoreCase("UTREE");
+ if (isUnrooted || token.equalsIgnoreCase("TREE")) {
+
+ if (helper.nextCharacter() == '*') {
+ // Star is used to specify a default tree - ignore it
+ helper.readCharacter();
+ }
+
+ final String meta = helper.getLastMetaComment();
+ if (meta != null) {
+ // Look for the unrooted meta comment [&U]
+ if (meta.equalsIgnoreCase("U")) {
+ isUnrooted = true;
+ }
+ helper.clearLastMetaComment();
+ }
+
+ treeName = helper.readToken("=;");
+
+ if (helper.getLastDelimiter() != '=') {
+ throw new ImportException.BadFormatException("Missing label for tree'" + treeName + "' or missing '=' in TREE command of TREES block");
+ }
+
+ try {
+
+ if (helper.nextCharacter() != '(') {
+ throw new ImportException.BadFormatException("Missing tree definition in TREE command of TREES block");
+ }
+
+ // Save tree comment and attach it later
+ final String comment = helper.getLastMetaComment();
+ helper.clearLastMetaComment();
+
+ Node internalNode = readInternalNode();
+ tree = new SimpleTree(internalNode);
+
+ int last = helper.getLastDelimiter();
+ if (last == ':') {
+ // root length - discard for now
+ /*double rootLength = */ helper.readDouble(";");
+ last = helper.getLastDelimiter();
+ }
+
+ if (last != ';') {
+ throw new ImportException.BadFormatException("Expecting ';' after tree, '" + treeName + "', TREE command of TREES block");
+ }
+
+ weight = 1.0;
+ if (comment != null) {
+ // if '[W number]' (MrBayes), set weight attribute
+ // ignore any other comment
+ if (comment.matches("^W\\s+[\\+\\-]?[\\d\\.]+")) {
+ weight = new Double(comment.substring(2));
+ }
+ }
+ tree.setAttribute(internalNode, TreeUtils.TREE_WEIGHT_ATTRIBUTE, weight);
+ tree.setAttribute(internalNode, TreeUtils.TREE_NAME_ATTRIBUTE, treeName);
+
+ } catch (EOFException e) {
+ // If we reach EOF we may as well return what we have?
+ return tree;
+ }
+
+ token = helper.readToken(";");
+ } else if (token.equalsIgnoreCase("ENDBLOCK") || token.equalsIgnoreCase("END")) {
+ return null;
+ } else {
+ throw new ImportException.BadFormatException("Unknown command '" + token + "' in TREES block");
+ }
+
+ //added this to escape readNextTree loop correctly -- AJD
+ lastToken[0] = token;
+
+ return tree;
+
+ } catch (EOFException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Reads a branch in. This could be a node or a tip (calls readNode or readTip
+ * accordingly). It then reads the branch length and SimpleNode that will
+ * point at the new node or tip.
+ */
+ private Node readBranch() throws IOException, ImportException {
+ Node branch;
+
+ helper.clearLastMetaComment();
+ if (helper.nextCharacter() == '(') {
+ // is an internal node
+ branch = readInternalNode();
+
+ } else {
+ // is an external node
+ branch = readExternalNode();
+ }
+
+ if (helper.getLastDelimiter() == ':') {
+ final double length = helper.readDouble(",():;");
+ branch.setBranchLength(length);
+ }
+
+ return branch;
+ }
+
+ /**
+ * Reads a node in. This could be a polytomy. Calls readBranch on each branch
+ * in the node.
+ * @param tree
+ * @return
+ */
+ private Node readInternalNode() throws IOException, ImportException {
+ List<Node> children = new ArrayList<Node>();
+
+ // read the opening '('
+ helper.readCharacter();
+
+ // read the first child
+ children.add(readBranch());
+
+ if (helper.getLastDelimiter() != ',') {
+ //throw new ImportException.BadFormatException("Missing ',' in tree");
+ }
+ // MK: previously, an internal node must have at least 2 children.
+ // MK: We we now allow trees with a single child so that we can create proper taxonomy
+ // MK: trees with only a single child at a taxonomy level.
+
+ // read subsequent children
+
+ while (helper.getLastDelimiter() == ',') {
+ children.add(readBranch());
+ }
+
+ // should have had a closing ')'
+ if (helper.getLastDelimiter() != ')') {
+ throw new ImportException.BadFormatException("Missing closing ')' in tree");
+ }
+
+ Node node = NodeFactory.createNode(children.toArray(new Node[0]));
+
+ // find the next delimiter
+ String token = helper.readToken(":(),;").trim();
+
+ // if there is a token before the branch length, treat it as a node label
+ // and store it as an attribute of the node...
+ if (token.length() > 0) {
+ node.setIdentifier(new Identifier((String) parseValue(token)));
+ }
+
+ return node;
+ }
+
+ /**
+ * Reads an external node in.
+ */
+ private Node readExternalNode() throws ImportException, IOException {
+ String label = helper.readToken(":(),;");
+
+ Taxon taxon;
+ try {
+ taxon = Taxon.getTaxon(label);
+ } catch (IllegalArgumentException e) {
+ throw new ImportException.UnknownTaxonException(e.getMessage());
+ }
+
+ if (translationList.size() > 0) {
+ taxon = translationList.get(label);
+
+ if (taxon == null) {
+ // taxon not found in taxon list...
+ throw new ImportException.UnknownTaxonException("Taxon in tree, '" + label + "' is unknown");
+ }
+ }
+
+ try {
+ final Node node = NodeFactory.createNode(new Identifier(taxon.getName()));
+
+ return node;
+ } catch (IllegalArgumentException e) {
+ throw new ImportException.DuplicateTaxaException(e.getMessage());
+ }
+ }
+
+ static void parseMetaCommentPairs(String meta, Attributable item) throws ImportException.BadFormatException {
+ // This regex should match key=value pairs, separated by commas
+ // This can match the following types of meta comment pairs:
+ // value=number, value="string", value={item1, item2, item3}
+ // (label must be quoted if it contains spaces (i.e. "my label"=label)
+
+ Pattern pattern = Pattern.compile("(\"[^\"]*\"+|[^,=\\s]+)\\s*(=\\s*(\\{[^=}]*\\}|\"[^\"]*\"+|[^,]+))?");
+ Matcher matcher = pattern.matcher(meta);
+
+ while (matcher.find()) {
+ String label = matcher.group(1);
+ if (label.charAt(0) == '\"') {
+ label = label.substring(1, label.length() - 1);
+ }
+ if (label == null || label.trim().length() == 0) {
+ throw new ImportException.BadFormatException("Badly formatted attribute: '" + matcher.group() + "'");
+ }
+ final String value = matcher.group(2);
+ if (value != null && value.trim().length() > 0) {
+ // there is a specified value so try to parse it
+ item.setAttribute(label, parseValue(value.substring(1)));
+ } else {
+ item.setAttribute(label, Boolean.TRUE);
+ }
+ }
+ }
+
+ /**
+ * This method takes a string and tries to decode it returning the object
+ * that best fits the data. It will recognize command delimited lists enclosed
+ * in {..} and call parseValue() on each element. It will also recognize Boolean,
+ * Integer and Double. If the value starts with a # then it will attempt to decode
+ * the following integer as an RGB colour - see Color.decode(). If nothing else fits
+ * then the value will be returned as a string but trimmed of leading and trailing
+ * white space.
+ * @param value the string
+ * @return the object
+ */
+ static Object parseValue(String value) {
+
+ value = value.trim();
+
+ if (value.startsWith("{")) {
+ // the value is a list so recursively parse the elements
+ // and return an array
+ String[] elements = value.substring(1, value.length() - 1).split(",");
+ Object[] values = new Object[elements.length];
+ for (int i = 0; i < elements.length; i++) {
+ values[i] = parseValue(elements[i]);
+ }
+ return values;
+ }
+
+ if (value.startsWith("#")) {
+ // I am not sure whether this is a good idea but
+ // I am going to assume that a # denotes an RGB colour
+ try {
+ return Color.decode(value.substring(1));
+ } catch (NumberFormatException nfe1) {
+ // not a colour
+ }
+ }
+
+ // A string qouted by the nexus exporter and such
+ if (value.startsWith("\"") && value.endsWith("\"")) {
+ return value.subSequence(1, value.length() - 1);
+ }
+
+ if (value.equalsIgnoreCase("TRUE") || value.equalsIgnoreCase("FALSE")) {
+ return Boolean.valueOf(value);
+ }
+
+ // Attempt to format the value as an integer
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException nfe1) {
+ // not an integer
+ }
+
+ // Attempt to format the value as a double
+ try {
+ return Double.parseDouble(value);
+ } catch (NumberFormatException nfe2) {
+ // not a double
+ }
+
+ // return the trimmed string
+ return value;
+ }
+
+ // private stuff
+ private NexusBlock nextBlock = null;
+ private String nextBlockName = null;
+ protected final ImportHelper helper;
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusTreeReader.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusTreeReader.java
new file mode 100755
index 0000000..f829740
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/NexusTreeReader.java
@@ -0,0 +1,71 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.fileio;
+
+import es.uvigo.darwin.prottest.consensus.*;
+import es.uvigo.darwin.prottest.tree.TreeUtils;
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+import es.uvigo.darwin.prottest.util.exception.ImportException;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import pal.tree.Tree;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class NexusTreeReader extends TreeReader {
+
+ private NexusImporter imp;
+
+ public String getNexusId() {
+ return imp.getNexusId();
+ }
+
+ public NexusTreeReader(File treeFile) throws ImportException {
+
+ try {
+ FileReader fileReader = new FileReader(treeFile);
+ imp = new NexusImporter(fileReader);
+ List<Tree> importedTrees = imp.importTrees();
+ for (Tree tree : importedTrees) {
+ double weight = (Double) tree.getAttribute(tree.getRoot(), TreeUtils.TREE_WEIGHT_ATTRIBUTE);
+ trees.add(new WeightedTree(tree, weight));
+ cumWeight += weight;
+ if (idGroup == null) {
+ idGroup = TreeUtils.getLeafIdGroup(tree);
+ numTaxa = idGroup.getIdCount();
+ }
+ }
+ fileReader.close();
+ } catch (IOException ex) {
+ Logger.getLogger(NexusTreeReader.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ public static void main(String args[]) throws ImportException {
+ String filename = args[0];
+ File file = new File(filename);
+ NexusTreeReader ntr = new NexusTreeReader(file);
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/SimpleNewickTreeReader.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/SimpleNewickTreeReader.java
new file mode 100755
index 0000000..60847cf
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/SimpleNewickTreeReader.java
@@ -0,0 +1,135 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.fileio;
+
+import java.io.File;
+import java.util.List;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.PushbackReader;
+import java.io.PrintWriter;
+
+import pal.tree.Tree;
+
+import java.io.IOException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class SimpleNewickTreeReader extends TreeReader {
+
+ /** The first element. */
+ private static final int FIRST = 0;
+
+ public SimpleNewickTreeReader(File treeFile)
+ throws ProtTestInternalException, IOException {
+
+ FileReader fr = new FileReader(treeFile);
+ BufferedReader br = new BufferedReader(fr);
+
+ //PushbackReader in = new PushbackReader(fr);
+
+ try {
+ while (br.ready()) {
+ String line = br.readLine();
+ if (line == null || line.equals("")) {
+ break;
+ }
+
+ line = line.replace('[', ';');
+ line = line.replace(']', ';');
+ String[] values = line.split(";");
+ String weightStr = values[1];
+ double weight;
+ weight = Double.parseDouble(weightStr);
+
+ File tempFile = File.createTempFile("consensus", "tmp");
+ tempFile.deleteOnExit();
+ FileWriter fw = new FileWriter(tempFile);
+ BufferedWriter bw = new BufferedWriter(fw);
+ bw.write(values[0]);
+ bw.append(';');
+ bw.close();
+ fw.close();
+
+ PushbackReader in = new PushbackReader(new FileReader(tempFile));
+
+ PrintWriter out = new PrintWriter(System.out);
+ Tree tree = AlignmentReader.readTree(out, in, false);
+ out.flush();
+
+ addTree(trees, new WeightedTree(tree, weight));
+ }
+ } catch (TreeFormatException tfe) {
+ throw new ProtTestInternalException("Bad file format. Cannot parse tree");
+ } catch (NumberFormatException nfe) {
+ throw new ProtTestInternalException("Bad file format. Expecting double value");
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Adds a weighted tree to the set.
+ *
+ * @param wTree the weighted tree
+ *
+ * @return true, if successful
+ */
+ private boolean addTree(List<WeightedTree> trees, WeightedTree wTree) {
+ //check integrity
+ if (wTree.getTree() == null || wTree.getWeight() < 0.0) {
+ throw new ProtTestInternalException();
+ }
+ //check compatibility
+ if (trees.size() == 0) {
+ trees.add(wTree);
+ numTaxa = wTree.getTree().getIdCount();
+ idGroup = pal.tree.TreeUtils.getLeafIdGroup(wTree.getTree());
+ } else {
+ if (wTree.getTree().getIdCount() != numTaxa) {
+ return false;
+ }
+ Tree pTree = trees.get(FIRST).getTree();
+ for (int i = 0; i < numTaxa; i++) {
+ boolean found = false;
+ for (int j = 0; j < numTaxa; j++) {
+ if (wTree.getTree().getIdentifier(i).equals(pTree.getIdentifier(j))) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ System.out.println("NOT COMPATIBLE TREES");
+ return false;
+ }
+ }
+ trees.add(wTree);
+ }
+ cumWeight += wTree.getWeight();
+ return true;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/fileio/TreeReader.java b/src/main/java/es/uvigo/darwin/prottest/util/fileio/TreeReader.java
new file mode 100755
index 0000000..cec71fb
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/fileio/TreeReader.java
@@ -0,0 +1,43 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.fileio;
+
+import es.uvigo.darwin.prottest.tree.WeightedTree;
+import java.util.ArrayList;
+import java.util.List;
+import pal.misc.IdGroup;
+
+/**
+ *
+ * This class allows reading a set of trees from a file
+ *
+ * @author Diego Darriba
+ */
+public abstract class TreeReader {
+
+ protected int numTaxa;
+ protected IdGroup idGroup;
+ protected double cumWeight;
+ protected List<WeightedTree> trees = new ArrayList<WeightedTree>();
+
+ public int getNumTaxa(){ return numTaxa; }
+ public IdGroup getIdGroup() { return idGroup; }
+ public double getCumWeight() { return cumWeight; }
+ public List<WeightedTree> getWeightedTreeList() { return trees; }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogFormatter.java b/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogFormatter.java
new file mode 100755
index 0000000..05a6c71
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogFormatter.java
@@ -0,0 +1,47 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.logging;
+
+import java.util.logging.Formatter;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class ProtTestLogFormatter extends Formatter {
+
+ @Override
+ public String format(LogRecord lr) {
+
+ StringBuffer text = new StringBuffer();
+
+ if (lr.getLevel().intValue() < Level.FINE.intValue()) {
+ text.append(lr.getLevel().getName() + " : ");
+ }
+ if (lr.getLevel().intValue() == Level.WARNING.intValue()) {
+ text.append("WARNING: ");
+ }
+ text.append(lr.getMessage());
+
+ return text.toString();
+
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogger.java b/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogger.java
new file mode 100755
index 0000000..1d12961
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/logging/ProtTestLogger.java
@@ -0,0 +1,361 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.prottest.util.logging;
+
+import es.uvigo.darwin.prottest.util.WriterOutputStream;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.StreamHandler;
+
+public class ProtTestLogger {
+
+ public static final String DEFAULT_LOGGER_NAME = "default";
+ public static final Level DEFAULT_LEVEL = Level.INFO;
+
+ private static HashMap<String, ProtTestLogger> loggers;
+
+ static {
+
+ loggers = new HashMap<String, ProtTestLogger>();
+ ProtTestLogger defaultLogger = new ProtTestLogger(DEFAULT_LOGGER_NAME);
+ loggers.put(DEFAULT_LOGGER_NAME, defaultLogger);
+
+ }
+
+ private String loggerName;
+ private Level loggerLevel;
+ private List<Handler> handlers;
+ private Handler stdHandler;
+ private Handler lowLevelHandler = null;
+
+ public static ProtTestLogger getLogger(String loggerName, boolean force) {
+ if (!loggers.containsKey(loggerName)) {
+ if (force)
+ loggers.put(loggerName, new ProtTestLogger(loggerName));
+ else
+ return null;
+ }
+ return loggers.get(loggerName);
+ }
+
+ public static boolean exists(Class classLogger) {
+ return getLogger(classLogger.getName(), false) != null;
+ }
+
+ public ProtTestLogger(String loggerName) {
+ this.loggerName = loggerName;
+ if (loggers.containsKey(loggerName))
+ throw new ProtTestInternalException("ProtTestLogger with name "
+ + loggerName + " already exists. "
+ + " Use getLogger() instead");
+ this.loggerLevel = Level.ALL;
+
+ // Add standard output handler
+ this.handlers = new ArrayList<Handler>();
+ stdHandler = new StreamHandler(System.out, new ProtTestLogFormatter());
+ stdHandler.setLevel(Level.OFF);
+ handlers.add(stdHandler);
+ }
+
+ public static ProtTestLogger getDefaultLogger() {
+ return getLogger(DEFAULT_LOGGER_NAME, true);
+ }
+
+ /**
+ * Check if a message of the given level would actually be logged by this
+ * logger. This check is based on the Loggers effective level, which may be
+ * inherited from its parent.
+ *
+ * @param level
+ * a message logging level
+ * @return true if the given message level is currently being logged.
+ */
+ public boolean isLoggable(Level level) {
+ if (level.intValue() < loggerLevel.intValue()
+ || loggerLevel.intValue() == Level.OFF.intValue()) {
+ return false;
+ }
+ return true;
+ }
+
+ public void addHandler(Handler handler) {
+ if (handler == null) {
+ throw new NullPointerException();
+ }
+ this.handlers.add(handler);
+ }
+
+ public void addHandler(Handler[] newHandlers) {
+ for (Handler handler : newHandlers) {
+ if (handler == null) {
+ throw new NullPointerException();
+ }
+ if (!handlers.contains(handler))
+ this.handlers.add(handler);
+ }
+ }
+
+ public Handler addHandler(OutputStream out) {
+ return addHandler(out, DEFAULT_LEVEL);
+ }
+
+ public Handler addHandler(OutputStream out, Level level) {
+ if (out == null) {
+ throw new NullPointerException();
+ }
+ Handler handler = new StreamHandler(out, new ProtTestLogFormatter());
+ handler.setLevel(level);
+ this.handlers.add(handler);
+ return handler;
+ }
+
+ public Handler addHandler(Writer out) {
+ return addHandler(out, DEFAULT_LEVEL);
+ }
+
+ public Handler addHandler(Writer out, Level level) {
+ if (out == null) {
+ throw new NullPointerException();
+ }
+ Handler handler = new StreamHandler(new WriterOutputStream(out),
+ new ProtTestLogFormatter());
+ handler.setLevel(level);
+ this.handlers.add(handler);
+ return handler;
+ }
+
+ public Handler addLowLevelHandler(Writer out) {
+ if (out == null) {
+ throw new NullPointerException();
+ }
+ Handler handler = new StreamHandler(new WriterOutputStream(out),
+ new ProtTestLogFormatter());
+ handler.setLevel(Level.ALL);
+ lowLevelHandler = handler;
+ return handler;
+ }
+
+ public Handler getLowLevelHandler() {
+ return lowLevelHandler;
+ }
+
+ public boolean removeHandler(Handler handler) {
+ return this.handlers.remove(handler);
+ }
+
+ public Handler[] getHandlers() {
+ return handlers.toArray(new Handler[0]);
+ }
+
+ public void setStdHandlerLevel(Level newLevel) {
+ if (newLevel == null) {
+ throw new NullPointerException();
+ }
+ stdHandler.setLevel(newLevel);
+ }
+
+ public Level getStdHandlerLevel() {
+ return stdHandler.getLevel();
+ }
+
+ public void setLevel(Level newLevel) {
+ if (newLevel == null) {
+ throw new NullPointerException();
+ }
+ loggerLevel = newLevel;
+ }
+
+ public Level getLevel() {
+ return loggerLevel;
+ }
+
+ public void info(String text) {
+ log(Level.INFO, text);
+ }
+
+ public void warning(String text) {
+ log(Level.WARNING, text);
+ }
+
+ public void config(String text) {
+ log(Level.CONFIG, text);
+ }
+
+ public void severe(String text) {
+ log(Level.SEVERE, text);
+ }
+
+ public void fine(String text) {
+ log(Level.FINE, text);
+ }
+
+ public void finer(String text) {
+ log(Level.FINER, text);
+ }
+
+ public void finest(String text) {
+ log(Level.FINEST, text);
+ }
+
+ public void infoln(String text) {
+ log(Level.INFO, text + "\n");
+ flush();
+ }
+
+ public void warningln(String text) {
+ log(Level.WARNING, text + "\n");
+ flush();
+ }
+
+ public void configln(String text) {
+ log(Level.CONFIG, text + "\n");
+ flush();
+ }
+
+ public void severeln(String text) {
+ log(Level.SEVERE, text + "\n");
+ flush();
+ }
+
+ public void fineln(String text) {
+ log(Level.FINE, text + "\n");
+ flush();
+ }
+
+ public void finerln(String text) {
+ log(Level.FINER, text + "\n");
+ flush();
+ }
+
+ public void finestln(String text) {
+ log(Level.FINEST, text + "\n");
+ flush();
+ }
+
+ public static void info(String text, Class loggingClass) {
+ log(Level.INFO, text, loggingClass);
+ }
+
+ public static void warning(String text, Class loggingClass) {
+ log(Level.WARNING, text, loggingClass);
+ }
+
+ public static void config(String text, Class loggingClass) {
+ log(Level.CONFIG, text, loggingClass);
+ }
+
+ public static void severe(String text, Class loggingClass) {
+ log(Level.SEVERE, text, loggingClass);
+ }
+
+ public static void fine(String text, Class loggingClass) {
+ log(Level.FINE, text, loggingClass);
+ }
+
+ public static void finer(String text, Class loggingClass) {
+ log(Level.FINER, text, loggingClass);
+ }
+
+ public static void finest(String text, Class loggingClass) {
+ log(Level.FINEST, text, loggingClass);
+ }
+
+ public static void infoln(String text, Class loggingClass) {
+ log(Level.INFO, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void warningln(String text, Class loggingClass) {
+ log(Level.WARNING, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void configln(String text, Class loggingClass) {
+ log(Level.CONFIG, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void severeln(String text, Class loggingClass) {
+ log(Level.SEVERE, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void fineln(String text, Class loggingClass) {
+ log(Level.FINE, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void finerln(String text, Class loggingClass) {
+ log(Level.FINER, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void finestln(String text, Class loggingClass) {
+ log(Level.FINEST, text + "\n", loggingClass);
+ flush(loggingClass);
+ }
+
+ public static void log(Level level, String text, Class loggingClass) {
+ // default logging + class logging
+ getDefaultLogger().log(level, text);
+ if (exists(loggingClass))
+ getLogger(loggingClass.getName(), false).log(level, text);
+ }
+
+ public void log(Level level, String text) {
+ log(new LogRecord(level, text));
+ }
+
+ public void log(LogRecord lr) {
+
+ if (lr.getLevel().intValue() > loggerLevel.intValue()
+ && loggerLevel.intValue() != Level.OFF.intValue()) {
+
+ for (Handler handler : handlers)
+ handler.publish(lr);
+
+ }
+
+ }
+
+ public static void lowLevelLog(String text) {
+ if (getDefaultLogger().lowLevelHandler != null) {
+ LogRecord lr = new LogRecord(Level.INFO, text + "\n");
+ getDefaultLogger().lowLevelHandler.publish(lr);
+ getDefaultLogger().lowLevelHandler.flush();
+ }
+ }
+
+ public void flush() {
+ for (Handler handler : handlers)
+ handler.flush();
+ }
+
+ public static void flush(Class loggingClass) {
+ getDefaultLogger().flush();
+ if (exists(loggingClass))
+ getLogger(loggingClass.getName(), false).flush();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/package.html b/src/main/java/es/uvigo/darwin/prottest/util/package.html
new file mode 100755
index 0000000..4844b25
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/package.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+ @(#)package.html 3.0 2010/07/01
+
+Diego Darriba López
+Bioinformatics and Molecular Evolution Group
+Universidade de Vigo, Spain
+http://darwin.uvigo.es/
+-->
+
+</head>
+<body bgcolor="white">
+
+Contains common utilities for ProtTest-HPC.
+
+ at since 3.0
+
+</body>
+</html>
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestFormattedOutput.java b/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestFormattedOutput.java
new file mode 100755
index 0000000..7efd92f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestFormattedOutput.java
@@ -0,0 +1,182 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.printer;
+
+import java.io.PrintWriter;
+
+import pal.io.FormattedOutput;
+
+// TODO: Auto-generated Javadoc
+/**
+ * The Class ProtTestFormattedOutput.
+ */
+public class ProtTestFormattedOutput {
+
+ /** The Constant NAN. */
+ private static final String NAN = "NaN";
+ /** The formatter. */
+ private static FormattedOutput formatter;
+
+ static {
+ formatter = FormattedOutput.getInstance();
+ }
+
+ /**
+ * Space.
+ *
+ * @param size the size
+ * @param c the c
+ *
+ * @return the string
+ */
+ public static String space(int size, char c) {
+ return FormattedOutput.space(size, c);
+ }
+
+ /**
+ * Gets the decimal string.
+ *
+ * @param number the number
+ * @param width the width
+ *
+ * @return the decimal string
+ */
+ public static String getDecimalString(double number, int width) {
+ String strValue;
+ if (Double.isNaN(number))//.isInfinite(number))
+ {
+ strValue = NAN;
+ } else {
+ strValue = formatter.getDecimalString(number, width);
+ }
+
+ return strValue;
+ }
+
+ /**
+ * Display decimal.
+ *
+ * @param out the out
+ * @param number the number
+ * @param width the width
+ *
+ * @return the int
+ */
+ public static int displayDecimal(PrintWriter out, double number, int width) {
+ int result = 0;
+ if (Double.isNaN(number)) {
+ formatter.displayLabel(out, NAN, width);
+ result = NAN.length();
+ } else {
+ result = formatter.displayDecimal(out, number, width);
+ }
+
+ return result;
+ }
+
+ /**
+ * turns an integer into a String, aligned to a reference number,
+ * (introducing space at the left side)
+ *
+ * @param num number to be printed
+ * @param maxNum reference number
+ */
+ public static String getIntegerString(int num, int maxNum) {
+ StringBuffer sb = new StringBuffer();
+ int lenNum = Integer.toString(num).length();
+ int lenMaxNum = Integer.toString(maxNum).length();
+
+ if (lenNum < lenMaxNum) {
+ for (int i = 0; i < num; i++) {
+ sb.append(' ');
+ }
+ }
+ sb.append(num);
+
+ return sb.toString();
+ }
+
+ /**
+ * print integer, aligned to a reference number,
+ * (introducing space at the left side)
+ *
+ * @param out output stream
+ * @param num number to be printed
+ * @param maxNum reference number
+ */
+ public static void displayInteger(PrintWriter out, int num, int maxNum) {
+ int lenNum = Integer.toString(num).length();
+ int lenMaxNum = Integer.toString(maxNum).length();
+
+ if (lenNum < lenMaxNum) {
+ multiplePrint(out, ' ', lenMaxNum - lenNum);
+ }
+ out.print(num);
+ }
+
+ /**
+ * print whitespace of length of a string displaying a given integer
+ *
+ * @param out the writer
+ * @param maxNum the number of white spaces
+ */
+ public static void displayIntegerWhite(PrintWriter out, int maxNum) {
+ int lenMaxNum = Integer.toString(maxNum).length();
+
+ multiplePrint(out, ' ', lenMaxNum);
+ }
+
+ /**
+ * print label with a prespecified length
+ * (label will be shortened or spaces will introduced, if necessary)
+ *
+ * @param out output stream
+ * @param label label to be printed
+ * @param width desired length
+ */
+ public static void displayLabel(PrintWriter out, String label, int width) {
+ int len = label.length();
+
+ if (len == width) {
+ // Print as is
+ out.print(label);
+ } else if (len < width) {
+ // fill rest with spaces
+ out.print(label);
+ multiplePrint(out, ' ', width - len);
+ } else {
+ // Print first width characters
+ for (int i = 0; i < width; i++) {
+ out.print(label.charAt(i));
+ }
+ }
+ }
+
+ /**
+ * repeatedly print a character
+ *
+ * @param out output stream
+ * @param c character
+ * @param num number of repeats
+ */
+ public static void multiplePrint(PrintWriter out, char c, int num) {
+ for (int i = 0; i < num; i++) {
+ out.print(c);
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestPrinter.java b/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestPrinter.java
new file mode 100755
index 0000000..1a7cb51
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/prottest/util/printer/ProtTestPrinter.java
@@ -0,0 +1,200 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.prottest.util.printer;
+
+import java.io.PrintWriter;
+import java.util.Date;
+
+import es.uvigo.darwin.prottest.ProtTest;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import java.io.File;
+
+/**
+ * The Class ProtTestPrinter provides a common PrintWriter module to
+ * the whole application. It encapsulates both output and error
+ * PrintWriter.
+ */
+public class ProtTestPrinter {
+
+ private static final String H_RULE =
+ "********************************************************";
+ /** The output print writer. */
+ private PrintWriter out;
+ /** The error print writer. */
+ private PrintWriter err;
+
+ /**
+ * Instantiates a new ProtTestPrinter.
+ *
+ * @param out the output writer
+ * @param err the error writer
+ */
+ public ProtTestPrinter(PrintWriter out, PrintWriter err) {
+ this.out = out;
+ this.err = err;
+ }
+
+ /**
+ * Prints out the header section of the application.
+ */
+ public static void printHeader() {
+ println("");
+ println("");
+ println("ProtTest " + ProtTest.versionNumber
+ + ProtTestFormattedOutput.space(27 - ProtTest.versionNumber.length(), ' ') +
+ "Fast selection of the best-fit models of protein evolution");
+ println("(c) 2009-2010 Diego Darriba (1,2), Guillermo Taboada (2), Ramón Doallo (2), David Posada (1)");
+ println("(1) Facultad de Biologia, Universidad de Vigo, 36200 Vigo, Spain");
+ println("(2) Facultade de Informática, Universidade da Coruña, 15071 A Coruña, Spain");
+ println("Contact: ddarriba at udc.es, dposada at uvigo.es");
+ println("----------------------------------------------------------------------------------------------");
+ println("");
+ println((new Date()).toString());
+ println("OS = " + System.getProperty("os.name") +
+ " (" + System.getProperty("os.version") + ")");
+ println("");
+ println("Citation: Darriba D, Taboada GL, Doallo R, Posada D. ProtTest 3: fast selection of best-fit ");
+ println(" models of protein evolution. Bioinformatics, 27:1164-1165, 2011");
+ println("");
+ }
+
+ /**
+ * Prints out the header of the pre-analysis section.
+ */
+ public static void printPreAnalysisHeader() {
+ println("");
+ println(H_RULE);
+ println(center("ALIGNMENT ANALYSIS"));
+ println(H_RULE);
+ println("");
+ }
+
+ /**
+ * Prints out the header of the selection section
+ */
+ public static void printSelectionHeader(String criterionName) {
+ println("");
+ println("");
+ println(H_RULE);
+ println(center(criterionName));
+ println(H_RULE);
+ }
+
+ /**
+ * Prints out the header of the tree display
+ */
+ public static void printTreeHeader(String modelName) {
+ println("");
+ println(H_RULE);
+ println(center(modelName));
+ println(H_RULE);
+ println("");
+ }
+
+ public static void printExecutionHeader(ApplicationOptions options) {
+ println("");
+ println(H_RULE);
+ println(center("MODEL OPTIMIZATION"));
+ println(H_RULE);
+ options.reportModelOptimization();
+ println("");
+ }
+
+ /**
+ * Prints file data
+ */
+ public static void printFileData(File f) {
+ println("");
+ println("File: " + f.getAbsolutePath());
+ println("Size: " + f.length());
+ println("");
+ }
+ public static void println(String text) {
+ ProtTestLogger.infoln(text, ProtTestPrinter.class);
+ }
+
+ /**
+ * Prints out the footer section of the application.
+ */
+ public static void printFooter() {
+ println("");
+ println("");
+ println("ProtTest-HPC - " + ProtTest.versionNumber);
+ }
+ private static String center(String text) {
+ return ProtTestFormattedOutput.space((H_RULE.length() - text.length())/2, ' ') + text;
+ }
+
+ /**
+ * Gets the output writer.
+ *
+ * @return the output writer
+ */
+ public PrintWriter getOutputWriter() {
+ return out;
+ }
+
+ /**
+ * Sets the output writer.
+ *
+ * @param out the new output writer
+ */
+ public void setOutputWriter(PrintWriter out) {
+ this.out = out;
+ }
+
+ /**
+ * Gets the error writer.
+ *
+ * @return the error writer
+ */
+ public PrintWriter getErrorWriter() {
+ return err;
+ }
+
+ /**
+ * Sets the error writer.
+ *
+ * @param err the new error writer
+ */
+ public void setErrorWriter(PrintWriter err) {
+ this.err = err;
+ }
+
+ /**
+ * Flushes output writer.
+ */
+ public void flush() {
+ out.flush();
+ }
+
+ /**
+ * Flushes error writer.
+ */
+ public void flushError() {
+ err.flush();
+ }
+
+ /**
+ * Closes error writer.
+ */
+ public void closeError() {
+ err.close();
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/CreditsBox.java b/src/main/java/es/uvigo/darwin/xprottest/CreditsBox.java
new file mode 100755
index 0000000..47de742
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/CreditsBox.java
@@ -0,0 +1,80 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest;
+
+import javax.swing.GroupLayout;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.WindowConstants;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class CreditsBox extends JDialog {
+
+ /** Creates new form Credits */
+ public CreditsBox(java.awt.Frame parent) {
+ super(parent);
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ namesLabel = new JLabel();
+
+ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ setTitle("Credits"); // NOI18N
+ setAlwaysOnTop(true);
+
+ namesLabel.setText("Diego Darriba, Guillermo L.Taboada, Ramon Doallo, David Posada"); // NOI18N
+ namesLabel.setName("namesLabel"); // NOI18N
+
+ GroupLayout layout = new GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(namesLabel)
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(namesLabel)
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private JLabel namesLabel;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/PreferencesView.java b/src/main/java/es/uvigo/darwin/xprottest/PreferencesView.java
new file mode 100755
index 0000000..a1749dc
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/PreferencesView.java
@@ -0,0 +1,197 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest;
+
+import org.jdesktop.application.Action;
+/**
+ *
+ * @author Diego Darriba
+ */
+public class PreferencesView extends javax.swing.JFrame {
+
+ XProtTestView mainFrame;
+
+ /** Creates new form PreferencesView */
+ public PreferencesView(XProtTestView mainFrame) {
+ this.mainFrame = mainFrame;
+ initComponents();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ txtContinueDesc = new javax.swing.JTextArea();
+ lblErrorBehavior = new javax.swing.JLabel();
+ cmbErrorBehavior = new javax.swing.JComboBox();
+ btnAccept = new javax.swing.JButton();
+ btnCancel = new javax.swing.JButton();
+ lblContinue = new javax.swing.JLabel();
+ txtStopDesc = new javax.swing.JTextArea();
+ lblStop = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class).getContext().getResourceMap(PreferencesView.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setAlwaysOnTop(true);
+ setBackground(resourceMap.getColor("Form.background")); // NOI18N
+ setName("Form"); // NOI18N
+ setResizable(false);
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosed(java.awt.event.WindowEvent evt) {
+ onClose(evt);
+ }
+ });
+
+ txtContinueDesc.setBackground(resourceMap.getColor("Form.background")); // NOI18N
+ txtContinueDesc.setColumns(20);
+ txtContinueDesc.setEditable(false);
+ txtContinueDesc.setForeground(resourceMap.getColor("txtContinueDesc.foreground")); // NOI18N
+ txtContinueDesc.setRows(2);
+ txtContinueDesc.setText(resourceMap.getString("error-continue-desc")); // NOI18N
+ txtContinueDesc.setBorder(null);
+ txtContinueDesc.setName("txtContinueDesc"); // NOI18N
+ txtContinueDesc.setOpaque(false);
+
+ lblErrorBehavior.setText(resourceMap.getString("lblErrorBehavior.text")); // NOI18N
+ lblErrorBehavior.setName("lblErrorBehavior"); // NOI18N
+
+ cmbErrorBehavior.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Continue", "Stop" }));
+ cmbErrorBehavior.setSelectedIndex(mainFrame.getErrorBehavior());
+ cmbErrorBehavior.setName("cmbErrorBehavior"); // NOI18N
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class).getContext().getActionMap(PreferencesView.class, this);
+ btnAccept.setAction(actionMap.get("Accept")); // NOI18N
+ btnAccept.setText(resourceMap.getString("button-accept")); // NOI18N
+ btnAccept.setName("btnAccept"); // NOI18N
+
+ btnCancel.setAction(actionMap.get("Cancel")); // NOI18N
+ btnCancel.setText(resourceMap.getString("button-cancel")); // NOI18N
+ btnCancel.setName("btnCancel"); // NOI18N
+
+ lblContinue.setForeground(resourceMap.getColor("lblContinue.foreground")); // NOI18N
+ lblContinue.setText(resourceMap.getString("lblContinue.text")); // NOI18N
+ lblContinue.setName("lblContinue"); // NOI18N
+
+ txtStopDesc.setBackground(resourceMap.getColor("txtStopDesc.background")); // NOI18N
+ txtStopDesc.setColumns(20);
+ txtStopDesc.setEditable(false);
+ txtStopDesc.setForeground(resourceMap.getColor("txtStopDesc.foreground")); // NOI18N
+ txtStopDesc.setRows(2);
+ txtStopDesc.setText(resourceMap.getString("error-stop-desc")); // NOI18N
+ txtStopDesc.setBorder(null);
+ txtStopDesc.setName("txtStopDesc"); // NOI18N
+ txtStopDesc.setOpaque(false);
+
+ lblStop.setForeground(resourceMap.getColor("lblStop.foreground")); // NOI18N
+ lblStop.setText(resourceMap.getString("lblStop.text")); // NOI18N
+ lblStop.setName("lblStop"); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addGap(24, 24, 24)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblContinue)
+ .addComponent(lblStop, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(txtContinueDesc, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(btnAccept)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnCancel))
+ .addComponent(txtStopDesc, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE))))
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblErrorBehavior, javax.swing.GroupLayout.DEFAULT_SIZE, 303, Short.MAX_VALUE))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap(24, Short.MAX_VALUE)
+ .addComponent(cmbErrorBehavior, 0, 291, Short.MAX_VALUE)))
+ .addContainerGap())
+ );
+
+ layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {lblContinue, lblStop});
+
+ layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {txtContinueDesc, txtStopDesc});
+
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblErrorBehavior)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cmbErrorBehavior, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(lblContinue)
+ .addComponent(txtContinueDesc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(txtStopDesc, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblStop))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(btnCancel, javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(btnAccept, javax.swing.GroupLayout.Alignment.TRAILING))
+ .addContainerGap())
+ );
+
+ layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {lblContinue, lblStop});
+
+ layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {txtContinueDesc, txtStopDesc});
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void onClose(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_onClose
+ mainFrame.unloadPreferencesView();
+ }//GEN-LAST:event_onClose
+
+ @Action
+ public void Accept() {
+ mainFrame.setErrorBehavior(cmbErrorBehavior.getSelectedIndex());
+ this.dispose();
+ }
+
+ @Action
+ public void Cancel() {
+ this.dispose();
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnAccept;
+ private javax.swing.JButton btnCancel;
+ private javax.swing.JComboBox cmbErrorBehavior;
+ private javax.swing.JLabel lblContinue;
+ private javax.swing.JLabel lblErrorBehavior;
+ private javax.swing.JLabel lblStop;
+ private javax.swing.JTextArea txtContinueDesc;
+ private javax.swing.JTextArea txtStopDesc;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/XProtTestAboutBox.java b/src/main/java/es/uvigo/darwin/xprottest/XProtTestAboutBox.java
new file mode 100755
index 0000000..eaff622
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/XProtTestAboutBox.java
@@ -0,0 +1,229 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.xprottest;
+
+import javax.swing.ActionMap;
+import javax.swing.GroupLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.LayoutStyle;
+import javax.swing.WindowConstants;
+
+import org.jdesktop.application.Action;
+
+public class XProtTestAboutBox extends JDialog {
+
+ public XProtTestAboutBox(java.awt.Frame parent) {
+ super(parent);
+ initComponents();
+ getRootPane().setDefaultButton(closeButton);
+ }
+
+ @Action
+ public void closeAboutBox() {
+ setVisible(false);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed"
+ // desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ closeButton = new JButton();
+ JLabel appTitleLabel = new JLabel();
+ JLabel versionLabel = new JLabel();
+ JLabel appVersionLabel = new JLabel();
+ JLabel homepageLabel = new JLabel();
+ JLabel appHomepageLabel = new JLabel();
+ JLabel citationLabel = new JLabel();
+ JLabel appCitation1Label = new JLabel();
+ JLabel appCitation2Label = new JLabel();
+ JLabel appDescLabel = new JLabel();
+ JLabel imageLabel = new JLabel();
+
+ setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(XProtTestAboutBox.class);
+ setTitle(resourceMap.getString("title")); // NOI18N
+ setModal(true);
+ setName("aboutBox"); // NOI18N
+ setResizable(false);
+
+ ActionMap actionMap = org.jdesktop.application.Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getActionMap(XProtTestAboutBox.class, this);
+ closeButton.setAction(actionMap.get("closeAboutBox")); // NOI18N
+ closeButton.setName("closeButton"); // NOI18N
+
+ appTitleLabel.setFont(appTitleLabel.getFont().deriveFont(
+ appTitleLabel.getFont().getStyle() | java.awt.Font.BOLD,
+ appTitleLabel.getFont().getSize() + 4));
+ appTitleLabel.setText(resourceMap.getString("Application.title")); // NOI18N
+ appTitleLabel.setName("appTitleLabel"); // NOI18N
+
+ versionLabel.setFont(versionLabel.getFont().deriveFont(
+ versionLabel.getFont().getStyle() | java.awt.Font.BOLD));
+ versionLabel.setText(resourceMap.getString("versionLabel.text")); // NOI18N
+ versionLabel.setName("versionLabel"); // NOI18N
+
+ appVersionLabel.setText(resourceMap.getString("Application.version")); // NOI18N
+ appVersionLabel.setName("appVersionLabel"); // NOI18N
+
+ homepageLabel.setFont(homepageLabel.getFont().deriveFont(
+ homepageLabel.getFont().getStyle() | java.awt.Font.BOLD));
+ homepageLabel.setText(resourceMap.getString("homepageLabel.text")); // NOI18N
+ homepageLabel.setName("homepageLabel"); // NOI18N
+
+ appHomepageLabel.setText(resourceMap.getString("Application.homepage")); // NOI18N
+ appHomepageLabel.setName("appHomepageLabel"); // NOI18N
+
+ citationLabel.setFont(citationLabel.getFont().deriveFont(
+ citationLabel.getFont().getStyle() | java.awt.Font.BOLD));
+ citationLabel.setText(resourceMap.getString("citationLabel.text")); // NOI18N
+ citationLabel.setName("citationLabel"); // NOI18N
+
+ appCitation1Label.setText(resourceMap.getString("Application.citation1")); // NOI18N
+ appCitation1Label.setName("appCitationLabel"); // NOI18N
+ appCitation2Label.setText(resourceMap.getString("Application.citation2")); // NOI18N
+ appCitation2Label.setName("appCitationLabel"); // NOI18N
+
+ appDescLabel.setText(resourceMap.getString("appDescLabel.text")); // NOI18N
+ appDescLabel.setName("appDescLabel"); // NOI18N
+
+ imageLabel.setIcon(resourceMap.getIcon("imageLabel.icon")); // NOI18N
+ imageLabel.setName("imageLabel"); // NOI18N
+
+ GroupLayout layout = new GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(layout
+ .createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(imageLabel)
+ .addGap(18, 18, 18)
+ .addGroup(
+ layout.createParallelGroup(
+ GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(
+ versionLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ appVersionLabel)
+ .addGap(238,
+ 238,
+ 238))
+ .addComponent(appTitleLabel)
+ .addComponent(
+ appDescLabel,
+ GroupLayout.DEFAULT_SIZE,
+ 367, Short.MAX_VALUE)
+ .addComponent(
+ closeButton,
+ GroupLayout.Alignment.TRAILING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(
+ homepageLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ appHomepageLabel,
+ GroupLayout.DEFAULT_SIZE,
+ 289,
+ Short.MAX_VALUE))
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(
+ citationLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ appCitation1Label,
+ GroupLayout.DEFAULT_SIZE,
+ 289,
+ Short.MAX_VALUE))
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(
+ citationLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ appCitation2Label,
+ GroupLayout.DEFAULT_SIZE,
+ 289,
+ Short.MAX_VALUE)))
+ .addContainerGap()));
+ layout.setVerticalGroup(layout
+ .createParallelGroup(GroupLayout.Alignment.LEADING)
+ .addComponent(imageLabel, GroupLayout.PREFERRED_SIZE, 190,
+ Short.MAX_VALUE)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(appTitleLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(appDescLabel)
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(versionLabel)
+ .addComponent(appVersionLabel))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(homepageLabel)
+ .addComponent(appHomepageLabel))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(citationLabel)
+ .addComponent(appCitation1Label))
+ .addGroup(
+ layout.createParallelGroup(
+ GroupLayout.Alignment.BASELINE)
+ .addComponent(appCitation2Label))
+ .addPreferredGap(
+ LayoutStyle.ComponentPlacement.RELATED,
+ 63, Short.MAX_VALUE)
+ .addComponent(closeButton).addContainerGap()));
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private JButton closeButton;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/XProtTestApp.java b/src/main/java/es/uvigo/darwin/xprottest/XProtTestApp.java
new file mode 100755
index 0000000..7a7b53b
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/XProtTestApp.java
@@ -0,0 +1,97 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest;
+
+import org.jdesktop.application.Application;
+import org.jdesktop.application.SingleFrameApplication;
+import es.uvigo.darwin.prottest.facade.ProtTestFacade;
+import es.uvigo.darwin.prottest.facade.ProtTestFacadeThread;
+import es.uvigo.darwin.prottest.util.Utilities;
+import java.awt.Font;
+import java.io.File;
+import javax.swing.JFileChooser;
+
+/**
+ * The main class of the application.
+ */
+public class XProtTestApp extends SingleFrameApplication {
+
+ public static final int ERROR_BEHAVIOR_CONTINUE = 0;
+ public static final int ERROR_BEHAVIOR_STOP = 1;
+ public static final Font FONT_CONSOLE;
+ public static final Font FONT_LABEL;
+ public static final Font FONT_PANEL_TITLE;
+ public static final Font FONT_OPTION_LABEL;
+
+ private ProtTestFacade prottestFacade;
+
+ static {
+ if (Utilities.isWindows() == false) {
+ FONT_CONSOLE = new Font(Font.MONOSPACED, 0, 10);
+ } else {
+ FONT_CONSOLE = new Font("Lucida Console", 0, 11);
+ }
+ FONT_LABEL = new Font("Application", 1, 9);
+ FONT_OPTION_LABEL = new Font("Application", 0, 10);
+ FONT_PANEL_TITLE = new Font("Application", 1, 10);
+ }
+
+ /**
+ * At startup create and show the main frame of the application.
+ */
+ @Override
+ protected void startup() {
+ prottestFacade = new ProtTestFacadeThread(
+ Runtime.getRuntime().availableProcessors());
+// prottestFacade = new ProtTestFacadeSequential();
+ XProtTestView view = new XProtTestView(this, prottestFacade);
+ show(view);
+ }
+
+ /**
+ * This method is to initialize the specified window by injecting resources.
+ * Windows shown in our application come fully initialized from the GUI
+ * builder, so this additional configuration is not needed.
+ */
+ @Override
+ protected void configureWindow(java.awt.Window root) {
+ }
+
+ /**
+ * A convenient static getter for the application instance.
+ * @return the instance of XProtTestApp
+ */
+ public static XProtTestApp getApplication() {
+ return Application.getInstance(XProtTestApp.class);
+ }
+
+ /**
+ * Main method launching the application.
+ */
+ public static void main(String[] args) {
+ launch(XProtTestApp.class, args);
+ }
+
+ public static JFileChooser createFileChooser(String title) {
+ JFileChooser fc = new JFileChooser();
+ fc.setDialogTitle(title);
+ fc.setFileFilter(fc.getAcceptAllFileFilter());
+ fc.setCurrentDirectory(new File("."));
+ return fc;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/XProtTestView.java b/src/main/java/es/uvigo/darwin/xprottest/XProtTestView.java
new file mode 100755
index 0000000..a72094a
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/XProtTestView.java
@@ -0,0 +1,1138 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.xprottest;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FileDialog;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.print.PrinterException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.ActionMap;
+import javax.swing.Icon;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.Timer;
+import javax.swing.plaf.BorderUIResource;
+
+import org.jdesktop.application.Action;
+import org.jdesktop.application.Application;
+import org.jdesktop.application.ApplicationContext;
+import org.jdesktop.application.FrameView;
+import org.jdesktop.application.ResourceMap;
+import org.jdesktop.application.SingleFrameApplication;
+import org.jdesktop.application.Task;
+import org.jdesktop.application.TaskMonitor;
+import org.jdesktop.application.TaskService;
+
+import pal.alignment.Alignment;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.ProtTest;
+import es.uvigo.darwin.prottest.facade.ProtTestFacade;
+import es.uvigo.darwin.prottest.facade.TreeFacade;
+import es.uvigo.darwin.prottest.facade.TreeFacadeImpl;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.factory.ProtTestFactory;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+import es.uvigo.darwin.prottest.util.printer.ProtTestPrinter;
+import es.uvigo.darwin.xprottest.analysis.FrequenciesView;
+import es.uvigo.darwin.xprottest.analysis.TreeView;
+import es.uvigo.darwin.xprottest.analysis.consensus.Consensus;
+import es.uvigo.darwin.xprottest.compute.OptionsView;
+import es.uvigo.darwin.xprottest.compute.RunningFrame;
+import es.uvigo.darwin.xprottest.results.ErrorLogView;
+import es.uvigo.darwin.xprottest.results.ResultsView;
+import es.uvigo.darwin.xprottest.util.BrowserLauncher;
+import es.uvigo.darwin.xprottest.util.TextAreaAppender;
+
+/**
+ * The XProtTest main frame offers whole connection between the application
+ * componentes providing the full functionality of ProtTest-HPC.
+ *
+ * @author Diego Darriba
+ */
+public final class XProtTestView extends FrameView {
+
+ /* Application colors */
+ public static final Color NORMAL_COLOR = Color.BLACK;
+ public static final Color CRITIC_COLOR = new Color(153, 0, 0);
+ public static final Color DONE_COLOR = new Color(102, 102, 153);
+ /* Settings */
+ private int errorBehavior;
+ /* General variables */
+ private ResourceMap resourceMap;
+ private Alignment alignment;
+ private Tree tree;
+ private ProtTestFacade prottestFacade;
+ private boolean alignmentLoaded;
+ private File alignmentFile;
+ private boolean lnlCalculated;
+ private Model[] models;
+ private PrintWriter displayWriter;
+ private Handler mainHandler;
+ private PrintWriter lowLevelDisplayWriter;
+ private Handler lowLevelHandler;
+ /* WINDOWS */
+ private ResultsView resultsView;
+ private TreeView treeView;
+ private Consensus consensusView;
+ private FrequenciesView frequenciesView;
+ private ErrorLogView errorLogView;
+
+ public int getErrorBehavior() {
+ return errorBehavior;
+ }
+
+ protected void setErrorBehavior(int errorBehavior) {
+ this.errorBehavior = errorBehavior;
+ }
+
+ public ProtTestFacade getFacade() {
+ return prottestFacade;
+ }
+
+ private void setAlignmentFile(File alignmentFile) {
+ enableHandler();
+ int numDecimals = 5;
+ alignmentLoaded = (alignmentFile != null);
+ if (alignmentLoaded) {
+ lblDataFileStatus.setText(resourceMap.getString("msg-data-loaded")
+ + " " + alignmentFile.getName());
+ lblDataFileStatus.setForeground(DONE_COLOR);
+ this.alignmentFile = alignmentFile;
+ showFrequenciesItem.setEnabled(true);
+ double[] frequencies = ProtTestAlignment.getFrequencies(alignment);
+ displayWriter.println("");
+ displayWriter.println(resourceMap.getString("aa-frequencies"));
+ displayWriter.println(ProtTestFormattedOutput.space(resourceMap
+ .getString("aa-frequencies").length(), '-'));
+
+ for (int i = 0; i < frequencies.length; i++) {
+ displayWriter.println(ProtTestAlignment.charOfIndex(i)
+ + " - "
+ + ProtTestFormattedOutput.getDecimalString(
+ frequencies[i], numDecimals));
+ }
+ } else {
+ lblDataFileStatus.setText(resourceMap.getString("msg-no-data"));
+ lblDataFileStatus.setForeground(CRITIC_COLOR);
+ showFrequenciesItem.setEnabled(false);
+ }
+ frequenciesView = null;
+ computeMenuItem.setEnabled(alignmentLoaded);
+ resultsMenuItem.setEnabled(false);
+ if (resultsView != null) {
+ resultsView.dispose();
+ resultsView = null;
+ }
+ showTreeMenuItem.setEnabled(false);
+ if (treeView != null) {
+ treeView.dispose();
+ treeView = null;
+ }
+ averagingMenuItem.setEnabled(false);
+ if (consensusView != null) {
+ consensusView.dispose();
+ consensusView = null;
+ }
+ disableHandler();
+ }
+
+ public PrintWriter getDisplayWriter() {
+ return displayWriter;
+ }
+
+ public XProtTestView(SingleFrameApplication app, ProtTestFacade facade) {
+ super(app);
+
+ resourceMap = Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(XProtTestView.class);
+
+ this.errorBehavior = Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(XProtTestApp.class)
+ .getInteger("default-error-behavior");
+
+ this.prottestFacade = facade;
+
+ initComponents();
+
+ displayWriter = new PrintWriter(new TextAreaAppender(mainTextArea));
+ lowLevelDisplayWriter = new PrintWriter(new TextAreaAppender(
+ phymlTextArea));
+
+ mainHandler = ProtTestLogger.getDefaultLogger().addHandler(
+ displayWriter);
+ lowLevelHandler = ProtTestLogger.getDefaultLogger().addLowLevelHandler(
+ lowLevelDisplayWriter);
+ try {
+ Handler logHandler = ProtTestFactory.getInstance()
+ .createLogHandler();
+ if (logHandler != null) {
+ ProtTestLogger.getDefaultLogger().addHandler(logHandler);
+ }
+ } catch (IOException ex) {
+ ProtTestLogger.getDefaultLogger().severeln(ex.getMessage());
+ }
+ // status bar initialization - message timeout, idle icon and busy
+ // animation, etc
+
+ int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
+ messageTimer = new Timer(messageTimeout, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ lblLikelihoodStatus.setText("");
+ }
+ });
+ messageTimer.setRepeats(false);
+ int busyAnimationRate = resourceMap
+ .getInteger("StatusBar.busyAnimationRate");
+ for (int i = 0; i < busyIcons.length; i++) {
+ busyIcons[i] = resourceMap
+ .getIcon("StatusBar.busyIcons[" + i + "]");
+ }
+ busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
+ lblDataFileStatus.setIcon(busyIcons[busyIconIndex]);
+ }
+ });
+ idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
+ lblDataFileStatus.setIcon(idleIcon);
+
+ TaskMonitor taskMonitor = new TaskMonitor(getApplication().getContext());
+ taskMonitor
+ .addPropertyChangeListener(new java.beans.PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(
+ java.beans.PropertyChangeEvent evt) {
+ String propertyName = evt.getPropertyName();
+ if ("started".equals(propertyName)) {
+ if (!busyIconTimer.isRunning()) {
+ lblDataFileStatus.setIcon(busyIcons[0]);
+ busyIconIndex = 0;
+ busyIconTimer.start();
+ }
+ } else if ("done".equals(propertyName)) {
+ busyIconTimer.stop();
+ lblDataFileStatus.setIcon(idleIcon);
+ } else if ("message".equals(propertyName)) {
+ String text = (String) (evt.getNewValue());
+ lblLikelihoodStatus.setText((text == null) ? ""
+ : text);
+ messageTimer.restart();
+ } else if ("progress".equals(propertyName)) {
+ int value = (Integer) (evt.getNewValue());
+ }
+ }
+ });
+ lblMoreInfo.setVisible(false);
+
+ ProtTestPrinter.printHeader();
+ disableHandler();
+ }
+
+ public void disableHandler() {
+ mainHandler.setLevel(Level.OFF);
+ }
+
+ public void enableHandler() {
+ mainHandler.setLevel(Level.INFO);
+ }
+
+ @Action
+ public void showAboutBox() {
+ if (aboutBox == null) {
+ JFrame mainFrame = XProtTestApp.getApplication().getMainFrame();
+ aboutBox = new XProtTestAboutBox(mainFrame);
+ aboutBox.setLocationRelativeTo(mainFrame);
+ }
+ aboutBox.setVisible(true);
+ }
+
+ @Action
+ public void showCreditsBox() {
+ if (creditsBox == null) {
+ JFrame mainFrame = XProtTestApp.getApplication().getMainFrame();
+ creditsBox = new CreditsBox(mainFrame);
+ creditsBox.setLocationRelativeTo(mainFrame);
+ }
+ creditsBox.setVisible(true);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ private void initComponents() {
+
+ mainPanel = new JPanel();
+ mainTabbedPane = new JTabbedPane();
+ mainScrollPane = new JScrollPane();
+ mainTextArea = new JTextArea();
+ phymlScrollPane = new JScrollPane();
+ phymlTextArea = new JTextArea();
+ statusPanel = new JPanel();
+ lblDataFileStatus = new JLabel();
+ lblLikelihoodStatus = new JLabel();
+ lblMoreInfo = new JLabel();
+ menuBar = new JMenuBar();
+ fileMenu = new JMenu();
+ loadAlignmentMenuItem = new JMenuItem();
+ exitMenuItem = new JMenuItem();
+ saveConsoleMenuItem = new JMenuItem();
+ printConsoleMenuItem = new JMenuItem();
+ editMenu = new JMenu();
+ editCopyMenuItem = new JMenuItem();
+ editSelectAllMenuItem = new JMenuItem();
+ preferencesMenuItem = new JMenuItem();
+ analysisMenu = new JMenu();
+ computeMenuItem = new JMenuItem();
+ showFrequenciesItem = new JMenuItem();
+ showTreeMenuItem = new JMenuItem();
+ averagingMenuItem = new JMenuItem();
+ resultsMenu = new JMenu();
+ resultsMenuItem = new JMenuItem();
+ errorMenuItem = new JMenuItem();
+ helpMenu = new JMenu();
+ manualMenuItem = new JMenuItem();
+ aboutMenuItem = new JMenuItem();
+
+ org.jdesktop.application.ResourceMap appResourceMap = org.jdesktop.application.Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(XProtTestView.class);
+
+ mainPanel.setSize(new java.awt.Dimension(500, 860));
+ mainPanel.setBorder(new BorderUIResource.EmptyBorderUIResource(
+ new java.awt.Insets(20, 20, 20, 20)));
+ mainPanel.setLocation(new java.awt.Point(10, -10));
+ mainPanel.setVisible(true);
+ mainPanel.setAutoscrolls(true);
+ mainPanel.setLayout(new BorderLayout());
+ mainPanel.setBackground(null);
+
+ // mainPanel.setBackground(resourceMap.getColor("mainPanel.background"));
+ mainPanel.setName("mainPanel");
+ // mainPanel.setPreferredSize(new java.awt.Dimension(500, 600));
+
+ mainScrollPane.setSize(590, 800);// new java.awt.Dimension(590, 600));
+ mainScrollPane.setLocation(new java.awt.Point(20, 20));
+ mainScrollPane.setVisible(true);
+ mainScrollPane.setAutoscrolls(true);
+
+ mainScrollPane.setName("mainScrollPane");
+ // mainScrollPane.setPreferredSize(new java.awt.Dimension(460, 500));
+
+ mainTextArea.setMargin(new Insets(5, 5, 5, 5));
+ mainTextArea.setBackground(Color.white);
+ mainTextArea.setEditable(false);
+ mainTextArea.setSize(500, 800);// new java.awt.Dimension(15, 10));
+ mainTextArea.setAutoscrolls(true);
+ mainTextArea.setVisible(true);
+
+ // mainTextArea.setColumns(15);
+ // mainTextArea.setEditable(false);
+ mainTextArea.setFont(XProtTestApp.FONT_CONSOLE);
+ // mainTextArea.setRows(30);
+ mainTextArea.setName("mainTextArea");
+ // mainScrollPane.setViewportView(mainTextArea);
+ mainScrollPane
+ .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ mainTextArea.setWrapStyleWord(true);
+ mainTextArea.setLineWrap(true);
+
+ phymlTextArea.setMargin(new Insets(5, 5, 5, 5));
+ phymlTextArea.setBackground(Color.white);
+ phymlTextArea.setEditable(false);
+ phymlTextArea.setSize(500, 800);// new java.awt.Dimension(15, 10));
+ phymlTextArea.setAutoscrolls(true);
+ phymlTextArea.setVisible(true);
+ phymlTextArea.setFont(XProtTestApp.FONT_CONSOLE);
+ phymlTextArea.setName("phymlTextArea");
+ phymlScrollPane
+ .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+ phymlTextArea.setWrapStyleWord(true);
+ phymlTextArea.setLineWrap(true);
+
+ statusPanel.setPreferredSize(new java.awt.Dimension(592, 30));
+ statusPanel.setBorder(new BorderUIResource.EtchedBorderUIResource(1,
+ new java.awt.Color(182, 182, 182), new java.awt.Color(89, 89,
+ 89)));
+ statusPanel.setLocation(new java.awt.Point(20, 630));
+ statusPanel.setVisible(true);
+ statusPanel.setLayout(new BorderLayout());
+ statusPanel.setForeground(java.awt.Color.blue);
+ statusPanel.setBackground(new java.awt.Color(220, 220, 220));
+ // statusPanel.setFont(new java.awt.Font("Dialog", 0, 9));
+
+ // statusPanel.setBorder(BorderFactory.createLineBorder(new
+ // java.awt.Color(0, 0, 0)));
+ statusPanel.setName("statusPanel");
+ // statusPanel.setPreferredSize(new java.awt.Dimension(100, 200));
+
+ lblDataFileStatus.setSize(new java.awt.Dimension(150, 40));
+ lblDataFileStatus.setVisible(true);
+ lblDataFileStatus.setForeground(CRITIC_COLOR);
+ lblDataFileStatus.setHorizontalAlignment(JLabel.RIGHT);
+ lblDataFileStatus.setFont(XProtTestApp.FONT_LABEL);
+
+ java.util.ResourceBundle bundle = java.util.ResourceBundle
+ .getBundle("es/uvigo/darwin/xprottest/resources/XProtTestView");
+ lblDataFileStatus.setText(bundle.getString("msg-no-data"));
+ lblDataFileStatus.setName("lblDataFileStatus");
+
+ lblLikelihoodStatus.setSize(new java.awt.Dimension(270, 40));
+ lblLikelihoodStatus.setVisible(true);
+ lblLikelihoodStatus.setForeground(CRITIC_COLOR);
+ lblLikelihoodStatus.setFont(XProtTestApp.FONT_LABEL);
+
+ lblLikelihoodStatus.setText(bundle.getString("msg-no-lnl-calculated"));
+ lblLikelihoodStatus.setName("lblLikelihoodStatus");
+
+ // mainPanel.add(mainScrollPane, BorderLayout.CENTER);
+ mainPanel.add(mainTabbedPane, BorderLayout.CENTER);
+ mainTabbedPane.addTab("Main", mainScrollPane);
+ mainTabbedPane.addTab("Phyml-log", phymlScrollPane);
+
+ mainPanel.add(statusPanel, BorderLayout.PAGE_END);
+ mainScrollPane.getViewport().add(mainTextArea);
+ phymlScrollPane.getViewport().add(phymlTextArea);
+ statusPanel.add(lblLikelihoodStatus, BorderLayout.LINE_START);
+ statusPanel.add(lblDataFileStatus, BorderLayout.LINE_END);
+
+ menuBar.setName("menuBar");
+
+ ActionMap actionMap = org.jdesktop.application.Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getActionMap(XProtTestView.class, this);
+ fileMenu.setAction(actionMap.get("openDataFile"));
+ fileMenu.setMnemonic('F');
+ fileMenu.setText(bundle.getString("item-file"));
+ fileMenu.setName("fileMenu");
+
+ saveConsoleMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_S,
+ java.awt.event.InputEvent.CTRL_MASK));
+ saveConsoleMenuItem.setMnemonic('S');
+ saveConsoleMenuItem.setText(bundle.getString("item-save-console"));
+ saveConsoleMenuItem.setName("saveConsoleMenuItem");
+ saveConsoleMenuItem
+ .addActionListener(new java.awt.event.ActionListener() {
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ saveConsole(evt);
+ }
+ });
+ printConsoleMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_P,
+ java.awt.event.InputEvent.CTRL_MASK));
+ printConsoleMenuItem.setMnemonic('P');
+ printConsoleMenuItem.setText(bundle.getString("item-print-console"));
+ printConsoleMenuItem.setName("printConsoleMenuItem");
+ printConsoleMenuItem
+ .addActionListener(new java.awt.event.ActionListener() {
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ printConsole(evt);
+ }
+ });
+ loadAlignmentMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_O,
+ java.awt.event.InputEvent.CTRL_MASK));
+ loadAlignmentMenuItem.setMnemonic('L');
+ loadAlignmentMenuItem.setText(bundle.getString("item-load-alignment"));
+ loadAlignmentMenuItem.setName("loadAlignmentMenuItem");
+ loadAlignmentMenuItem
+ .addActionListener(new java.awt.event.ActionListener() {
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ openDataFile(evt);
+ }
+ });
+ fileMenu.add(loadAlignmentMenuItem);
+ fileMenu.add(saveConsoleMenuItem);
+ fileMenu.add(printConsoleMenuItem);
+ exitMenuItem.setAction(actionMap.get("quit"));
+ exitMenuItem.setMnemonic('x');
+ exitMenuItem.setName("menuFileExit");
+ fileMenu.add(exitMenuItem);
+
+ menuBar.add(fileMenu);
+
+ editMenu.setMnemonic('E');
+ editMenu.setText(appResourceMap.getString("menu-edit"));
+ editMenu.setName("editMenu");
+
+ editCopyMenuItem.setAction(actionMap.get("editCopy"));
+ editCopyMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_C,
+ java.awt.event.InputEvent.CTRL_MASK));
+ editCopyMenuItem.setMnemonic('c');
+ editCopyMenuItem.setText(appResourceMap.getString("menu-copy"));
+ editCopyMenuItem.setToolTipText(appResourceMap
+ .getString("editCopyMenuItem.toolTipText"));
+ editCopyMenuItem.setName("editCopyMenuItem");
+ editMenu.add(editCopyMenuItem);
+
+ editSelectAllMenuItem.setAction(actionMap.get("editSelectAll"));
+ editSelectAllMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_A,
+ java.awt.event.InputEvent.CTRL_MASK));
+ editSelectAllMenuItem.setMnemonic('a');
+ editSelectAllMenuItem.setText(appResourceMap
+ .getString("menu-selectAll"));
+ editSelectAllMenuItem.setToolTipText(appResourceMap
+ .getString("editSelectAllMenuItem.toolTipText"));
+ editSelectAllMenuItem.setName("editSelectAllMenuItem");
+ editMenu.add(editSelectAllMenuItem);
+
+ preferencesMenuItem.setMnemonic('p');
+ preferencesMenuItem.setText(appResourceMap
+ .getString("menu-preferences"));
+ preferencesMenuItem.setToolTipText(appResourceMap
+ .getString("editPreferencesMenuItem.toolTipText"));
+ preferencesMenuItem.setName("preferencesMenuItem");
+ preferencesMenuItem
+ .addActionListener(new java.awt.event.ActionListener() {
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ loadPreferencesView(evt);
+ }
+ });
+ editMenu.add(preferencesMenuItem);
+
+ menuBar.add(editMenu);
+
+ analysisMenu.setMnemonic('A');
+ analysisMenu.setText(bundle.getString("item-analysis"));
+ analysisMenu.setName("analysisMenu");
+
+ computeMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_L,
+ java.awt.event.InputEvent.CTRL_MASK));
+ computeMenuItem.setMnemonic('c');
+ computeMenuItem.setText(bundle.getString("item-compute-likelihood"));
+ computeMenuItem.setToolTipText(appResourceMap
+ .getString("computeMenuItem.toolTipText"));
+ computeMenuItem.setEnabled(false);
+ computeMenuItem.setName("computeMenuItem");
+ computeMenuItem.addActionListener(new java.awt.event.ActionListener() {
+
+ @Override
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ loadOptionsView(evt);
+ }
+ });
+ analysisMenu.add(computeMenuItem);
+
+ showFrequenciesItem
+ .setAction(actionMap.get("showAminoacidFrequencies"));
+ showFrequenciesItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_F,
+ java.awt.event.InputEvent.SHIFT_MASK
+ | java.awt.event.InputEvent.CTRL_MASK));
+ showFrequenciesItem.setMnemonic('f');
+ showFrequenciesItem.setText(bundle.getString("item-show-frequencies"));
+ showFrequenciesItem.setToolTipText(appResourceMap
+ .getString("showFrequenciesItem.toolTipText"));
+ showFrequenciesItem.setEnabled(false);
+ showFrequenciesItem.setName("showFrequenciesItem");
+ analysisMenu.add(showFrequenciesItem);
+
+ showTreeMenuItem.setAction(actionMap.get("showTree"));
+ showTreeMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_T,
+ java.awt.event.InputEvent.SHIFT_MASK
+ | java.awt.event.InputEvent.CTRL_MASK));
+ showTreeMenuItem.setMnemonic('t');
+ showTreeMenuItem.setText(bundle.getString("item-show-tree"));
+ showTreeMenuItem.setToolTipText(appResourceMap
+ .getString("showTreeMenuItem.toolTipText"));
+ showTreeMenuItem.setEnabled(false);
+ showTreeMenuItem.setName("showTreeMenuItem");
+ analysisMenu.add(showTreeMenuItem);
+
+ averagingMenuItem.setAction(actionMap.get("showConsensus"));
+ averagingMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_C,
+ java.awt.event.InputEvent.SHIFT_MASK
+ | java.awt.event.InputEvent.CTRL_MASK));
+ averagingMenuItem.setMnemonic('p');
+ averagingMenuItem.setText(appResourceMap
+ .getString("averagingMenuItem.text"));
+ averagingMenuItem.setToolTipText(appResourceMap
+ .getString("averagingMenuItem.toolTipText"));
+ averagingMenuItem.setEnabled(false);
+ averagingMenuItem.setName("averagingMenuItem");
+ analysisMenu.add(averagingMenuItem);
+
+ menuBar.add(analysisMenu);
+
+ resultsMenu.setAction(actionMap.get("showResultsWindow"));
+ resultsMenu.setMnemonic('S');
+ resultsMenu.setText(bundle.getString("item-results"));
+ resultsMenu.setName("resultsMenu");
+
+ resultsMenuItem.setAction(actionMap.get("showResultsWindow"));
+ resultsMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_R,
+ java.awt.event.InputEvent.SHIFT_MASK
+ | java.awt.event.InputEvent.CTRL_MASK));
+ resultsMenuItem.setMnemonic('r');
+ resultsMenuItem.setText(bundle.getString("item-results-sub"));
+ resultsMenuItem.setEnabled(false);
+ resultsMenuItem.setName("resultsMenuItem");
+ resultsMenuItem.setToolTipText(appResourceMap
+ .getString("resultsMenuItem.toolTipText"));
+ resultsMenu.add(resultsMenuItem);
+
+ errorMenuItem.setAction(actionMap.get("showErrorLog"));
+ errorMenuItem.setAccelerator(KeyStroke.getKeyStroke(
+ java.awt.event.KeyEvent.VK_E,
+ java.awt.event.InputEvent.SHIFT_MASK
+ | java.awt.event.InputEvent.CTRL_MASK));
+ errorMenuItem.setMnemonic('e');
+ errorMenuItem.setText(appResourceMap.getString("errorMenuItem.text"));
+ errorMenuItem.setToolTipText(appResourceMap
+ .getString("errorMenuItem.toolTipText"));
+ errorMenuItem.setEnabled(false);
+ errorMenuItem.setName("errorMenuItem");
+ resultsMenu.add(errorMenuItem);
+
+ menuBar.add(resultsMenu);
+
+ helpMenu.setMnemonic('H');
+ helpMenu.setText(bundle.getString("item-help"));
+ helpMenu.setName("helpMenu");
+
+ manualMenuItem.setAction(actionMap.get("showManual"));
+ manualMenuItem.setMnemonic('m');
+ manualMenuItem.setText(appResourceMap.getString("menu-manual"));
+ manualMenuItem.setName("manualMenuItem");
+ helpMenu.add(manualMenuItem);
+
+ aboutMenuItem.setAction(actionMap.get("showAboutBox"));
+ aboutMenuItem.setText(bundle.getString("item-about-window"));
+ aboutMenuItem.setName("aboutMenuItem");
+ helpMenu.add(aboutMenuItem);
+
+ creditsMenuItem.setAction(actionMap.get("showCreditsBox"));
+ creditsMenuItem.setText(bundle.getString("item-credits-window"));
+ creditsMenuItem.setName("creditsMenuItem");
+ helpMenu.add(creditsMenuItem);
+
+ menuBar.add(helpMenu);
+
+ setComponent(mainPanel);
+ setMenuBar(menuBar);
+
+ this.getFrame().setLayout(new BorderLayout());
+
+ this.getFrame().setLocation(new java.awt.Point(281, 80));
+ this.getFrame().getContentPane().setLayout(new BorderLayout());
+ this.getFrame().setTitle("ProtTest " + ProtTest.versionNumber);
+ this.getFrame().setSize(new java.awt.Dimension(630, 695));
+ this.getFrame().setResizable(true);
+ this.getFrame().setContentPane(mainPanel);
+ }
+
+ private void openDataFile(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_openDataFile
+ FileDialog fc = new FileDialog(this.getFrame(),
+ "Load amino-acid alignment", FileDialog.LOAD);
+ fc.setDirectory(System.getProperty("user.dir"));
+ fc.setVisible(true);
+
+ String dataFileName = fc.getFile();
+
+ if (dataFileName != null) {
+ enableHandler();
+ try {
+ ProtTestPrinter.printPreAnalysisHeader();
+ File f = new File(fc.getDirectory() + dataFileName);// fc.getSelectedFile();
+ ProtTestPrinter.printFileData(f);
+ if (alignmentFile == null
+ || !f.getAbsolutePath().equals(
+ alignmentFile.getAbsolutePath())) {
+ lblLikelihoodStatus.setText(resourceMap
+ .getString("msg-no-lnl-calculated"));
+ lblLikelihoodStatus.setForeground(CRITIC_COLOR);
+ lnlCalculated = false;
+ }
+ alignment = prottestFacade.readAlignment(f.getAbsolutePath(),
+ true);
+ setAlignmentFile(f);
+ } catch (AlignmentParseException ex) {
+ displayWriter.println(ex.getMessage());
+ setAlignmentFile(null);
+ } catch (FileNotFoundException ex) {
+ displayWriter.println(ex.getMessage());
+ setAlignmentFile(null);
+ } catch (IOException ex) {
+ displayWriter.println(ex.getMessage());
+ setAlignmentFile(null);
+ }
+ disableHandler();
+ }
+ }// GEN-LAST:event_openDataFile
+
+ private void saveConsole(java.awt.event.ActionEvent evt) {
+ String text = mainTextArea.getText();
+
+ FileDialog fc = new FileDialog(this.getFrame(),
+ "Save ProtTest console", FileDialog.SAVE);
+ fc.setDirectory(System.getProperty("user.dir"));
+ fc.setVisible(true);
+
+ String dataFileName = fc.getFile();
+ try {
+ File f = new File(dataFileName);
+ FileWriter fw = new FileWriter(f);
+ fw.write(text);
+ fw.close();
+ } catch (IOException ex) {
+ Logger.getLogger(XProtTestView.class.getName()).log(Level.SEVERE,
+ null, ex);
+ }
+ }
+
+ private void printConsole(java.awt.event.ActionEvent evt) {
+ try {
+ mainTextArea.print();
+ } catch (PrinterException ex) {
+ Logger.getLogger(XProtTestView.class.getName()).log(Level.SEVERE,
+ null, ex);
+ }
+ }
+
+ private void loadOptionsView(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_loadOptionsView
+ OptionsView op = new OptionsView(this, alignment,
+ alignmentFile.getAbsolutePath());
+ op.setVisible(true);
+
+ enableItems(false);
+ }// GEN-LAST:event_loadOptionsView
+
+ private void loadPreferencesView(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_loadPreferencesView
+ PreferencesView pv = new PreferencesView(this);
+ pv.setVisible(true);
+
+ enableItems(false);
+ }// GEN-LAST:event_loadPreferencesView
+
+ public void unloadOptionsView(boolean running) {
+ if (!running) {
+ enableItems(true);
+
+ }
+ }
+
+ public void unloadPreferencesView() {
+ enableItems(true);
+
+ }
+
+ // private JFileChooser createFileChooser(String title) {
+ // JFileChooser fc = new JFileChooser();
+ // fc.setDialogTitle(title);
+ // fc.setFileFilter(fc.getAcceptAllFileFilter());
+ // fc.setCurrentDirectory(new File("."));
+ // return fc;
+ // }
+
+ @Action
+ public void showAminoacidFrequencies() {
+ if (alignment != null) {
+ if (frequenciesView == null) {
+ frequenciesView = new FrequenciesView(alignment);
+
+ }
+ frequenciesView.setVisible(true);
+
+ }
+ }
+
+ private boolean correctDone;
+
+ @Action
+ public void showResultsWindow() {
+ if (models != null) {
+ if (resultsView == null) {
+ resultsView = new ResultsView(this, alignment, models,
+ correctDone);
+
+ }
+ resultsView.setVisible(true);
+
+ }
+ }
+
+ private int numModels;
+ private boolean taskRunning = false;
+
+ public void computeLikelihood(int numModels, ApplicationOptions options) {
+
+ enableHandler();
+
+ ProtTestPrinter.printExecutionHeader(options);
+
+ preferencesMenuItem.setEnabled(false);
+
+ this.numModels = numModels;
+
+ if (errorLogView != null) {
+ ProtTestLogger.getDefaultLogger().removeHandler(
+ errorLogView.getLogHandler());
+ errorLogView.setVisible(false);
+ errorLogView.dispose();
+ errorLogView = null;
+
+ }
+ if (resultsView != null) {
+ resultsView.setVisible(false);
+ resultsView.dispose();
+ resultsView = null;
+
+ }
+ if (treeView != null) {
+ treeView.setVisible(false);
+ treeView.dispose();
+ treeView = null;
+
+ }
+ if (consensusView != null) {
+ consensusView.setVisible(false);
+ consensusView.dispose();
+ consensusView = null;
+
+ }
+ errorLogView = new ErrorLogView();
+ ProtTestLogger.getDefaultLogger().addHandler(
+ errorLogView.getLogHandler());
+ RunningFrame runningFrame = new RunningFrame(this, numModels);
+ errorMenuItem.setEnabled(false);
+ prottestFacade.addObserver(runningFrame);
+ lblMoreInfo.setVisible(false);
+
+ Task task = new ComputeLikelihoodTask(getApplication(), runningFrame,
+ this, options);
+ // get the application's context...
+ ApplicationContext appC = Application.getInstance().getContext();
+ // ...to get the TaskMonitor and TaskService
+ TaskMonitor tM = appC.getTaskMonitor();
+ TaskService tS = appC.getTaskService();
+
+ // i.e. making the animated progressbar and busy icon visible
+ tS.execute(task);
+ taskRunning = true;
+
+ enableItems(false);
+ runningFrame.setVisible(true);
+
+ }
+
+ private void enableItems(boolean enable) {
+ menuBar.setEnabled(enable);
+ fileMenu.setEnabled(enable);
+ editMenu.setEnabled(enable);
+ analysisMenu.setEnabled(enable);
+ resultsMenu.setEnabled(enable);
+ helpMenu.setEnabled(enable);
+ }
+
+ protected void computationDone(boolean done, Model[] models) {
+
+ preferencesMenuItem.setEnabled(true);
+
+ if (done) {
+ correctDone = (models.length == this.numModels);
+
+ if (correctDone) {
+ lblLikelihoodStatus.setText(resourceMap
+ .getString("msg-lnl-calculated"));
+ lblLikelihoodStatus.setForeground(DONE_COLOR);
+ errorMenuItem.setEnabled(false);
+ lblMoreInfo.setVisible(false);
+
+ if (errorLogView != null) {
+ errorLogView.setVisible(false);
+ errorLogView.dispose();
+ errorLogView = null;
+
+ }
+ } else {
+ lblLikelihoodStatus.setText("Warning! "
+ + resourceMap.getString("models-not-complete"));
+ lblLikelihoodStatus.setForeground(CRITIC_COLOR);
+ displayWriter.println("");
+ displayWriter.println(resourceMap
+ .getString("models-not-complete"));
+ displayWriter.println(resourceMap
+ .getString("msg-see-error-log"));
+ errorMenuItem.setEnabled(true);
+ lblMoreInfo.setVisible(true);
+
+ }
+ } else {
+ lblLikelihoodStatus.setText(resourceMap.getString("msg-lnl-error"));
+ lblLikelihoodStatus.setForeground(CRITIC_COLOR);
+ displayWriter.println(resourceMap.getString("msg-see-error-log"));
+ errorMenuItem.setEnabled(true);
+
+ }
+
+ lnlCalculated = done;
+ resultsMenuItem.setEnabled(done);
+ showTreeMenuItem.setEnabled(done);
+ averagingMenuItem.setEnabled(done);
+
+ this.models = models;
+
+ disableHandler();
+
+ }
+
+ public void computationInterrupted() {
+ lblLikelihoodStatus.setText(resourceMap.getString("msg-lnl-error"));
+ lblLikelihoodStatus.setForeground(CRITIC_COLOR);
+ errorMenuItem.setEnabled(true);
+ lblMoreInfo.setVisible(true);
+ disableHandler();
+
+ }
+
+ public void unloadRunningView(RunningFrame rf) {
+ enableItems(true);
+ rf.setVisible(false);
+ disableHandler();
+ }
+
+ private class ComputeLikelihoodTask extends Task<Object, Void> {
+
+ private RunningFrame runningFrame;
+ private XProtTestView mainFrame;
+ private Model[] models;
+ private ApplicationOptions options;
+
+ ComputeLikelihoodTask(Application app, RunningFrame runningFrame,
+ XProtTestView mainFrame, ApplicationOptions options) {
+ // Runs on the EDT. Copy GUI state that
+ // doInBackground() depends on from parameters
+ // to ComputeLikelihoodTask fields, here.
+ super(app);
+ this.options = options;
+ this.runningFrame = runningFrame;
+ this.mainFrame = mainFrame;
+ runningFrame.setTask(this);
+ }
+
+ @Override
+ protected Object doInBackground() {
+ // Your Task's code here. This method runs
+ // on a background thread, so don't reference
+ // the Swing GUI from here.
+ // ProtTestPrinter printer = new ProtTestPrinter(getDisplayWriter(),
+ // new PrintWriter(System.err));
+
+ try {
+ options.setAlignment(alignmentFile.getAbsolutePath());
+ models = prottestFacade.startAnalysis(options);
+ } catch (AlignmentParseException ex) {
+ ProtTestLogger.severeln(ex.getMessage(), this.getClass());
+ } catch (IOException ex) {
+ ProtTestLogger.severeln(ex.getMessage(), this.getClass());
+ } catch (ProtTestInternalException ex) {
+ ProtTestLogger.severeln(ex.getMessage(), this.getClass());
+ }
+
+ runningFrame.finishedExecution();
+
+ return null; // return your result
+ }
+
+ @Override
+ protected void succeeded(Object result) {
+ // Runs on the EDT. Update the GUI based on
+ // the result computed by doInBackground().
+ boolean done = models != null && models.length > 0;
+ if (done) {
+ try {
+ for (Model model : models) {
+ // throws ProtTestInternalException when Lk is not set
+ model.getLk();
+ }
+ } catch (ProtTestInternalException e) {
+ done = false;
+ }
+ }
+
+ mainFrame.computationDone(done, models);
+ }
+
+ @Override
+ protected void cancelled() {
+ mainFrame.computationDone(false, null);
+ }
+
+ @Override
+ protected void interrupted(InterruptedException ex) {
+ mainFrame.computationInterrupted();
+ }
+ }
+
+ @Action
+ public void showTree() {
+ TreeFacade treeFacade = new TreeFacadeImpl();
+
+ if (models != null) {
+ if (treeView == null) {
+ treeView = new TreeView(this, treeFacade, tree, models);
+
+ }
+ treeView.setVisible(true);
+
+ }
+ }
+
+ @Action
+ public void showConsensus() {
+ TreeFacade treeFacade = new TreeFacadeImpl();
+
+ if (models != null) {
+ if (consensusView == null) {
+ consensusView = new Consensus(this, treeFacade, models,
+ alignment);
+
+ }
+ consensusView.setVisible(true);
+
+ }
+ }
+
+ @Action
+ public void showErrorLog() {
+ if (errorLogView != null) {
+ errorLogView.setVisible(true);
+
+ }
+ }
+
+ @Action
+ public void editCopy() {
+ mainTextArea.copy();
+
+ }
+
+ @Action
+ public void editSelectAll() {
+ mainTextArea.selectAll();
+
+ }
+
+ @Action
+ public void showPreferences() {
+ }
+
+ @Action
+ public void showManual() {
+ try {
+ BrowserLauncher
+ .openURL("http://darwin.uvigo.es/download/prottest_manual.pdf");
+
+ } catch (IOException e) {
+ displayWriter.println("Cannot open URL : " + e.getMessage());
+
+ }
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private JMenu fileMenu;
+ private JMenuItem exitMenuItem;
+ private JMenu analysisMenu;
+ private JMenuItem averagingMenuItem;
+ private JMenuItem computeMenuItem;
+ private JMenuItem editCopyMenuItem;
+ private JMenu editMenu;
+ private JMenuItem editSelectAllMenuItem;
+ private JMenuItem errorMenuItem;
+ private JLabel lblDataFileStatus;
+ private JLabel lblLikelihoodStatus;
+ private JLabel lblMoreInfo;
+ private JMenuItem loadAlignmentMenuItem;
+ private JPanel mainPanel;
+ private JTabbedPane mainTabbedPane;
+ private JScrollPane phymlScrollPane;
+ private JTextArea phymlTextArea;
+ private JScrollPane mainScrollPane;
+ private JTextArea mainTextArea;
+ private JMenuItem manualMenuItem;
+ private JMenuBar menuBar;
+ private JMenuItem preferencesMenuItem;
+ private JMenu resultsMenu;
+ private JMenuItem resultsMenuItem;
+ private JMenuItem showFrequenciesItem;
+ private JMenuItem showTreeMenuItem;
+ private JMenu helpMenu;
+ private JMenuItem aboutMenuItem;
+ private JPanel statusPanel;
+ // End of variables declaration//GEN-END:variables
+ private JMenuItem saveConsoleMenuItem;
+ private JMenuItem printConsoleMenuItem;
+ private JMenuItem creditsMenuItem = new JMenuItem();
+ private final Timer messageTimer;
+ private final Timer busyIconTimer;
+ private final Icon idleIcon;
+ private final Icon[] busyIcons = new Icon[15];
+ private int busyIconIndex = 0;
+ private JDialog aboutBox;
+ private JDialog creditsBox;
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/FrequenciesView.java b/src/main/java/es/uvigo/darwin/xprottest/analysis/FrequenciesView.java
new file mode 100755
index 0000000..d7aeda9
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/FrequenciesView.java
@@ -0,0 +1,128 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.analysis;
+
+import es.uvigo.darwin.prottest.util.ProtTestAlignment;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+import pal.alignment.Alignment;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.RowSorter;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+
+/**
+ * This frame shows the observed frequencies of every amino-acid on
+ * the selected alignment.
+ *
+ * @author Diego Darriba
+ */
+public class FrequenciesView extends javax.swing.JFrame {
+
+ private int freqWidth = 5;
+
+ /** Creates new form FrequenciesView */
+ public FrequenciesView(Alignment alignment) {
+ initComponents();
+ double[] frequencies = ProtTestAlignment.getFrequencies(alignment);
+ for (int i = 0; i < frequencies.length; i++) {
+ tableFrequencies.setValueAt(ProtTestAlignment.charOfIndex(i), i, 0);
+ tableFrequencies.setValueAt(
+ ProtTestFormattedOutput.getDecimalString(frequencies[i], freqWidth), i, 1);
+ }
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ jScrollPane1 = new javax.swing.JScrollPane();
+ tableFrequencies = new javax.swing.JTable();
+ lblTitle = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ setName("Form"); // NOI18N
+
+ jScrollPane1.setName("jScrollPane1"); // NOI18N
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class).getContext().getResourceMap(FrequenciesView.class);
+ tableFrequencies.setBackground(resourceMap.getColor("tableFrequencies.background")); // NOI18N
+ DefaultTableModel freqTableModel =
+ new javax.swing.table.DefaultTableModel() {
+ public Class getColumnClass(int column) {
+ if (column >= 0 && column <= getColumnCount()){
+ try {
+ return getValueAt(0, column).getClass();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return Object.class;
+ }
+ }
+ else
+ return Object.class;
+ }
+ public boolean isCellEditable(int row, int col) { return false; }
+ };
+ freqTableModel.addColumn("AA", new String[20][1]);
+ freqTableModel.addColumn("Frequency", new Double[20][1]);
+ tableFrequencies.setModel(freqTableModel
+ );
+ RowSorter<TableModel> freqSorter = new TableRowSorter<TableModel>(freqTableModel);
+ tableFrequencies.setRowSorter(freqSorter);
+ tableFrequencies.setColumnSelectionAllowed(true);
+ tableFrequencies.setName("tableFrequencies"); // NOI18N
+ jScrollPane1.setViewportView(tableFrequencies);
+
+ lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("es/uvigo/darwin/xprottest/analysis/resources/FrequenciesView"); // NOI18N
+ lblTitle.setText(bundle.getString("msg-title")); // NOI18N
+ lblTitle.setName("lblTitle"); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE)
+ .addComponent(lblTitle, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 217, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblTitle)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 343, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JLabel lblTitle;
+ private javax.swing.JTable tableFrequencies;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeView.java b/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeView.java
new file mode 100755
index 0000000..2c255d1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeView.java
@@ -0,0 +1,282 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.analysis;
+
+import es.uvigo.darwin.prottest.facade.TreeFacade;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import es.uvigo.darwin.prottest.util.printer.ProtTestPrinter;
+import es.uvigo.darwin.xprottest.XProtTestView;
+import java.awt.Font;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import org.jdesktop.application.Action;
+import pal.tree.Tree;
+import es.uvigo.darwin.xprottest.util.TextAreaWriter;
+/**
+ *
+ * @author diego
+ */
+public class TreeView extends javax.swing.JFrame {
+
+ private Tree tree;
+ private List<Tree> trees;
+ private TreeFacade facade;
+ private PrintWriter displayWriter;
+ private XProtTestView mainFrame;
+
+ /** Creates new form TreeView */
+ public TreeView(XProtTestView mainFrame, TreeFacade facade, Tree tree, Model[] models) {
+ this.mainFrame = mainFrame;
+ this.tree = tree;
+ this.facade = facade;
+ this.trees = new ArrayList<Tree>(models.length);
+
+ initComponents();
+ displayWriter = new PrintWriter(new TextAreaWriter(displayArea));
+
+ Font f = new Font(Font.MONOSPACED, Font.PLAIN, 12);
+ displayArea.setFont(f);
+
+ if (tree != null)
+ cmbTreeSelection.addItem(new TreeWrapper("Starting Topology", tree));
+ if (models != null) {
+ for (Model model : models) {
+ if (model.getTree() != null) {
+ cmbTreeSelection.addItem(new TreeWrapper(model.getModelName(), model.getTree()));
+ trees.add(model.getTree());
+ }
+ }
+ }
+ if (cmbTreeSelection.getItemCount() > 0)
+ cmbTreeSelection.setSelectedIndex(0);
+
+ treeFormatSelection();
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ treeDisplayTypeBtnGroup = new javax.swing.ButtonGroup();
+ displayScroll = new javax.swing.JScrollPane();
+ displayArea = new javax.swing.JTextArea();
+ optionsPanel = new javax.swing.JPanel();
+ cmbTreeSelection = new javax.swing.JComboBox();
+ cmbTreeFormatSelection = new javax.swing.JComboBox();
+ btnExport = new javax.swing.JButton();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ windowMenu = new javax.swing.JMenu();
+ closeMenuItem = new javax.swing.JMenuItem();
+ editMenu = new javax.swing.JMenu();
+ editCopyMenuItem = new javax.swing.JMenuItem();
+ editSelectAllMenuItem = new javax.swing.JMenuItem();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("es/uvigo/darwin/xprottest/analysis/resources/TreeView"); // NOI18N
+ setTitle(bundle.getString("title")); // NOI18N
+ setName("Form"); // NOI18N
+ setResizable(false);
+
+ displayScroll.setName("displayScroll"); // NOI18N
+
+ displayArea.setColumns(20);
+ displayArea.setEditable(false);
+ displayArea.setRows(5);
+ displayArea.setName("displayArea"); // NOI18N
+ displayScroll.setViewportView(displayArea);
+
+ optionsPanel.setName("optionsPanel"); // NOI18N
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance().getContext().getActionMap(TreeView.class, this);
+ cmbTreeSelection.setAction(actionMap.get("treeFormatSelection")); // NOI18N
+ cmbTreeSelection.setName("cmbTreeSelection"); // NOI18N
+
+ cmbTreeFormatSelection.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Newick Format", "ASCII Format" }));
+ cmbTreeFormatSelection.setSelectedItem("ASCII Format");
+ cmbTreeFormatSelection.setAction(actionMap.get("treeFormatSelection")); // NOI18N
+ cmbTreeFormatSelection.setName("cmbTreeFormatSelection"); // NOI18N
+
+ btnExport.setAction(actionMap.get("exportData")); // NOI18N
+ btnExport.setText("Export to main console"); // NOI18N
+ btnExport.setName("btnExport"); // NOI18N
+
+ javax.swing.GroupLayout optionsPanelLayout = new javax.swing.GroupLayout(optionsPanel);
+ optionsPanel.setLayout(optionsPanelLayout);
+ optionsPanelLayout.setHorizontalGroup(
+ optionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(optionsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(cmbTreeSelection, javax.swing.GroupLayout.PREFERRED_SIZE, 173, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 47, Short.MAX_VALUE)
+ .addComponent(cmbTreeFormatSelection, javax.swing.GroupLayout.PREFERRED_SIZE, 124, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(btnExport))
+ );
+ optionsPanelLayout.setVerticalGroup(
+ optionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(optionsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(optionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cmbTreeSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(btnExport)
+ .addComponent(cmbTreeFormatSelection, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ jMenuBar1.setName("jMenuBar1"); // NOI18N
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(TreeView.class);
+ windowMenu.setText(resourceMap.getString("windowMenu.text")); // NOI18N
+ windowMenu.setName("windowMenu"); // NOI18N
+
+ closeMenuItem.setAction(actionMap.get("close")); // NOI18N
+ closeMenuItem.setName("closeMenuItem"); // NOI18N
+ windowMenu.add(closeMenuItem);
+
+ jMenuBar1.add(windowMenu);
+
+ editMenu.setText(resourceMap.getString("editMenu.text")); // NOI18N
+ editMenu.setName("editMenu"); // NOI18N
+
+ editCopyMenuItem.setAction(actionMap.get("editCopy")); // NOI18N
+ editCopyMenuItem.setName("editCopyMenuItem"); // NOI18N
+ editMenu.add(editCopyMenuItem);
+
+ editSelectAllMenuItem.setAction(actionMap.get("editSelectAll")); // NOI18N
+ editSelectAllMenuItem.setName("editSelectAllMenuItem"); // NOI18N
+ editMenu.add(editSelectAllMenuItem);
+
+ jMenuBar1.add(editMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(displayScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
+ .addComponent(optionsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(optionsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(displayScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 451, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void displayAsciiTree(Tree tree) {
+ displayArea.setText("");
+ displayArea.setLineWrap(false);
+ displayWriter.println(facade.toASCII(tree));
+ displayWriter.println(" ");
+ displayWriter.println(facade.branchInfo(tree));
+ displayWriter.println(" ");
+ displayWriter.println(facade.heightInfo(tree));
+ }
+
+ private void displayNewickTree(Tree tree) {
+ displayArea.setText("");
+ displayArea.setLineWrap(true);
+ String newickTree = facade.toNewick(tree, true, true, false);
+ displayWriter.println(newickTree);
+ }
+
+
+ @Action
+ public void treeFormatSelection() {
+ Tree displayTree = ((TreeWrapper)cmbTreeSelection.getSelectedItem()).getTree();
+
+ if (cmbTreeFormatSelection.getSelectedItem()
+ .toString().toLowerCase().contains("newick"))
+ displayNewickTree(displayTree);
+ else if (cmbTreeFormatSelection.getSelectedItem()
+ .toString().toLowerCase().contains("ascii"))
+ displayAsciiTree(displayTree);
+ }
+
+ @Action
+ public void editCopy() {
+ displayArea.copy();
+ }
+
+ @Action
+ public void editSelectAll() {
+ displayArea.selectAll();
+ }
+
+ @Action
+ public void close() {
+ this.setVisible(false);
+ }
+
+ @Action
+ public void exportData() {
+ mainFrame.enableHandler();
+ ProtTestPrinter.printTreeHeader(((TreeWrapper)cmbTreeSelection.getSelectedItem()).toString());
+ ProtTestLogger.getDefaultLogger().infoln(displayArea.getText());
+ mainFrame.disableHandler();
+ }
+
+// @Action
+// public void buildConsensus() {
+// double threshold = Double.parseDouble(txtThreshold.getText());
+//
+// if (consensusTrees.containsKey(threshold)) {
+// cmbTreeSelection.setSelectedItem(consensusTrees.get(threshold));
+// } else {
+// Tree consensus = facade.createConsensusTree(trees, threshold);
+// TreeWrapper consensusWrapper = new TreeWrapper("Consensus " + threshold, consensus);
+// consensusTrees.put(threshold, consensusWrapper);
+// cmbTreeSelection.addItem(consensusWrapper);
+// cmbTreeSelection.setSelectedItem(consensusWrapper);
+// }
+// }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnExport;
+ private javax.swing.JMenuItem closeMenuItem;
+ private javax.swing.JComboBox cmbTreeFormatSelection;
+ private javax.swing.JComboBox cmbTreeSelection;
+ private javax.swing.JTextArea displayArea;
+ private javax.swing.JScrollPane displayScroll;
+ private javax.swing.JMenuItem editCopyMenuItem;
+ private javax.swing.JMenu editMenu;
+ private javax.swing.JMenuItem editSelectAllMenuItem;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JPanel optionsPanel;
+ private javax.swing.ButtonGroup treeDisplayTypeBtnGroup;
+ private javax.swing.JMenu windowMenu;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeWrapper.java b/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeWrapper.java
new file mode 100755
index 0000000..f4224c3
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/TreeWrapper.java
@@ -0,0 +1,44 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.analysis;
+
+import pal.tree.Tree;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class TreeWrapper {
+
+ private String id;
+ private Tree tree;
+
+ public Tree getTree() {
+ return tree;
+ }
+
+ public TreeWrapper (String id, Tree tree) {
+ this.id = id;
+ this.tree = tree;
+ }
+
+ @Override
+ public String toString() {
+ return id;
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/Consensus.java b/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/Consensus.java
new file mode 100755
index 0000000..6131d92
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/Consensus.java
@@ -0,0 +1,690 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.xprottest.analysis.consensus;
+
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.getDefaultLogger;
+import static es.uvigo.darwin.prottest.util.logging.ProtTestLogger.infoln;
+
+import java.awt.Font;
+import java.io.PrintWriter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+
+import org.jdesktop.application.Action;
+import org.jdesktop.application.Application;
+import org.jdesktop.application.ResourceMap;
+
+import pal.alignment.Alignment;
+import pal.misc.Identifier;
+import pal.tree.Tree;
+import es.uvigo.darwin.prottest.facade.TreeFacade;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.AIC;
+import es.uvigo.darwin.prottest.selection.AICc;
+import es.uvigo.darwin.prottest.selection.BIC;
+import es.uvigo.darwin.prottest.selection.DT;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.LNL;
+import es.uvigo.darwin.prottest.util.collection.ModelCollection;
+import es.uvigo.darwin.prottest.util.collection.SingleModelCollection;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogger;
+import es.uvigo.darwin.prottest.util.printer.ProtTestPrinter;
+import es.uvigo.darwin.xprottest.XProtTestView;
+import es.uvigo.darwin.xprottest.util.TextAreaWriter;
+
+/**
+ *
+ * @author diego
+ */
+public class Consensus extends javax.swing.JFrame {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7857819028765401188L;
+
+ private static final int AIC_SELECTION = 0;
+ private static final int BIC_SELECTION = 1;
+ private static final int AICC_SELECTION = 2;
+ private static final int LNL_SELECTION = 3;
+ private static final int DT_SELECTION = 4;
+ private static final int DISABLED_SELECTION = 5;
+ private static final String[] SELECTION = { "AIC", "BIC", "AICc", "LK",
+ "DT", "Disabled" };
+ private ResourceMap resourceMap;
+ private TreeFacade facade;
+ private ModelCollection models;
+ private Handler logHandler;
+ private PrintWriter displayWriter;
+ private XProtTestView mainFrame;
+
+ /** Creates new form Consensus */
+ public Consensus(XProtTestView mainFrame, TreeFacade facade,
+ Model[] models, Alignment alignment) {
+ initComponents();
+ this.mainFrame = mainFrame;
+ this.facade = facade;
+ this.models = new SingleModelCollection(models, alignment);
+ this.displayWriter = new PrintWriter(new TextAreaWriter(displayArea));
+ this.logHandler = getDefaultLogger().addHandler(displayWriter,
+ Level.OFF);
+
+ resourceMap = Application
+ .getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(Consensus.class);
+
+ Font f = new Font(Font.MONOSPACED, Font.PLAIN, 12);
+ displayArea.setFont(f);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed"
+ // desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ btnGrpCriterion = new javax.swing.ButtonGroup();
+ settingsPanel = new javax.swing.JPanel();
+ lblTitle = new javax.swing.JLabel();
+ lblCriterion = new javax.swing.JLabel();
+ radioAIC = new javax.swing.JRadioButton();
+ radioBIC = new javax.swing.JRadioButton();
+ radioAICC = new javax.swing.JRadioButton();
+ radioDT = new javax.swing.JRadioButton();
+ radioLK = new javax.swing.JRadioButton();
+ sliderConsType = new javax.swing.JSlider();
+ lblConsType = new javax.swing.JLabel();
+ btnBuild = new javax.swing.JButton();
+ lblMR = new javax.swing.JLabel();
+ lblStrict = new javax.swing.JLabel();
+ lblConfInt = new javax.swing.JLabel();
+ sliderConfidence = new javax.swing.JSlider();
+ lblConfidenceInterval = new javax.swing.JLabel();
+ lblConsensusType = new javax.swing.JLabel();
+ lblPercent = new javax.swing.JLabel();
+ btnExport = new javax.swing.JButton();
+ displayScroll = new javax.swing.JScrollPane();
+ displayArea = new javax.swing.JTextArea();
+ jMenuBar1 = new javax.swing.JMenuBar();
+ windowMenu = new javax.swing.JMenu();
+ closeMenuItem = new javax.swing.JMenuItem();
+ editMenu = new javax.swing.JMenu();
+ editCopyMenuItem = new javax.swing.JMenuItem();
+ selectAllMenuItem = new javax.swing.JMenuItem();
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application
+ .getInstance().getContext().getResourceMap(Consensus.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setName("Form"); // NOI18N
+
+ settingsPanel.setBorder(javax.swing.BorderFactory
+ .createBevelBorder(javax.swing.border.BevelBorder.RAISED));
+ settingsPanel.setName("settingsPanel"); // NOI18N
+
+ lblTitle.setBackground(resourceMap.getColor("lblTitle.background")); // NOI18N
+ lblTitle.setFont(resourceMap.getFont("lblTitle.font")); // NOI18N
+ lblTitle.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ lblTitle.setText(resourceMap.getString("title.text")); // NOI18N
+ lblTitle.setName("lblTitle"); // NOI18N
+
+ lblCriterion.setText(resourceMap.getString("lblCriterion.text")); // NOI18N
+ lblCriterion.setName("lblCriterion"); // NOI18N
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application
+ .getInstance().getContext().getActionMap(Consensus.class, this);
+ btnGrpCriterion.add(radioAIC);
+ radioAIC.setText(resourceMap.getString("radioAIC.text")); // NOI18N
+ radioAIC.setName("radioAIC"); // NOI18N
+
+ btnGrpCriterion.add(radioBIC);
+ radioBIC.setText(resourceMap.getString("radioBIC.text")); // NOI18N
+ radioBIC.setName("radioBIC"); // NOI18N
+
+ btnGrpCriterion.add(radioAICC);
+ radioAICC.setText(resourceMap.getString("radioAICC.text")); // NOI18N
+ radioAICC.setName("radioAICC"); // NOI18N
+
+ btnGrpCriterion.add(radioDT);
+ radioDT.setSelected(true);
+ radioDT.setText(resourceMap.getString("radioDT.text")); // NOI18N
+ radioDT.setName("radioDT"); // NOI18N
+
+ btnGrpCriterion.add(radioLK);
+ radioLK.setText(resourceMap.getString("radioLK.text")); // NOI18N
+ radioLK.setName("radioLK"); // NOI18N
+
+ sliderConsType.setMinimum(50);
+ sliderConsType.setToolTipText(resourceMap
+ .getString("sliderConsType.toolTipText")); // NOI18N
+ sliderConsType.setName("sliderConsType"); // NOI18N
+ sliderConsType
+ .addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ sliderConsTypeStateChanged(evt);
+ }
+ });
+
+ lblConsType.setText(resourceMap.getString("lblConsType.text")); // NOI18N
+ lblConsType.setName("lblConsType"); // NOI18N
+
+ btnBuild.setAction(actionMap.get("buildConsensus")); // NOI18N
+ btnBuild.setText(resourceMap.getString("btnBuild.text")); // NOI18N
+ btnBuild.setName("btnBuild"); // NOI18N
+
+ lblMR.setFont(resourceMap.getFont("lblMR.font")); // NOI18N
+ lblMR.setForeground(resourceMap.getColor("lblMR.foreground")); // NOI18N
+ lblMR.setText(resourceMap.getString("lblMR.text")); // NOI18N
+ lblMR.setName("lblMR"); // NOI18N
+
+ lblStrict.setFont(resourceMap.getFont("lblStrict.font")); // NOI18N
+ lblStrict.setForeground(resourceMap.getColor("lblStrict.foreground")); // NOI18N
+ lblStrict.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ lblStrict.setText(resourceMap.getString("lblStrict.text")); // NOI18N
+ lblStrict.setName("lblStrict"); // NOI18N
+
+ lblConfInt.setText(resourceMap.getString("lblConfInt.text")); // NOI18N
+ lblConfInt.setToolTipText(resourceMap
+ .getString("lblConfInt.toolTipText")); // NOI18N
+ lblConfInt.setName("lblConfInt"); // NOI18N
+
+ sliderConfidence.setValue(100);
+ sliderConfidence.setName("sliderConfidence"); // NOI18N
+ sliderConfidence
+ .addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ sliderConfidenceStateChanged(evt);
+ }
+ });
+
+ lblConfidenceInterval.setText(resourceMap
+ .getString("default-confidence-interval")); // NOI18N
+ lblConfidenceInterval.setName("lblConfidenceInterval"); // NOI18N
+
+ lblConsensusType
+ .setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ lblConsensusType.setText(resourceMap
+ .getString("default-consensus-type")); // NOI18N
+ lblConsensusType.setName("lblConsensusType"); // NOI18N
+
+ lblPercent.setText(resourceMap.getString("percent-symbol")); // NOI18N
+ lblPercent.setName("lblPercent"); // NOI18N
+
+ btnExport.setAction(actionMap.get("exportData")); // NOI18N
+ btnExport.setText(resourceMap.getString("btnExport.text")); // NOI18N
+ btnExport.setEnabled(false);
+ btnExport.setName("btnExport"); // NOI18N
+
+ javax.swing.GroupLayout settingsPanelLayout = new javax.swing.GroupLayout(
+ settingsPanel);
+ settingsPanel.setLayout(settingsPanelLayout);
+ settingsPanelLayout
+ .setHorizontalGroup(settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ lblCriterion,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 161,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(
+ lblTitle,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 636,
+ Short.MAX_VALUE)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addGap(12,
+ 12,
+ 12)
+ .addComponent(
+ radioAIC)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(
+ radioBIC)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(
+ radioAICC)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(
+ radioDT)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(
+ radioLK))
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addComponent(
+ lblConsType)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ lblConsensusType,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 40,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ lblPercent))
+ .addComponent(
+ sliderConsType,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 636,
+ Short.MAX_VALUE)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addComponent(
+ lblMR,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 76,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addGap(129,
+ 129,
+ 129)
+ .addComponent(
+ btnBuild)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ btnExport)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED,
+ 182,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblStrict,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 40,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(
+ sliderConfidence,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 636,
+ Short.MAX_VALUE)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addComponent(
+ lblConfInt)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ lblConfidenceInterval)))))
+ .addContainerGap()));
+ settingsPanelLayout
+ .setVerticalGroup(settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ settingsPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblTitle)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblCriterion)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(radioAIC)
+ .addComponent(radioBIC)
+ .addComponent(radioAICC)
+ .addComponent(radioDT)
+ .addComponent(radioLK))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblConfInt)
+ .addComponent(
+ lblConfidenceInterval))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ sliderConfidence,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblConsType)
+ .addComponent(
+ lblConsensusType)
+ .addComponent(
+ lblPercent))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ sliderConsType,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblMR)
+ .addComponent(lblStrict)
+ .addGroup(
+ settingsPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ btnBuild)
+ .addComponent(
+ btnExport)))
+ .addContainerGap()));
+
+ displayScroll.setName("displayScroll"); // NOI18N
+
+ displayArea.setColumns(20);
+ displayArea.setEditable(false);
+ displayArea.setLineWrap(true);
+ displayArea.setRows(5);
+ displayArea.setName("displayArea"); // NOI18N
+ displayScroll.setViewportView(displayArea);
+
+ jMenuBar1.setName("jMenuBar1"); // NOI18N
+
+ windowMenu.setName("windowMenu"); // NOI18N
+
+ closeMenuItem.setAction(actionMap.get("Close")); // NOI18N
+ closeMenuItem.setName("closeMenuItem"); // NOI18N
+ windowMenu.add(closeMenuItem);
+
+ jMenuBar1.add(windowMenu);
+
+ editMenu.setText(resourceMap.getString("editMenu.text")); // NOI18N
+ editMenu.setName("editMenu"); // NOI18N
+
+ editCopyMenuItem.setAction(actionMap.get("editCopy")); // NOI18N
+ editCopyMenuItem.setName("editCopyMenuItem"); // NOI18N
+ editMenu.add(editCopyMenuItem);
+
+ selectAllMenuItem.setAction(actionMap.get("editSelectAll")); // NOI18N
+ selectAllMenuItem.setText(resourceMap
+ .getString("selectAllMenuItem.text")); // NOI18N
+ selectAllMenuItem.setName("selectAllMenuItem"); // NOI18N
+ editMenu.add(selectAllMenuItem);
+
+ jMenuBar1.add(editMenu);
+
+ setJMenuBar(jMenuBar1);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
+ getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(layout
+ .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(
+ displayScroll,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 664, Short.MAX_VALUE)
+ .addComponent(
+ settingsPanel,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ layout.setVerticalGroup(layout
+ .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(settingsPanel,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(displayScroll,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 362, Short.MAX_VALUE).addContainerGap()));
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void sliderConfidenceStateChanged(javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_sliderConfidenceStateChanged
+ lblConfidenceInterval.setText(String.valueOf(Double
+ .valueOf(sliderConfidence.getValue()) / 100));
+ }// GEN-LAST:event_sliderConfidenceStateChanged
+
+ private void sliderConsTypeStateChanged(javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_sliderConsTypeStateChanged
+ lblConsensusType.setText(String.valueOf(Double.valueOf(sliderConsType
+ .getValue()) / 100));
+ }// GEN-LAST:event_sliderConsTypeStateChanged
+
+ @Action
+ public void buildConsensus() {
+ displayArea.setText("");
+ displayArea.setForeground(XProtTestView.NORMAL_COLOR);
+ double confidenceInterval = Double.valueOf(sliderConfidence.getValue()) / 100;
+ double supportThreshold = Double.valueOf(sliderConsType.getValue()) / 100;
+ InformationCriterion ic;
+ int selection;
+ if (radioAIC.isSelected()) {
+ ic = new AIC(models, confidenceInterval, models.getAlignment()
+ .getSiteCount());
+ selection = AIC_SELECTION;
+ } else if (radioBIC.isSelected()) {
+ ic = new BIC(models, confidenceInterval, models.getAlignment()
+ .getSiteCount());
+ selection = BIC_SELECTION;
+ } else if (radioAICC.isSelected()) {
+ ic = new AICc(models, confidenceInterval, models.getAlignment()
+ .getSiteCount());
+ selection = AICC_SELECTION;
+ } else if (radioLK.isSelected()) {
+ ic = new LNL(models, confidenceInterval, models.getAlignment()
+ .getSiteCount());
+ selection = LNL_SELECTION;
+ } else if (radioDT.isSelected()) {
+ ic = new DT(models, confidenceInterval, models.getAlignment()
+ .getSiteCount());
+ selection = DT_SELECTION;
+ } else {
+ ic = null;
+ selection = DISABLED_SELECTION;
+ }
+
+ logHandler.setLevel(Level.INFO);
+
+ if (ic == null || ic.getConfidenceModels().size() > 0) {
+ es.uvigo.darwin.prottest.consensus.Consensus consensus = null;
+ if (ic != null) {
+ consensus = facade.createConsensus(ic, supportThreshold);
+ } else {
+ throw new ProtTestInternalException(
+ "Consensus needs an Information Criterion");
+ // ArrayList<Tree> trees = new ArrayList<Tree>(models.size());
+ // for (Model model : models) {
+ // trees.add(model.getTree());
+ // }
+ // consensus = facade.createConsensus(trees, supportThreshold);
+ }
+ println("----------------------------------------");
+ println("Selection criterion: . . . . " + SELECTION[selection]);
+ println("Confidence interval: . . . . " + confidenceInterval);
+ println("Consensus support threshold: " + supportThreshold);
+ println("----------------------------------------");
+
+ // displayWriter.println("Computed models:");
+ // for (SelectionModel model : ic.getConfidenceModels()) {
+ // displayWriter.println(model.getModel().getModelName() + " (" +
+ // model.getWeightValue() + ")");
+ // }
+ // displayWriter.println("----------------------------------------");
+
+ println("");
+
+ println("# # # # # # # # # # # # # # # #");
+ println(" ");
+ println("Species in order:");
+ println(" ");
+
+ for (int i = 0; i < consensus.getIdGroup().getIdCount(); i++) {
+ Identifier id = consensus.getIdGroup().getIdentifier(i);
+ println(" " + (i + 1) + ". " + id.getName());
+ }
+ println(" ");
+ println("# # # # # # # # # # # # # # # #");
+ println(" ");
+ println("Sets included in the consensus tree");
+ println(" ");
+
+ println(consensus.getSetsIncluded());
+
+ println(" ");
+ println("Sets NOT included in consensus tree");
+ println(" ");
+
+ println(consensus.getSetsNotIncluded());
+
+ println(" ");
+ println("# # # # # # # # # # # # # # # #");
+ println(" ");
+
+ Tree consensusTree = consensus.getConsensusTree();
+ String newickTree = facade
+ .toNewick(consensusTree, true, true, true);
+ println(newickTree);
+
+ println(" ");
+ println("# # # # # # # # # # # # # # # #");
+ println(" ");
+
+ println(facade.toASCII(consensusTree));
+ println(" ");
+ println(facade.branchInfo(consensusTree));
+ println(" ");
+ println(facade.heightInfo(consensusTree));
+ } else {
+ displayArea.setForeground(XProtTestView.CRITIC_COLOR);
+ println(resourceMap.getString("msg-no-data"));
+ }
+ logHandler.setLevel(Level.OFF);
+ btnExport.setEnabled(!displayArea.getText().equals(""));
+ }
+
+ @Action
+ public void close() {
+ getDefaultLogger().removeHandler(logHandler);
+ this.setVisible(false);
+ }
+
+ @Action
+ public void editCopy() {
+ displayArea.copy();
+ }
+
+ @Action
+ public void editSelectAll() {
+ displayArea.selectAll();
+ }
+
+ private void println(String message) {
+ infoln(message, this.getClass());
+ }
+
+ @Action
+ public void exportData() {
+ mainFrame.enableHandler();
+ ProtTestPrinter.printTreeHeader("MODEL AVERAGED PHYLOGENY");
+ ProtTestLogger.getDefaultLogger().infoln(displayArea.getText());
+ mainFrame.disableHandler();
+ }
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnBuild;
+ private javax.swing.JButton btnExport;
+ private javax.swing.ButtonGroup btnGrpCriterion;
+ private javax.swing.JMenuItem closeMenuItem;
+ private javax.swing.JTextArea displayArea;
+ private javax.swing.JScrollPane displayScroll;
+ private javax.swing.JMenuItem editCopyMenuItem;
+ private javax.swing.JMenu editMenu;
+ private javax.swing.JMenuBar jMenuBar1;
+ private javax.swing.JLabel lblConfInt;
+ private javax.swing.JLabel lblConfidenceInterval;
+ private javax.swing.JLabel lblConsType;
+ private javax.swing.JLabel lblConsensusType;
+ private javax.swing.JLabel lblCriterion;
+ private javax.swing.JLabel lblMR;
+ private javax.swing.JLabel lblPercent;
+ private javax.swing.JLabel lblStrict;
+ private javax.swing.JLabel lblTitle;
+ private javax.swing.JRadioButton radioAIC;
+ private javax.swing.JRadioButton radioAICC;
+ private javax.swing.JRadioButton radioBIC;
+ private javax.swing.JRadioButton radioDT;
+ private javax.swing.JRadioButton radioLK;
+ private javax.swing.JMenuItem selectAllMenuItem;
+ private javax.swing.JPanel settingsPanel;
+ private javax.swing.JSlider sliderConfidence;
+ private javax.swing.JSlider sliderConsType;
+ private javax.swing.JMenu windowMenu;
+ // End of variables declaration//GEN-END:variables
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/resources/Consensus.properties b/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/resources/Consensus.properties
new file mode 100755
index 0000000..571796e
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/consensus/resources/Consensus.properties
@@ -0,0 +1,49 @@
+title.text=Phylogenetic Averaging
+#NOI18N
+lblTitle.background=153, 153, 153
+#NOI18N
+lblTitle.font=Dialog-Bold-12
+lblCriterion.text=Criterion for tree weights:
+radioAIC.text=AIC
+radioBIC.text=BIC
+radioAICC.text=AICc
+radioLK.text=-Lk
+lblConsType.text=Consensus Type:
+btnBuild.toolTip=Builds the consensus tree according to the settings above
+btnBuild.text=Build Consensus
+sliderConsType.toolTipText=Select the consensus threshold (%)
+lblMR.text=Majority Rule
+#NOI18N
+lblMR.foreground=102, 102, 102
+#NOI18N
+lblMR.font=Dialog-Italic-10
+lblStrict.text=Strict
+#NOI18N
+lblStrict.font=Dialog-Italic-10
+#NOI18N
+lblStrict.foreground=102, 102, 102
+lblConfInt.text=Confidence Interval:
+lblConfInt.toolTipText=
+buildConsensus.Action.text=
+buildConsensus.Action.shortDescription=
+msg-no-data=There are no trees in the selection criterion
+Form.title=Consensus Tree
+closeMenuItem.text=Item
+Close.Action.text=
+Close.Action.accelerator=ctrl pressed W
+Close.Action.shortDescription=
+editMenu.text=Edit
+editCopyMenuItem.text=Item
+editCopy.Action.text=Copy
+editCopy.Action.shortDescription=
+jMenuItem1.text=Item
+editSelectAll.Action.shortDescription=
+editSelectAll.Action.text=
+radioDT.text=DT
+default-confidence-interval=1.0
+default-consensus-type=50
+percent-symbol=%
+selectAllMenuItem.text=Select All
+btnExport.text=Export data
+exportData.Action.text=
+exportData.Action.shortDescription=
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/FrequenciesView.properties b/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/FrequenciesView.properties
new file mode 100755
index 0000000..7911318
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/FrequenciesView.properties
@@ -0,0 +1,4 @@
+
+msg-title=Observed Amino-acid Frequencies
+#NOI18N
+tableFrequencies.background=238, 238, 238
diff --git a/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/TreeView.properties b/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/TreeView.properties
new file mode 100755
index 0000000..3f27113
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/analysis/resources/TreeView.properties
@@ -0,0 +1,28 @@
+
+lbl-newick-tree=Newick Format
+lbl-ascii-tree=ASCII Format
+displayAsciiTree.Action.text=
+displayAsciiTree.Action.shortDescription=
+displayNewickTree.Action.text=
+displayNewickTree.Action.shortDescription=
+title=Display Tree
+lbl-best-aic=Best AIC
+lbl-best-bic=Best BIC
+treeFormatSelection.Action.text=
+treeFormatSelection.Action.shortDescription=
+buildConsensus.Action.text=
+buildConsensus.Action.shortDescription=
+windowMenu.text=Window
+jMenuItem1.text=Select all
+editMenu.text=Edit
+closeMenuItem.text=Close
+editCopy.Action.text=
+editCopy.Action.shortDescription=
+editSelectAll.Action.text=
+editSelectAll.Action.shortDescription=
+close.Action.shortDescription=
+close.Action.text=
+treeFormatSelection.toolTipText=Select the tree display format
+treeSelection.toolTipText=Select the aminoacid substitution model
+exportData.Action.text=
+exportData.Action.shortDescription=
diff --git a/src/main/java/es/uvigo/darwin/xprottest/compute/OptionsView.java b/src/main/java/es/uvigo/darwin/xprottest/compute/OptionsView.java
new file mode 100755
index 0000000..cbc1af7
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/compute/OptionsView.java
@@ -0,0 +1,748 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.compute;
+
+import es.uvigo.darwin.xprottest.*;
+import es.uvigo.darwin.xprottest.util.OptimizationStrategyWrapper;
+import es.uvigo.darwin.prottest.facade.util.ProtTestParameterVO;
+import static es.uvigo.darwin.prottest.global.AminoAcidApplicationGlobals.*;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.prottest.util.exception.AlignmentParseException;
+import es.uvigo.darwin.prottest.util.exception.ProtTestInternalException;
+import es.uvigo.darwin.prottest.util.exception.TreeFormatException;
+import java.awt.Color;
+import java.awt.FileDialog;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.ResourceBundle;
+import javax.swing.GroupLayout;
+import javax.swing.JCheckBox;
+import org.jdesktop.application.Action;
+import pal.tree.Tree;
+import pal.alignment.Alignment;
+import pal.misc.Identifier;
+
+/**
+ * The execution settings. The options chosen in this view will lead the
+ * execution of ProtTest-HPC likelihood computation.
+ *
+ * @author Diego Darriba
+ */
+public class OptionsView extends javax.swing.JFrame {
+
+ private XProtTestView mainFrame;
+
+ private ArrayList<JCheckBox> cbMatrices;
+
+ private String alignmentFilePath;
+
+ private String treeFilePath;
+
+ private Alignment alignment;
+
+ private Tree userTree;
+
+ private boolean running;
+
+ private ResourceBundle resource;
+
+ /** Creates new form OptionsView */
+ public OptionsView(XProtTestView mainFrame,
+ Alignment alignment, String alignmentFilePath) {
+
+ resource = java.util.ResourceBundle.getBundle("es/uvigo/darwin/xprottest/compute/resources/OptionsView");
+ this.alignment = alignment;
+
+ this.mainFrame = mainFrame;
+ this.alignmentFilePath = alignmentFilePath;
+ this.running = false;
+ initComponents();
+ msgValidate.setVisible(false);
+
+ GroupLayout jPanel1Layout = new GroupLayout(subMatricesPanel);
+ GroupLayout.ParallelGroup pg1 = jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
+ GroupLayout.ParallelGroup pg2 = jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
+ GroupLayout.SequentialGroup horizontalGroup = jPanel1Layout.createSequentialGroup()
+ .addContainerGap();
+
+ GroupLayout.ParallelGroup verticalGroup = jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
+ GroupLayout.SequentialGroup sg1 = jPanel1Layout.createSequentialGroup()
+ .addContainerGap();
+ GroupLayout.SequentialGroup sg2 = jPanel1Layout.createSequentialGroup()
+ .addContainerGap();
+ String[] matrices = ALL_MATRICES;
+ cbMatrices = new ArrayList<JCheckBox>(matrices.length);
+ int i = 0;
+ for (String matrix : matrices) {
+ JCheckBox cbMatrix = new JCheckBox();
+ cbMatrix.setText(matrix);
+ cbMatrix.setSelected(true);
+ cbMatrix.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ onChangeOptions(evt);
+ }
+ });
+ cbMatrices.add(cbMatrix);
+
+ if (i < matrices.length/2) {
+ pg1.addComponent(cbMatrix);
+ sg1.addComponent(cbMatrix)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED);
+ }
+ else {
+ pg2.addComponent(cbMatrix);
+ sg2.addComponent(cbMatrix)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED);
+ }
+ i++;
+ }
+
+ horizontalGroup.addGroup(pg1);
+ horizontalGroup.addGroup(pg2);
+ verticalGroup.addGroup(sg1);
+ verticalGroup.addGroup(sg2);
+ subMatricesPanel.setLayout(jPanel1Layout);
+ jPanel1Layout.setHorizontalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(jPanel1Layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(horizontalGroup)
+ .addContainerGap())
+ );
+ jPanel1Layout.setVerticalGroup(
+ jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(verticalGroup)
+ );
+
+ lblNumModels.setText(String.valueOf(calculateNumberOfModels()));
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ subMatPanel = new javax.swing.JPanel();
+ subMatricesPanel = new javax.swing.JPanel();
+ distributionsPanel = new javax.swing.JPanel();
+ rateVarPanel = new javax.swing.JPanel();
+ lblNCat = new javax.swing.JLabel();
+ cbDistGroupCat = new javax.swing.JCheckBox();
+ cbDistInvariant = new javax.swing.JCheckBox();
+ txtNCat = new javax.swing.JTextField();
+ cbDistInvGC = new javax.swing.JCheckBox();
+ msgValidate = new javax.swing.JLabel();
+ empiricalFPanel = new javax.swing.JPanel();
+ cbEmpiricalF = new javax.swing.JCheckBox();
+ lblNumModelsLabel = new javax.swing.JLabel();
+ lblNumModels = new javax.swing.JLabel();
+ btnCompute = new javax.swing.JButton();
+ processorsPanel = new javax.swing.JPanel();
+ sliderProcessors = new javax.swing.JSlider();
+ lblNumProc = new javax.swing.JLabel();
+ btnSetDefault = new javax.swing.JButton();
+ btnCancel = new javax.swing.JButton();
+ startingTopologiesPanel = new javax.swing.JPanel();
+ lblStrategyMode = new javax.swing.JLabel();
+ cmbStrategyMode = new javax.swing.JComboBox();
+ lblUserTree = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(OptionsView.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setName("Form"); // NOI18N
+ addWindowListener(new java.awt.event.WindowAdapter() {
+ public void windowClosed(java.awt.event.WindowEvent evt) {
+ onClose(evt);
+ }
+ });
+
+ subMatPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("subMatPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_PANEL_TITLE, resourceMap.getColor("subMatPanel.border.titleColor"))); // NOI18N
+ subMatPanel.setName("subMatPanel"); // NOI18N
+
+ subMatricesPanel.setToolTipText(resourceMap.getString("subMatricesPanel.toolTipText")); // NOI18N
+ subMatricesPanel.setName("subMatricesPanel"); // NOI18N
+
+ javax.swing.GroupLayout subMatricesPanelLayout = new javax.swing.GroupLayout(subMatricesPanel);
+ subMatricesPanel.setLayout(subMatricesPanelLayout);
+ subMatricesPanelLayout.setHorizontalGroup(
+ subMatricesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 172, Short.MAX_VALUE)
+ );
+ subMatricesPanelLayout.setVerticalGroup(
+ subMatricesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGap(0, 283, Short.MAX_VALUE)
+ );
+
+ javax.swing.GroupLayout subMatPanelLayout = new javax.swing.GroupLayout(subMatPanel);
+ subMatPanel.setLayout(subMatPanelLayout);
+ subMatPanelLayout.setHorizontalGroup(
+ subMatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(subMatPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(subMatricesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+ subMatPanelLayout.setVerticalGroup(
+ subMatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(subMatPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(subMatricesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
+ distributionsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("distributionsPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_LABEL, resourceMap.getColor("distributionsPanel.border.titleColor"))); // NOI18N
+ distributionsPanel.setName("distributionsPanel"); // NOI18N
+
+ rateVarPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("rateVarPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_PANEL_TITLE, resourceMap.getColor("rateVarPanel.border.titleColor"))); // NOI18N
+ rateVarPanel.setName("rateVarPanel"); // NOI18N
+
+ lblNCat.setFont(lblNCat.getFont());
+ lblNCat.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ lblNCat.setText(resourceMap.getString("lblNCat.text")); // NOI18N
+ lblNCat.setName("lblNCat"); // NOI18N
+
+ cbDistGroupCat.setFont(cbDistGroupCat.getFont());
+ cbDistGroupCat.setSelected(true);
+ cbDistGroupCat.setText(resourceMap.getString("cbDistGroupCat.text")); // NOI18N
+ cbDistGroupCat.setToolTipText(resourceMap.getString("cbDistGroupCat.toolTipText")); // NOI18N
+ cbDistGroupCat.setName("cbDistGroupCat"); // NOI18N
+ cbDistGroupCat.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ onChangeOptions(evt);
+ }
+ });
+
+ cbDistInvariant.setFont(cbDistInvariant.getFont());
+ cbDistInvariant.setSelected(true);
+ cbDistInvariant.setText(resourceMap.getString("cbDistInvariant.text")); // NOI18N
+ cbDistInvariant.setToolTipText(resourceMap.getString("cbDistInvariant.toolTipText")); // NOI18N
+ cbDistInvariant.setName("cbDistInvariant"); // NOI18N
+ cbDistInvariant.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ onChangeOptions(evt);
+ }
+ });
+
+ txtNCat.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
+ txtNCat.setText(String.valueOf(DEFAULT_NCAT));
+ java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("es/uvigo/darwin/xprottest/compute/resources/OptionsView"); // NOI18N
+ txtNCat.setToolTipText(bundle.getString("txtNCat.toolTip")); // NOI18N
+ txtNCat.setName("txtNCat"); // NOI18N
+
+ cbDistInvGC.setFont(cbDistInvGC.getFont());
+ cbDistInvGC.setSelected(true);
+ cbDistInvGC.setText(resourceMap.getString("cbDistInvGC.text")); // NOI18N
+ cbDistInvGC.setName("cbDistInvGC"); // NOI18N
+ cbDistInvGC.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ onChangeOptions(evt);
+ }
+ });
+
+ msgValidate.setFont(XProtTestApp.FONT_OPTION_LABEL);
+ msgValidate.setForeground(XProtTestView.CRITIC_COLOR);
+ msgValidate.setText(resourceMap.getString("msgValidate.text")); // NOI18N
+ msgValidate.setName("msgValidate"); // NOI18N
+
+ javax.swing.GroupLayout rateVarPanelLayout = new javax.swing.GroupLayout(rateVarPanel);
+ rateVarPanel.setLayout(rateVarPanelLayout);
+ rateVarPanelLayout.setHorizontalGroup(
+ rateVarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(rateVarPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(cbDistInvariant)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cbDistGroupCat)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cbDistInvGC)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblNCat)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(txtNCat, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap())
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, rateVarPanelLayout.createSequentialGroup()
+ .addContainerGap(94, Short.MAX_VALUE)
+ .addComponent(msgValidate)
+ .addContainerGap())
+ );
+ rateVarPanelLayout.setVerticalGroup(
+ rateVarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(rateVarPanelLayout.createSequentialGroup()
+ .addComponent(msgValidate)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(rateVarPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cbDistInvariant)
+ .addComponent(cbDistGroupCat)
+ .addComponent(cbDistInvGC)
+ .addComponent(txtNCat, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblNCat))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ empiricalFPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("empiricalFPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_PANEL_TITLE, resourceMap.getColor("empiricalFPanel.border.titleColor"))); // NOI18N
+ empiricalFPanel.setName("empiricalFPanel"); // NOI18N
+
+ cbEmpiricalF.setFont(cbEmpiricalF.getFont());
+ cbEmpiricalF.setSelected(true);
+ cbEmpiricalF.setText(bundle.getString("cbEmpiricalF.text")); // NOI18N
+ cbEmpiricalF.setToolTipText(resourceMap.getString("cbEmpiricalF.toolTipText")); // NOI18N
+ cbEmpiricalF.setName("cbEmpiricalF"); // NOI18N
+ cbEmpiricalF.addActionListener(new java.awt.event.ActionListener() {
+ public void actionPerformed(java.awt.event.ActionEvent evt) {
+ onChangeOptions(evt);
+ }
+ });
+
+ javax.swing.GroupLayout empiricalFPanelLayout = new javax.swing.GroupLayout(empiricalFPanel);
+ empiricalFPanel.setLayout(empiricalFPanelLayout);
+ empiricalFPanelLayout.setHorizontalGroup(
+ empiricalFPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(empiricalFPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(cbEmpiricalF)
+ .addContainerGap(223, Short.MAX_VALUE))
+ );
+ empiricalFPanelLayout.setVerticalGroup(
+ empiricalFPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(empiricalFPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(cbEmpiricalF)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ lblNumModelsLabel.setFont(XProtTestApp.FONT_OPTION_LABEL);
+ lblNumModelsLabel.setForeground(resourceMap.getColor("lblNumModelsLabel.foreground")); // NOI18N
+ lblNumModelsLabel.setText(resourceMap.getString("lblNumModelsLabel.text")); // NOI18N
+ lblNumModelsLabel.setName("lblNumModelsLabel"); // NOI18N
+
+ lblNumModels.setFont(XProtTestApp.FONT_OPTION_LABEL);
+ lblNumModels.setForeground(resourceMap.getColor("lblNumModelsLabel.foreground")); // NOI18N
+ lblNumModels.setName("lblNumModels"); // NOI18N
+
+ javax.swing.GroupLayout distributionsPanelLayout = new javax.swing.GroupLayout(distributionsPanel);
+ distributionsPanel.setLayout(distributionsPanelLayout);
+ distributionsPanelLayout.setHorizontalGroup(
+ distributionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, distributionsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(distributionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(rateVarPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(empiricalFPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(distributionsPanelLayout.createSequentialGroup()
+ .addComponent(lblNumModelsLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 248, Short.MAX_VALUE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(lblNumModels, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap())
+ );
+ distributionsPanelLayout.setVerticalGroup(
+ distributionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(distributionsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(rateVarPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 65, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(empiricalFPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(distributionsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(lblNumModels, javax.swing.GroupLayout.PREFERRED_SIZE, 13, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblNumModelsLabel))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance().getContext().getActionMap(OptionsView.class, this);
+ btnCompute.setAction(actionMap.get("computeLikelihood")); // NOI18N
+ btnCompute.setText(resourceMap.getString("btnCompute.text")); // NOI18N
+ btnCompute.setName("btnCompute"); // NOI18N
+
+ processorsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("processorsPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_PANEL_TITLE, resourceMap.getColor("processorsPanel.border.titleColor"))); // NOI18N
+ processorsPanel.setName("processorsPanel"); // NOI18N
+
+ sliderProcessors.setMinimum(1);
+ sliderProcessors.setMaximum(
+ Runtime.getRuntime().availableProcessors()
+ );
+ sliderProcessors.setValue(
+ mainFrame.getFacade().getNumberOfThreads()
+ );
+ sliderProcessors.setPaintLabels(true);
+ sliderProcessors.setPaintTicks(true);
+ sliderProcessors.setSnapToTicks(true);
+ sliderProcessors.setToolTipText(resourceMap.getString("sliderProcessors.toolTipText")); // NOI18N
+ sliderProcessors.setName("sliderProcessors"); // NOI18N
+ sliderProcessors.addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ sliderProcessorsStateChanged(evt);
+ }
+ });
+
+ lblNumProc.setFont(lblNumProc.getFont());
+ lblNumProc.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
+ lblNumProc.setText(String.valueOf(sliderProcessors.getValue()));
+ lblNumProc.setName("lblNumProc"); // NOI18N
+
+ javax.swing.GroupLayout processorsPanelLayout = new javax.swing.GroupLayout(processorsPanel);
+ processorsPanel.setLayout(processorsPanelLayout);
+ processorsPanelLayout.setHorizontalGroup(
+ processorsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(processorsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblNumProc)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(sliderProcessors, javax.swing.GroupLayout.DEFAULT_SIZE, 442, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+ processorsPanelLayout.setVerticalGroup(
+ processorsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(processorsPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(processorsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(sliderProcessors, javax.swing.GroupLayout.DEFAULT_SIZE, 47, Short.MAX_VALUE)
+ .addComponent(lblNumProc))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ btnSetDefault.setAction(actionMap.get("restoreDefault")); // NOI18N
+ btnSetDefault.setText(resourceMap.getString("btnSetDefault.text")); // NOI18N
+ btnSetDefault.setToolTipText(resourceMap.getString("btnSetDefault.toolTipText")); // NOI18N
+ btnSetDefault.setName("btnSetDefault"); // NOI18N
+
+ btnCancel.setAction(actionMap.get("close")); // NOI18N
+ btnCancel.setText(resourceMap.getString("btnCancel.text")); // NOI18N
+ btnCancel.setToolTipText(resourceMap.getString("btnCancel.toolTipText")); // NOI18N
+ btnCancel.setName("btnCancel"); // NOI18N
+
+ startingTopologiesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, resourceMap.getString("startingTopologiesPanel.border.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, XProtTestApp.FONT_PANEL_TITLE, resourceMap.getColor("startingTopologiesPanel.border.titleColor"))); // NOI18N
+ startingTopologiesPanel.setName("startingTopologiesPanel"); // NOI18N
+
+ lblStrategyMode.setFont(lblStrategyMode.getFont());
+ lblStrategyMode.setText(bundle.getString("lbl-strategy-mode")); // NOI18N
+ lblStrategyMode.setName("lblStrategyMode"); // NOI18N
+
+ cmbStrategyMode.setAction(actionMap.get("setStrategyMode")); // NOI18N
+ cmbStrategyMode.setName("cmbStrategyMode"); // NOI18N
+
+ lblUserTree.setFont(XProtTestApp.FONT_OPTION_LABEL);
+ lblUserTree.setForeground(resourceMap.getColor("lblUserTree.foreground")); // NOI18N
+ lblUserTree.setText(bundle.getString("msg-no-user-tree-loaded")); // NOI18N
+ lblUserTree.setName("lblUserTree"); // NOI18N
+
+ javax.swing.GroupLayout startingTopologiesPanelLayout = new javax.swing.GroupLayout(startingTopologiesPanel);
+ startingTopologiesPanel.setLayout(startingTopologiesPanelLayout);
+ startingTopologiesPanelLayout.setHorizontalGroup(
+ startingTopologiesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(startingTopologiesPanelLayout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(startingTopologiesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(cmbStrategyMode, 0, 329, Short.MAX_VALUE)
+ .addComponent(lblStrategyMode, javax.swing.GroupLayout.DEFAULT_SIZE, 329, Short.MAX_VALUE)
+ .addComponent(lblUserTree, javax.swing.GroupLayout.DEFAULT_SIZE, 329, Short.MAX_VALUE))
+ .addContainerGap())
+ );
+ startingTopologiesPanelLayout.setVerticalGroup(
+ startingTopologiesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(startingTopologiesPanelLayout.createSequentialGroup()
+ .addComponent(lblStrategyMode)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(cmbStrategyMode, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblUserTree)
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ for (int optimizeValue : OPTIMIZE_VALUES) {
+ OptimizationStrategyWrapper optimizeItem = new OptimizationStrategyWrapper(OPTIMIZE_NAMES[optimizeValue], optimizeValue);
+ cmbStrategyMode.addItem(optimizeItem);
+ }
+ cmbStrategyMode.setSelectedIndex(DEFAULT_STRATEGY_MODE);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(processorsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(subMatPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(distributionsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ .addComponent(startingTopologiesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addComponent(btnCompute)
+ .addGap(18, 18, 18)
+ .addComponent(btnSetDefault)
+ .addGap(18, 18, 18)
+ .addComponent(btnCancel)))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(processorsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+ .addGroup(layout.createSequentialGroup()
+ .addComponent(distributionsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(startingTopologiesPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addComponent(subMatPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(btnCancel)
+ .addComponent(btnSetDefault)
+ .addComponent(btnCompute))
+ .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void onClose(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_onClose
+ mainFrame.unloadOptionsView(running);
+ }//GEN-LAST:event_onClose
+
+ private void onChangeOptions(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_onChangeOptions
+
+ lblNumModels.setText(String.valueOf(calculateNumberOfModels()));
+ txtNCat.setEnabled(cbDistGroupCat.isSelected() || cbDistInvGC.isSelected());
+ }//GEN-LAST:event_onChangeOptions
+
+ private void sliderProcessorsStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderProcessorsStateChanged
+ lblNumProc.setText(String.valueOf(sliderProcessors.getValue()));
+ }//GEN-LAST:event_sliderProcessorsStateChanged
+
+ private int calculateNumberOfModels() {
+ int numberOfModels = 0;
+ for (JCheckBox cbMatrix : cbMatrices ) {
+ if (cbMatrix.isSelected())
+ numberOfModels++;
+ }
+ int numberOfMatrices = numberOfModels;
+ if (cbDistInvariant.isSelected())
+ numberOfModels += numberOfMatrices;
+ if (cbDistGroupCat.isSelected())
+ numberOfModels += numberOfMatrices;
+ if (cbDistInvGC.isSelected())
+ numberOfModels += numberOfMatrices;
+ if (cbEmpiricalF.isSelected())
+ numberOfModels *= 2;
+ return numberOfModels;
+ }
+
+ @Action
+ public void computeLikelihood() {
+ boolean validate = true;
+ msgValidate.setVisible(false);
+ Collection<String> matrices = new ArrayList<String>();
+ Collection<String> distributions = new ArrayList<String>();
+ int ncat = 0;
+ boolean plusF;
+ int strategyMode;
+ for (JCheckBox cbMatrix : cbMatrices)
+ if (cbMatrix.isSelected()) {
+ matrices.add(cbMatrix.getText());
+ }
+ distributions.add("Uniform");
+ if (cbDistGroupCat.isSelected())
+ distributions.add("+G");
+ if (cbDistInvariant.isSelected())
+ distributions.add("+I");
+ if (cbDistInvGC.isSelected())
+ distributions.add("+I+G");
+ if (cbDistGroupCat.isSelected() || cbDistInvGC.isSelected()) {
+ try {
+ ncat = Integer.parseInt(txtNCat.getText());
+ if (ncat <= 0) {
+ msgValidate.setVisible(true);
+ validate = false;
+ }
+ } catch (NumberFormatException e) {
+ msgValidate.setVisible(true);
+ validate = false;
+ }
+ }
+ plusF = cbEmpiricalF.isSelected();
+ strategyMode = cmbStrategyMode.getSelectedIndex();
+ if (validate) {
+ try {
+ mainFrame.getFacade().setNumberOfThreads(sliderProcessors.getValue());
+ ProtTestParameterVO parameters = new ProtTestParameterVO(
+ alignmentFilePath, alignment, treeFilePath, matrices, distributions, plusF, ncat,
+ strategyMode);
+ ApplicationOptions options = mainFrame.getFacade().configure(parameters);
+ mainFrame.computeLikelihood(calculateNumberOfModels(), options);
+ running = true;
+ } catch (IOException e) {
+ mainFrame.getDisplayWriter().println(e.getMessage());
+ } catch (AlignmentParseException e) {
+ mainFrame.getDisplayWriter().println(e.getMessage());
+ } catch (ProtTestInternalException e) {
+ mainFrame.getDisplayWriter().println(e.getMessage());
+ }
+ this.dispose();
+ }
+ }
+
+ @Action
+ public void setStrategyMode() {
+ org.jdesktop.application.ResourceMap resourceMap
+ = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(OptionsView.class);
+ File f = null;
+ if (((OptimizationStrategyWrapper)cmbStrategyMode.getSelectedItem()).getValue()
+ == OPTIMIZE_USER) {
+
+ FileDialog fc = new FileDialog(this, "Load DNA alignment", FileDialog.LOAD);
+ fc.setDirectory(System.getProperty("user.dir"));
+ fc.setVisible(true);
+
+ String dataFileName = fc.getFile();
+
+// JFileChooser fc = XProtTestApp.createFileChooser(resourceMap.getString(
+// "loadTree.dialogTitle"));
+// int option = fc.showOpenDialog(this);
+//
+// if (JFileChooser.APPROVE_OPTION == option) {
+ if (dataFileName != null) {
+ try {
+ f = new File(fc.getDirectory() + dataFileName);
+
+ Tree tree = mainFrame.getFacade().readTree(
+ mainFrame.getDisplayWriter(), f.getAbsolutePath(), true);
+ this.treeFilePath = f.getAbsolutePath();
+
+ // check tree consistency
+ boolean consistent = true;
+ if (alignment.getIdCount() == tree.getIdCount()) {
+ for (int id = 0; id < alignment.getIdCount(); id++) {
+ Identifier identifier = alignment.getIdentifier(id);
+ if (tree.whichIdNumber(identifier.getName()) == -1) {
+ consistent = false;
+ break;
+ }
+ }
+ } else
+ consistent = false;
+ if (consistent)
+ setUserTree(tree);
+ else {
+ mainFrame.getDisplayWriter().println("User topology is not consistent with current alignment");
+ setUserTree(null);
+ cmbStrategyMode.setSelectedIndex(0);
+ }
+ } catch (TreeFormatException ex) {
+ mainFrame.getDisplayWriter().println(ex.getMessage());
+ setUserTree(null);
+ cmbStrategyMode.setSelectedIndex(0);
+ } catch (FileNotFoundException ex) {
+ mainFrame.getDisplayWriter().println(ex.getMessage());
+ setUserTree(null);
+ cmbStrategyMode.setSelectedIndex(0);
+ } catch (IOException ex) {
+ mainFrame.getDisplayWriter().println(ex.getMessage());
+ setUserTree(null);
+ cmbStrategyMode.setSelectedIndex(0);
+ }
+ mainFrame.getDisplayWriter().println("");
+ mainFrame.getFrame().toFront();
+ mainFrame.getFrame().transferFocus();
+ }
+
+ } else {
+
+ if (userTree != null)
+ setUserTree(null);
+
+ }
+ }
+
+ private void setUserTree(Tree tree) {
+ this.userTree = tree;
+ org.jdesktop.application.ResourceMap resourceMap
+ = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class)
+ .getContext().getResourceMap(OptionsView.class);
+ if (tree == null) {
+ lblUserTree.setText(resourceMap.getString("msg-no-user-tree-loaded"));
+ lblUserTree.setForeground(Color.GRAY);
+ this.treeFilePath = null;
+ }
+ else {
+ lblUserTree.setText(resourceMap.getString("msg-user-tree-loaded"));
+ lblUserTree.setForeground(XProtTestView.DONE_COLOR);
+ }
+ }
+
+ @Action
+ public void restoreDefault() {
+ for (JCheckBox matrix : cbMatrices) {
+ matrix.setSelected(true);
+ }
+ cbDistGroupCat.setSelected(true);
+ cbDistInvGC.setSelected(true);
+ cbDistInvariant.setSelected(true);
+ cbEmpiricalF.setSelected(true);
+ txtNCat.setText(String.valueOf(DEFAULT_NCAT));
+ sliderProcessors.setValue(sliderProcessors.getMaximum());
+ cmbStrategyMode.setSelectedIndex(DEFAULT_STRATEGY_MODE);
+ onChangeOptions(null);
+ sliderProcessorsStateChanged(null);
+ setUserTree(null);
+ }
+
+ @Action
+ public void close() {
+ this.dispose();
+ }
+
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton btnCancel;
+ private javax.swing.JButton btnCompute;
+ private javax.swing.JButton btnSetDefault;
+ private javax.swing.JCheckBox cbDistGroupCat;
+ private javax.swing.JCheckBox cbDistInvGC;
+ private javax.swing.JCheckBox cbDistInvariant;
+ private javax.swing.JCheckBox cbEmpiricalF;
+ private javax.swing.JComboBox cmbStrategyMode;
+ private javax.swing.JPanel distributionsPanel;
+ private javax.swing.JPanel empiricalFPanel;
+ private javax.swing.JLabel lblNCat;
+ private javax.swing.JLabel lblNumModels;
+ private javax.swing.JLabel lblNumModelsLabel;
+ private javax.swing.JLabel lblNumProc;
+ private javax.swing.JLabel lblStrategyMode;
+ private javax.swing.JLabel lblUserTree;
+ private javax.swing.JLabel msgValidate;
+ private javax.swing.JPanel processorsPanel;
+ private javax.swing.JPanel rateVarPanel;
+ private javax.swing.JSlider sliderProcessors;
+ private javax.swing.JPanel startingTopologiesPanel;
+ private javax.swing.JPanel subMatPanel;
+ private javax.swing.JPanel subMatricesPanel;
+ private javax.swing.JTextField txtNCat;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/compute/RunningFrame.java b/src/main/java/es/uvigo/darwin/xprottest/compute/RunningFrame.java
new file mode 100755
index 0000000..46661f7
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/compute/RunningFrame.java
@@ -0,0 +1,261 @@
+/*
+ * RunningFrame.java
+ *
+ * Created on 1 de octubre de 2009, 19:43
+ */
+package es.uvigo.darwin.xprottest.compute;
+
+import es.uvigo.darwin.prottest.exe.ExternalExecutionManager;
+import es.uvigo.darwin.prottest.global.options.ApplicationOptions;
+import es.uvigo.darwin.xprottest.*;
+import org.jdesktop.application.Action;
+import org.jdesktop.application.Task;
+import es.uvigo.darwin.xprottest.util.TextAreaAppender;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.observer.ModelUpdaterObserver;
+import es.uvigo.darwin.prottest.observer.ObservableModelUpdater;
+import es.uvigo.darwin.prottest.util.Utilities;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import javax.swing.Timer;
+
+/**
+ *
+ * @author diego
+ */
+public class RunningFrame extends javax.swing.JFrame
+ implements ModelUpdaterObserver {
+
+ private static final int TIMER_UPDATE_FREQUENCY = 1000;
+ private XProtTestView mainFrame;
+ private Task task;
+ private int computedModels;
+ private int numModels;
+ private PrintWriter displayWriter;
+ /** Timer for calculate the elapsed time **/
+ private Calendar startTime;
+ /** Timer for display the elapsed time **/
+ Timer timer;
+ private HashMap<String, Long> partialTimestamps;
+ private ArrayList<String> runningModels;
+ // var used to discard concurrent messages during
+ // proccess cancel
+ private boolean running;
+
+ /** Creates new form RunningFrame */
+ public RunningFrame(XProtTestView mainFrame, int numModels) {
+ initComponents();
+ setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
+
+ this.startTime = Calendar.getInstance();
+ this.mainFrame = mainFrame;
+ this.numModels = numModels;
+ this.displayWriter = new PrintWriter(new TextAreaAppender(computedTextArea));
+ this.running = true;
+ this.partialTimestamps = new HashMap<String, Long>();
+ this.runningModels = new ArrayList<String>();
+
+ lblNumModels.setText(String.valueOf(numModels));
+ lblExecutedModels.setText(String.valueOf(computedModels));
+ runningProgress.setMaximum(numModels);
+ runningProgress.setMinimum(0);
+ runningProgress.setValue(computedModels);
+
+ timer = new Timer(TIMER_UPDATE_FREQUENCY, new ActionListener() {
+
+ public void actionPerformed(ActionEvent e) {
+ lblElapsedTime.setText(Utilities.calculateRuntime(
+ startTime.getTimeInMillis(),
+ Calendar.getInstance().getTimeInMillis()));
+ updateHeader();
+ }
+ });
+
+ timer.start();
+ }
+
+ public void setTask(Task task) {
+ this.task = task;
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ lblRunning = new javax.swing.JLabel();
+ runningProgress = new javax.swing.JProgressBar();
+ cancelButton = new javax.swing.JButton();
+ lblNumModels = new javax.swing.JLabel();
+ lblExecutedModels = new javax.swing.JLabel();
+ lblSeparator = new javax.swing.JLabel();
+ computedScrollArea = new javax.swing.JScrollPane();
+ computedTextArea = new javax.swing.JTextArea();
+ lblElapsedTime = new javax.swing.JLabel();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance().getContext().getResourceMap(RunningFrame.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setName("Form"); // NOI18N
+
+ lblRunning.setText(resourceMap.getString("lblRunning.text")); // NOI18N
+ lblRunning.setName("lblRunning"); // NOI18N
+
+ runningProgress.setName("runningProgress"); // NOI18N
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance().getContext().getActionMap(RunningFrame.class, this);
+ cancelButton.setAction(actionMap.get("cancelExecution")); // NOI18N
+ cancelButton.setText(resourceMap.getString("cancelButton.text")); // NOI18N
+ cancelButton.setName("cancelButton"); // NOI18N
+
+ lblNumModels.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
+ lblNumModels.setText(resourceMap.getString("lblNumModels.text")); // NOI18N
+ lblNumModels.setName("lblNumModels"); // NOI18N
+
+ lblExecutedModels.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ lblExecutedModels.setText(resourceMap.getString("lblExecutedModels.text")); // NOI18N
+ lblExecutedModels.setName("lblExecutedModels"); // NOI18N
+
+ lblSeparator.setText(resourceMap.getString("lblSeparator.text")); // NOI18N
+ lblSeparator.setName("lblSeparator"); // NOI18N
+
+ computedScrollArea.setName("computedScrollArea"); // NOI18N
+
+ computedTextArea.setBackground(resourceMap.getColor("computedTextArea.background")); // NOI18N
+ computedTextArea.setColumns(20);
+ computedTextArea.setEditable(false);
+ computedTextArea.setRows(15);
+ computedTextArea.setName("computedTextArea"); // NOI18N
+ computedScrollArea.setViewportView(computedTextArea);
+
+ lblElapsedTime.setText(resourceMap.getString("lblElapsedTime.text")); // NOI18N
+ lblElapsedTime.setName("lblElapsedTime"); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(computedScrollArea, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 329, Short.MAX_VALUE)
+ .addComponent(runningProgress, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 329, Short.MAX_VALUE)
+ .addComponent(lblRunning, javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
+ .addComponent(cancelButton)
+ .addGap(18, 18, 18)
+ .addComponent(lblElapsedTime)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 135, Short.MAX_VALUE)
+ .addComponent(lblExecutedModels)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblSeparator)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblNumModels, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap())
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(layout.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(lblRunning)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(runningProgress, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(cancelButton)
+ .addComponent(lblNumModels)
+ .addComponent(lblSeparator)
+ .addComponent(lblExecutedModels)
+ .addComponent(lblElapsedTime))
+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addComponent(computedScrollArea, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE)
+ .addContainerGap())
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ @Action
+ public void cancelExecution() {
+ ExternalExecutionManager.getInstance().killProcesses();
+ task.cancel(true);
+ unload();
+ }
+
+ public void finishedExecution() {
+ unload();
+ }
+
+ private void unload() {
+ mainFrame.unloadRunningView(this);
+ }
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JButton cancelButton;
+ private javax.swing.JScrollPane computedScrollArea;
+ private javax.swing.JTextArea computedTextArea;
+ private javax.swing.JLabel lblElapsedTime;
+ private javax.swing.JLabel lblExecutedModels;
+ private javax.swing.JLabel lblNumModels;
+ private javax.swing.JLabel lblRunning;
+ private javax.swing.JLabel lblSeparator;
+ private javax.swing.JProgressBar runningProgress;
+ // End of variables declaration//GEN-END:variables
+
+ public void updateHeader() {
+ StringBuffer models = new StringBuffer();
+ Iterator it = runningModels.iterator();
+ while (it.hasNext()) {
+ models.append(it.next());
+ if (it.hasNext()) {
+ models.append(", ");
+ }
+ }
+ lblRunning.setText("Computing: " + models);
+ }
+
+ public void update(ObservableModelUpdater o, Model model, ApplicationOptions options) {
+ if (running) {
+ if (options == null) {
+// displayWriter.println("Computing " + model.getModelName() + "...");
+ runningModels.add(model.getModelName());
+ partialTimestamps.put(model.getModelName(), Calendar.getInstance().getTimeInMillis());
+ } else {
+ computedModels++;
+ runningProgress.setValue(computedModels);
+ lblExecutedModels.setText(String.valueOf(computedModels));
+ runningModels.remove(model.getModelName());
+ if (model.isComputed()) {
+ StringBuffer partialTime = new StringBuffer("");
+ displayWriter.println("Computed " + model.getModelName() + "(" + model.getLk() + ")");
+ long currentTimestamp = Calendar.getInstance().getTimeInMillis();
+ long partialTimestamp = partialTimestamps.get(model.getModelName());
+ displayWriter.println(" " + Utilities.calculateRuntime(partialTimestamp, currentTimestamp) +
+ " Elapsed time: " + Utilities.calculateRuntime(startTime.getTimeInMillis(), currentTimestamp));
+ } else {
+// if (options != null) {
+ // Follow error behavior
+ if (mainFrame.getErrorBehavior() == XProtTestApp.ERROR_BEHAVIOR_CONTINUE) {
+ displayWriter.println("There were errors computing " + model.getModelName());
+ } else if (mainFrame.getErrorBehavior() == XProtTestApp.ERROR_BEHAVIOR_STOP) {
+ running = false;
+ mainFrame.computationInterrupted();
+ cancelExecution();
+ } else {
+ running = false;
+ cancelExecution();
+ throw new RuntimeException("Unsupported error behavior : " + mainFrame.getErrorBehavior());
+ }
+// }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/compute/resources/OptionsView.properties b/src/main/java/es/uvigo/darwin/xprottest/compute/resources/OptionsView.properties
new file mode 100755
index 0000000..36c1b89
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/compute/resources/OptionsView.properties
@@ -0,0 +1,62 @@
+# display
+
+distributionsPanel.border.titleColor=102, 102, 153
+empiricalFPanel.border.titleColor=102, 102, 153
+lblNumModelsLabel.foreground=128, 128, 128
+lblUserTree.foreground=128, 128, 128
+processorsPanel.border.titleColor=102, 102, 153
+rateVarPanel.border.titleColor=102, 102, 153
+startingTopologiesPanel.border.titleColor=102, 102, 153
+subMatPanel.border.titleColor=102, 102, 153
+
+# messages
+
+msg-user-tree-loaded=Loaded user topology
+msg-no-user-tree-loaded=No user topology loaded
+
+# labels
+
+Form.title=XProtTest HPC Lk Computation Options
+distributionsPanel.border.title=Distributions
+empiricalFPanel.border.title=Amino-acid frequencies
+processorsPanel.border.title=Number of processors requested
+rateVarPanel.border.title=Rate variation
+startingTopologiesPanel.border.title=Starting topology
+subMatPanel.border.title=Substitution model matrices
+
+btnCancel.text=Cancel
+btnCompute.text=Compute
+btnSetDefault.text=Restore
+cbDistInvariant.text=+I
+cbDistInvGC.text=+I+G
+cbDistGroupCat.text=+G
+cbEmpiricalF.text=Empirical
+close.Action.text=Close
+lblNCat.text=Categories
+lblNumModelsLabel.text=Total number of models
+lbl-amino-acid-frequencies=Amino-acid Frequencies
+lbl-base-frequencies=Base Frequencies
+lbl-strategy-mode=Base tree for likelihood calculations:
+loadTree.dialogTitle=Load User Topology
+msgValidate.text=Invalid number of rate categories
+number-of-processors=Number of processors
+restoreDefault.Action.text=Restore default values
+
+# tooltip texts
+
+btnCancel.toolTipText=Cancel
+btnSetDefault.toolTipText=Restore default settings
+cbDistInvariant.toolTipText=Consider a proportion of invariable sites
+cbDistGroupCat.toolTipText=Consider rate variation among sites with a number of rate categories
+cbEmpiricalF.toolTipText=Use empirical frequencies distribution
+cmbStrategyMode.toolTipText=Select strategy mode to compute likelihood scores
+sliderProcessors.toolTipText=Select the number of processors to compute
+subMatricesPanel.toolTipText=Select substitution model matrixes to compute
+txtNCatToolTip=Number of rate categories
+txtNCat.toolTip=Number of categories
+
+# other
+
+restoreDefault.Action.shortDescription=Restore default values
+close.Action.shortDescription=Close window
+
diff --git a/src/main/java/es/uvigo/darwin/xprottest/compute/resources/RunningFrame.properties b/src/main/java/es/uvigo/darwin/xprottest/compute/resources/RunningFrame.properties
new file mode 100755
index 0000000..b275993
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/compute/resources/RunningFrame.properties
@@ -0,0 +1,12 @@
+cancelButton.text=Cancel
+lblSeparator.text=/
+lblExecutedModels.text=000
+lblNumModels.text=000
+lblRunning.text=Running...
+cancelExecution.Action.text=Cancel
+cancelExecution.Action.accelerator=shift pressed C
+cancelExecution.Action.shortDescription=Cancel Likelihood Computation
+#NOI18N
+computedTextArea.background=238, 238, 238
+Form.title=Running status
+lblElapsedTime.text=00:00:00
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/CreditsBox.properties b/src/main/java/es/uvigo/darwin/xprottest/resources/CreditsBox.properties
new file mode 100755
index 0000000..6384dfa
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/resources/CreditsBox.properties
@@ -0,0 +1,16 @@
+title = About: ${Application.title} ${Application.version}
+
+closeAboutBox.Action.text = &Close
+
+appDescLabel.text=<html>Selection of best-fit models of protein evolution
+
+versionLabel.text=Product Version\:
+
+homepageLabel.text=Homepage\:
+#NOI18N
+imageLabel.icon=prottestlogo.gif
+lblDisclaimer.text=Use of ProtTest's logo kindly allowed by IconBAZAAR
+#NOI18N
+lblDisclaimer.font=DejaVu Sans-Plain-10
+#NOI18N
+lblDisclaimer.foreground=106, 106, 106
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/PreferencesView.properties b/src/main/java/es/uvigo/darwin/xprottest/resources/PreferencesView.properties
new file mode 100755
index 0000000..ff1909d
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/resources/PreferencesView.properties
@@ -0,0 +1,24 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+Form.title=XProtTest Preferences
+lblErrorBehavior.text=Behavior when errors:
+Accept.Action.text=
+Accept.Action.shortDescription=
+btnCancel.text=jButton1
+Cancel.Action.text=
+Cancel.Action.shortDescription=
+lblContinue.text=Continue:
+error-continue-desc=Continue execution even with errors\nand compute partial results
+#NOI18N
+lblContinue.foreground=102, 102, 102
+error-stop-desc=Cancel execution when an error is\ndetected
+lblStop.text=Stop:
+#NOI18N
+lblStop.foreground=102, 102, 102
+#NOI18N
+txtStopDesc.foreground=102, 102, 102
+#NOI18N
+txtStopDesc.background=238, 238, 238
+#NOI18N
+txtContinueDesc.foreground=102, 102, 102
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestAboutBox.properties b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestAboutBox.properties
new file mode 100755
index 0000000..25aa449
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestAboutBox.properties
@@ -0,0 +1,19 @@
+title = About: ${Application.title} ${Application.version}
+
+closeAboutBox.Action.text = &Close
+
+appDescLabel.text=<html>Selection of best-fit models of protein evolution
+
+versionLabel.text=Product Version\:
+
+homepageLabel.text=Homepage\:
+
+citationLabel.text=Citation\:
+
+#NOI18N
+imageLabel.icon=prottestlogo.gif
+lblDisclaimer.text=Use of ProtTest's logo kindly allowed by IconBAZAAR
+#NOI18N
+lblDisclaimer.font=DejaVu Sans-Plain-10
+#NOI18N
+lblDisclaimer.foreground=106, 106, 106
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestApp.properties b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestApp.properties
new file mode 100755
index 0000000..2503ae5
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestApp.properties
@@ -0,0 +1,38 @@
+# Application global resources
+
+Application.name = XProtTest
+Application.title = XProtTest
+Application.version = 3.3
+Application.vendor = Phylogenomics
+Application.homepage = http://code.google.com/p/prottest3
+Application.citation1 = Darriba D, Taboada GL, Doallo R, Posada D. ProtTest 3: fast selection
+Application.citation2 = of best-fit models of protein evolution. Bioinformatics, 27:1164-1165, 2011
+Application.description = A user graphical interface for ProtTest 3 for amino-acid model selection
+Application.vendorId = Darwin
+Application.id = XProtTest
+Application.lookAndFeel = system
+computeLikelihood.Action.text=Compute
+computeLikelihood.Action.shortDescription=Compute Likelihood Scores
+models-not-complete=Warning! The model set computation is not complete
+menu-edit=Edit
+menu-copy=Copy
+menu-selectAll=Select all
+menu-window=Window
+menu-close=Close
+menu-preferences=Preferences
+quit.Action.text=Exit
+quit.Action.accelerator=ctrl pressed Q
+quit.Action.shortDescription=Exit the application
+
+# --------------------
+# Default error behavior
+# 0 = Continue
+# 1 = Stop
+# --------------------
+default-error-behavior=0
+button-accept=Accept
+button-cancel=Cancel
+Form.background=238, 238, 238
+menu-manual=ProtTest Manual
+export-to-console=Export to main console
+txtNCat.defaultText=4
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestView.properties b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestView.properties
new file mode 100755
index 0000000..dc84b6f
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/resources/XProtTestView.properties
@@ -0,0 +1,91 @@
+
+# status bar resources
+
+StatusBar.messageTimeout = 5000
+StatusBar.busyAnimationRate = 30
+StatusBar.idleIcon = busyicons/idle-icon.png
+StatusBar.busyIcons[0] = busyicons/busy-icon0.png
+StatusBar.busyIcons[1] = busyicons/busy-icon1.png
+StatusBar.busyIcons[2] = busyicons/busy-icon2.png
+StatusBar.busyIcons[3] = busyicons/busy-icon3.png
+StatusBar.busyIcons[4] = busyicons/busy-icon4.png
+StatusBar.busyIcons[5] = busyicons/busy-icon5.png
+StatusBar.busyIcons[6] = busyicons/busy-icon6.png
+StatusBar.busyIcons[7] = busyicons/busy-icon7.png
+StatusBar.busyIcons[8] = busyicons/busy-icon8.png
+StatusBar.busyIcons[9] = busyicons/busy-icon9.png
+StatusBar.busyIcons[10] = busyicons/busy-icon10.png
+StatusBar.busyIcons[11] = busyicons/busy-icon11.png
+StatusBar.busyIcons[12] = busyicons/busy-icon12.png
+StatusBar.busyIcons[13] = busyicons/busy-icon13.png
+StatusBar.busyIcons[14] = busyicons/busy-icon14.png
+
+# appearance
+
+lblDataFileStatus.foreground=255, 0, 0
+lblLikelihoodStatus.foreground=255, 0, 0
+mainPanel.background=238, 238, 238
+menuFileExit.icon=${null}
+lblMoreInfo.foreground=255, 0, 0
+statusPanel.foreground=0, 0, 255
+statusPanel.border.shadowColor=89, 89, 89
+statusPanel.border.highlightColor=182, 182, 182
+statusPanel.background=220, 220, 220
+
+aa-frequencies=Observed Amino-Acid Frequencies
+msg-no-data=No data file loaded
+msg-data-loaded=Alignment:
+msg-no-tree=No tree file loaded
+msg-tree-loaded=Tree:
+msg-no-lnl-calculated=Likelihood scores not available
+msg-lnl-calculated=Likelihood scores available!
+msg-lnl-error=There was an error computing likelihood scores!
+loadAlignment.dialogTitle=Load Alignment
+
+# menu items
+
+editSelectAllMenuItem.text=Item
+errorMenuItem.text=Show error log
+item-show-frequencies=Show observed amino-acid frequencies
+item-compute-likelihood=Compute likelihood scores
+item-file=File
+item-load-alignment=Load Alignment
+item-analysis=Analysis
+item-exit=Exit
+item-results=Selection
+item-results-sub=Results
+item-edit=Edit
+item-help=Help
+item-about=About
+item-credits=Credits
+item-about-window=About...
+item-credits-window=Credits
+item-load-tree=Load Tree File
+item-print-console=Print Console
+item-save-console=Save Console
+item-show-tree=Show Trees
+averagingMenuItem.text=Phylogenetic averaging
+manualMenuItem.text=Item
+preferencesMenuItem.text=Item
+showAboutBox.Action.text = &About...
+showCreditsBox.Action.text = &Credits
+
+# tooltip texts
+
+averagingMenuItem.toolTipText=Build consensus tree
+computeMenuItem.toolTipText=Optimize the model set
+editCopyMenuItem.toolTipText=Copy selected data
+editPreferencesMenuItem.toolTipText=Set the application preferences
+editSelectAllMenuItem.toolTipText=Select all text in the main console
+errorMenuItem.toolTipText=Display error console
+resultsMenuItem.toolTipText=Show model selection results
+showAboutBox.Action.shortDescription = Show the application's information dialog
+showAboutBox.Action.shortDescription = Show the application's credits
+showFrequenciesItem.toolTipText=Show empirical amino-acid frequencies from the input alignment
+showTreeMenuItem.toolTipText=Show inferred phylogenies from each model
+
+# labels
+
+lblMoreInfo.text=Press Ctrl+Shift+E to open Error Log
+models-not-complete=The model set computation is not complete
+msg-see-error-log=Please see error log for details.
\ No newline at end of file
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/about.png b/src/main/java/es/uvigo/darwin/xprottest/resources/about.png
new file mode 100755
index 0000000..c6dfe0a
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/about.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon0.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon0.png
new file mode 100755
index 0000000..242c0c8
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon0.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon1.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon1.png
new file mode 100755
index 0000000..9f6f634
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon1.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon10.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon10.png
new file mode 100755
index 0000000..c4ef4a1
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon10.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon11.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon11.png
new file mode 100755
index 0000000..6eca1f5
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon11.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon12.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon12.png
new file mode 100755
index 0000000..e447ee8
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon12.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon13.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon13.png
new file mode 100755
index 0000000..848a6f1
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon13.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon14.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon14.png
new file mode 100755
index 0000000..7b3561d
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon14.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon2.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon2.png
new file mode 100755
index 0000000..c866e62
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon2.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon3.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon3.png
new file mode 100755
index 0000000..9be22fa
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon3.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon4.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon4.png
new file mode 100755
index 0000000..f07c20d
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon4.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon5.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon5.png
new file mode 100755
index 0000000..653fc9c
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon5.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon6.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon6.png
new file mode 100755
index 0000000..7035572
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon6.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon7.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon7.png
new file mode 100755
index 0000000..49fbc6e
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon7.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon8.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon8.png
new file mode 100755
index 0000000..e1a5a40
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon8.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon9.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon9.png
new file mode 100755
index 0000000..8278012
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/busy-icon9.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/idle-icon.png b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/idle-icon.png
new file mode 100755
index 0000000..50312f8
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/busyicons/idle-icon.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/prottestlogo.gif b/src/main/java/es/uvigo/darwin/xprottest/resources/prottestlogo.gif
new file mode 100755
index 0000000..eaaf955
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/prottestlogo.gif differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/resources/splash.png b/src/main/java/es/uvigo/darwin/xprottest/resources/splash.png
new file mode 100755
index 0000000..a1fbdc1
Binary files /dev/null and b/src/main/java/es/uvigo/darwin/xprottest/resources/splash.png differ
diff --git a/src/main/java/es/uvigo/darwin/xprottest/results/Bundle.properties b/src/main/java/es/uvigo/darwin/xprottest/results/Bundle.properties
new file mode 100755
index 0000000..1ebdc43
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/results/Bundle.properties
@@ -0,0 +1,19 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+lbl-overall-alpha=Alpha
+lbl-overall-alpha-inv=Alpha-Inv
+lbl-overall-inv-alpha=Inv-Alpha
+lbl-overall-inv=Inv
+lbl-overall=Model-averaged estimates
+lbl-overall_1=Model-averaged estimates
+lbl-overall_2=Model-averaged estimates
+lbl-overall-alpha_1=Alpha
+lbl-overall-alpha-inv_1=Alpha-Inv
+lbl-overall-inv-alpha_1=Inv-Alpha
+lbl-overall-inv_1=Inv
+lbl-overall-alpha_2=Alpha
+lbl-overall-alpha-inv_2=Alpha-Inv
+lbl-overall-inv-alpha_2=Inv-Alpha
+lbl-overall-inv_2=Inv
+btnExport.text=Export to main console
diff --git a/src/main/java/es/uvigo/darwin/xprottest/results/ErrorLogView.java b/src/main/java/es/uvigo/darwin/xprottest/results/ErrorLogView.java
new file mode 100755
index 0000000..c661541
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/results/ErrorLogView.java
@@ -0,0 +1,101 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.results;
+
+import es.uvigo.darwin.prottest.util.WriterOutputStream;
+import es.uvigo.darwin.prottest.util.logging.ProtTestLogFormatter;
+import java.io.PrintWriter;
+import es.uvigo.darwin.xprottest.util.TextAreaAppender;
+import java.util.logging.Filter;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
+import java.util.logging.StreamHandler;
+
+/**
+ *
+ * @author Diego Darriba
+ */
+public class ErrorLogView extends javax.swing.JFrame {
+
+ private PrintWriter errorWriter;
+ private Handler logHandler;
+
+ public Handler getLogHandler() {
+ return logHandler;
+ }
+
+ /** Creates new form ErrorLogView */
+ public ErrorLogView() {
+ initComponents();
+ errorWriter = new PrintWriter(new TextAreaAppender(errorTextArea));
+ logHandler = new StreamHandler(new WriterOutputStream(errorWriter),
+ new ProtTestLogFormatter());
+ logHandler.setFilter(new Filter(){
+
+ public boolean isLoggable(LogRecord lr) {
+ return lr.getLevel().equals(Level.SEVERE);
+ }
+
+ });
+ }
+
+ /** This method is called from within the constructor to
+ * initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is
+ * always regenerated by the Form Editor.
+ */
+ // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ errorScrollPane = new javax.swing.JScrollPane();
+ errorTextArea = new javax.swing.JTextArea();
+
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(es.uvigo.darwin.xprottest.XProtTestApp.class).getContext().getResourceMap(ErrorLogView.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setName("Form"); // NOI18N
+
+ errorScrollPane.setName("errorScrollPane"); // NOI18N
+
+ errorTextArea.setColumns(15);
+ errorTextArea.setEditable(false);
+ errorTextArea.setFont(resourceMap.getFont("errorTextArea.font")); // NOI18N
+ errorTextArea.setRows(30);
+ errorTextArea.setName("errorTextArea"); // NOI18N
+ errorScrollPane.setViewportView(errorTextArea);
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(errorScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 601, Short.MAX_VALUE)
+ );
+ layout.setVerticalGroup(
+ layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(errorScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 426, Short.MAX_VALUE)
+ );
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+ private javax.swing.JScrollPane errorScrollPane;
+ private javax.swing.JTextArea errorTextArea;
+ // End of variables declaration//GEN-END:variables
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/results/ResultsView.java b/src/main/java/es/uvigo/darwin/xprottest/results/ResultsView.java
new file mode 100755
index 0000000..45c7934
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/results/ResultsView.java
@@ -0,0 +1,2483 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+ */
+package es.uvigo.darwin.xprottest.results;
+
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.CRITERION_NAMES;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.CRITERION_PRECISSION;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.PARAMETER_F;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.PARAMETER_G;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.PARAMETER_I;
+import static es.uvigo.darwin.prottest.global.ProtTestConstants.PARAMETER_IG;
+import static es.uvigo.darwin.prottest.selection.printer.PrintFramework.getDisplayValue;
+
+import java.util.Collection;
+
+import javax.swing.JTable;
+import javax.swing.RowSorter;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+
+import org.jdesktop.application.Action;
+
+import pal.alignment.Alignment;
+import es.uvigo.darwin.prottest.facade.util.SelectionChunk;
+import es.uvigo.darwin.prottest.model.Model;
+import es.uvigo.darwin.prottest.selection.InformationCriterion;
+import es.uvigo.darwin.prottest.selection.model.SelectionModel;
+import es.uvigo.darwin.prottest.util.printer.ProtTestFormattedOutput;
+import es.uvigo.darwin.prottest.util.printer.ProtTestPrinter;
+import es.uvigo.darwin.xprottest.XProtTestView;
+
+/**
+ * The view of the model selection results. It includes a selection under all
+ * supported information criterions.
+ *
+ * @author Diego Darriba
+ */
+public class ResultsView extends javax.swing.JFrame {
+
+ private static final int AIC_TAB = 0;
+ private static final int BIC_TAB = 1;
+ private static final int AICC_TAB = 2;
+ private static final int DT_TAB = 3;
+ private int rows;
+ javax.swing.table.DefaultTableModel aicTableModel, bicTableModel,
+ aiccTableModel, dtTableModel;
+ private Model[] models;
+ private Alignment alignment;
+ private XProtTestView mainFrame;
+ private SelectionChunk aicResults, bicResults, aiccResults, dtResults;
+
+ // private boolean existInvModels = false,
+ // existGammaModels = false,
+ // existGammaInvModels = false,
+ // existFModels = false;
+
+ private void loadCache(double confidenceInterval) {
+ // criterion cache
+ aicResults = mainFrame.getFacade().computeInformationCriterion(
+ alignment, models, SelectionChunk.AIC, confidenceInterval);
+ bicResults = mainFrame.getFacade().computeInformationCriterion(
+ alignment, models, SelectionChunk.BIC, confidenceInterval);
+ aiccResults = mainFrame.getFacade().computeInformationCriterion(
+ alignment, models, SelectionChunk.AICC, confidenceInterval);
+ dtResults = mainFrame.getFacade().computeInformationCriterion(
+ alignment, models, SelectionChunk.DT, confidenceInterval);
+ }
+
+ /** Creates new form ResultsView */
+ public ResultsView(XProtTestView mainFrame, Alignment alignment,
+ Model[] models, boolean correctDone) {
+ this.mainFrame = mainFrame;
+ this.alignment = alignment;
+ this.rows = models.length;
+ this.models = models;
+
+ // for (Model model : models) {
+ // if (!existInvModels && model.isInv() && !model.isGamma()) {
+ // existInvModels = true;
+ // } else if (!existGammaModels && !model.isInv() && model.isGamma()) {
+ // existGammaModels = true;
+ // } else if (!existGammaInvModels && model.isInv() && model.isGamma())
+ // {
+ // existGammaInvModels = true;
+ // } else if (!existFModels && model.isPlusF()) {
+ // existFModels = true;
+ // }
+ // }
+
+ initComponents();
+ loadCache(Double.parseDouble(sliderConfidenceInterval.getValue() + "") / 100);
+ fillInResults();
+
+ lblNotComplete.setVisible(!correctDone);
+ }
+
+ /**
+ * This method is called from within the constructor to initialize the form.
+ * WARNING: Do NOT modify this code. The content of this method is always
+ * regenerated by the Form Editor.
+ */
+ @SuppressWarnings("unchecked")
+ // <editor-fold defaultstate="collapsed"
+ // desc="Generated Code">//GEN-BEGIN:initComponents
+ private void initComponents() {
+
+ resultsTabbedPane = new javax.swing.JTabbedPane();
+ aicPanel = new javax.swing.JPanel();
+ aicScrollPanel = new javax.swing.JScrollPane();
+ aicTable = new javax.swing.JTable();
+ aicDataPanel = new javax.swing.JPanel();
+ lblAICOverall = new javax.swing.JLabel();
+ lblAICOverallAlpha = new javax.swing.JLabel();
+ lblAICOverallAlphaInv = new javax.swing.JLabel();
+ lblAICOverallInvAlpha = new javax.swing.JLabel();
+ lblAICOverallInv = new javax.swing.JLabel();
+ displayAICoAlpha = new javax.swing.JLabel();
+ displayAICoAlphaInv = new javax.swing.JLabel();
+ displayAICoInvAlpha = new javax.swing.JLabel();
+ displayAICoInv = new javax.swing.JLabel();
+ lblAICPI = new javax.swing.JLabel();
+ lblAICImpInv = new javax.swing.JLabel();
+ lblAICImpAlpha = new javax.swing.JLabel();
+ lblAICImpF = new javax.swing.JLabel();
+ lblAICImpAlphaInv = new javax.swing.JLabel();
+ displayAICImpInv = new javax.swing.JLabel();
+ displayAICImpAlpha = new javax.swing.JLabel();
+ displayAICImpAlphaInv = new javax.swing.JLabel();
+ displayAICImpF = new javax.swing.JLabel();
+ bicPanel = new javax.swing.JPanel();
+ bicScrollPanel = new javax.swing.JScrollPane();
+ bicTable = new javax.swing.JTable();
+ bicDataPanel = new javax.swing.JPanel();
+ lblBICOverall = new javax.swing.JLabel();
+ lblBICOverallAlpha = new javax.swing.JLabel();
+ lblBICOverallAlphaInv = new javax.swing.JLabel();
+ lblBICOverallInvAlpha = new javax.swing.JLabel();
+ lblBICOverallInv = new javax.swing.JLabel();
+ displayBICoAlpha = new javax.swing.JLabel();
+ displayBICoAlphaInv = new javax.swing.JLabel();
+ displayBICoInvAlpha = new javax.swing.JLabel();
+ displayBICoInv = new javax.swing.JLabel();
+ lblBICImpInv = new javax.swing.JLabel();
+ lblBICImpAlpha = new javax.swing.JLabel();
+ lblBICImpF = new javax.swing.JLabel();
+ lblBICImpAlphaInv = new javax.swing.JLabel();
+ displayBICImpInv = new javax.swing.JLabel();
+ displayBICImpAlpha = new javax.swing.JLabel();
+ displayBICImpAlphaInv = new javax.swing.JLabel();
+ displayBICImpF = new javax.swing.JLabel();
+ lblBICPI = new javax.swing.JLabel();
+ aiccPanel = new javax.swing.JPanel();
+ aiccScrollPanel = new javax.swing.JScrollPane();
+ aiccTable = new javax.swing.JTable();
+ aiccDataPanel = new javax.swing.JPanel();
+ lblAICcOverall = new javax.swing.JLabel();
+ lblAICcOverallAlpha = new javax.swing.JLabel();
+ lblAICcOverallAlphaInv = new javax.swing.JLabel();
+ lblAICcOverallInvAlpha = new javax.swing.JLabel();
+ lblAICcOverallInv = new javax.swing.JLabel();
+ displayAICcoAlpha = new javax.swing.JLabel();
+ displayAICcoAlphaInv = new javax.swing.JLabel();
+ displayAICcoInvAlpha = new javax.swing.JLabel();
+ displayAICcoInv = new javax.swing.JLabel();
+ lblAICcPI = new javax.swing.JLabel();
+ lblAICcImpInv = new javax.swing.JLabel();
+ lblAICcImpAlpha = new javax.swing.JLabel();
+ lblAICcImpF = new javax.swing.JLabel();
+ lblAICcImpAlphaInv = new javax.swing.JLabel();
+ displayAICcImpInv = new javax.swing.JLabel();
+ displayAICcImpAlpha = new javax.swing.JLabel();
+ displayAICcImpAlphaInv = new javax.swing.JLabel();
+ displayAICcImpF = new javax.swing.JLabel();
+ dtPanel = new javax.swing.JPanel();
+ dtScrollPanel = new javax.swing.JScrollPane();
+ dtTable = new javax.swing.JTable();
+ dtDataPanel = new javax.swing.JPanel();
+ lblDTOverall = new javax.swing.JLabel();
+ lblDTOverallAlpha = new javax.swing.JLabel();
+ lblDTOverallAlphaInv = new javax.swing.JLabel();
+ lblDTOverallInvAlpha = new javax.swing.JLabel();
+ lblDTOverallInv = new javax.swing.JLabel();
+ displayDToAlpha = new javax.swing.JLabel();
+ displayDToAlphaInv = new javax.swing.JLabel();
+ displayDToInvAlpha = new javax.swing.JLabel();
+ displayDToInv = new javax.swing.JLabel();
+ lblDTPI = new javax.swing.JLabel();
+ lblDTImpInv = new javax.swing.JLabel();
+ lblDTImpAlpha = new javax.swing.JLabel();
+ lblDTImpF = new javax.swing.JLabel();
+ lblDTImpAlphaInv = new javax.swing.JLabel();
+ displayDTImpInv = new javax.swing.JLabel();
+ displayDTImpAlpha = new javax.swing.JLabel();
+ displayDTImpAlphaInv = new javax.swing.JLabel();
+ displayDTImpF = new javax.swing.JLabel();
+ sliderConfidenceInterval = new javax.swing.JSlider();
+ lblConfInt = new javax.swing.JLabel();
+ jScrollPane1 = new javax.swing.JScrollPane();
+ lblCommandLine = new javax.swing.JTextArea();
+ lblComandLineLabel = new javax.swing.JLabel();
+ lblSelectedModelLabel = new javax.swing.JLabel();
+ lblSelectedModel = new javax.swing.JLabel();
+ lblNotComplete = new javax.swing.JLabel();
+ lblConfidence = new javax.swing.JLabel();
+ btnExport = new javax.swing.JButton();
+
+ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+ org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application
+ .getInstance().getContext().getResourceMap(ResultsView.class);
+ setTitle(resourceMap.getString("Form.title")); // NOI18N
+ setName("Form"); // NOI18N
+ setResizable(false);
+
+ resultsTabbedPane
+ .setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);
+ resultsTabbedPane.setName("resultsTabbedPane"); // NOI18N
+
+ aicPanel.setName("aicPanel"); // NOI18N
+
+ aicScrollPanel.setName("aicScrollPanel"); // NOI18N
+
+ aicTableModel = new javax.swing.table.DefaultTableModel() {
+ public Class getColumnClass(int column) {
+ if (column == 0)
+ return String.class;
+ if (column >= 1 && column <= getColumnCount()) {
+ try {
+ return getValueAt(0, column).getClass();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return Object.class;
+ }
+ } else
+ return Object.class;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+ };
+ aicTableModel.addColumn("Model", new String[rows][1]);
+ aicTableModel.addColumn("-LnL", new Double[rows][1]);
+ aicTableModel.addColumn("AIC", new Double[rows][1]);
+ aicTableModel.addColumn("deltaAIC", new Double[rows][1]);
+ aicTableModel.addColumn("AIC weight", new Double[rows][1]);
+ aicTable.setModel(aicTableModel);
+ aicTable.setCellSelectionEnabled(true);
+ aicTable.setName("aicTable"); // NOI18N
+ RowSorter<TableModel> aicSorter = new TableRowSorter<TableModel>(
+ aicTableModel);
+ aicTable.setRowSorter(aicSorter);
+
+ SelectionListener listener = new SelectionListener(aicTable);
+ aicTable.getSelectionModel().addListSelectionListener(listener);
+ aicTable.getColumnModel().getSelectionModel()
+ .addListSelectionListener(listener);
+ aicScrollPanel.setViewportView(aicTable);
+
+ aicDataPanel.setBorder(javax.swing.BorderFactory
+ .createLineBorder(new java.awt.Color(0, 0, 0)));
+ aicDataPanel.setName("aicDataPanel"); // NOI18N
+
+ java.util.ResourceBundle bundle = java.util.ResourceBundle
+ .getBundle("es/uvigo/darwin/xprottest/results/resources/ResultsView"); // NOI18N
+ lblAICOverall.setText(bundle.getString("lbl-overall")); // NOI18N
+ lblAICOverall.setName("lblAICOverall"); // NOI18N
+
+ lblAICOverallAlpha.setText(bundle.getString("lbl-overall-alpha")); // NOI18N
+ lblAICOverallAlpha.setName("lblAICOverallAlpha"); // NOI18N
+
+ lblAICOverallAlphaInv
+ .setText(bundle.getString("lbl-overall-alpha-inv")); // NOI18N
+ lblAICOverallAlphaInv.setName("lblAICOverallAlphaInv"); // NOI18N
+
+ lblAICOverallInvAlpha
+ .setText(bundle.getString("lbl-overall-inv-alpha")); // NOI18N
+ lblAICOverallInvAlpha.setName("lblAICOverallInvAlpha"); // NOI18N
+
+ lblAICOverallInv.setText(bundle.getString("lbl-overall-inv")); // NOI18N
+ lblAICOverallInv.setName("lblAICOverallInv"); // NOI18N
+
+ displayAICoAlpha
+ .setText(resourceMap.getString("displayAICoAlpha.text")); // NOI18N
+ displayAICoAlpha.setName("displayAICoAlpha"); // NOI18N
+
+ displayAICoAlphaInv.setText(resourceMap
+ .getString("displayAICoAlphaInv.text")); // NOI18N
+ displayAICoAlphaInv.setName("displayAICoAlphaInv"); // NOI18N
+
+ displayAICoInvAlpha.setText(resourceMap
+ .getString("displayAICoInvAlpha.text")); // NOI18N
+ displayAICoInvAlpha.setName("displayAICoInvAlpha"); // NOI18N
+
+ displayAICoInv.setText(resourceMap.getString("displayAICoInv.text")); // NOI18N
+ displayAICoInv.setName("displayAICoInv"); // NOI18N
+
+ lblAICPI.setText(resourceMap.getString("lblAICPI.text")); // NOI18N
+ lblAICPI.setName("lblAICPI"); // NOI18N
+
+ lblAICImpInv.setText(resourceMap.getString("lblAICImpInv.text")); // NOI18N
+ lblAICImpInv.setName("lblAICImpInv"); // NOI18N
+
+ lblAICImpAlpha.setText(resourceMap.getString("lblAICImpAlpha.text")); // NOI18N
+ lblAICImpAlpha.setName("lblAICImpAlpha"); // NOI18N
+
+ lblAICImpF.setText(resourceMap.getString("lblAICImpF.text")); // NOI18N
+ lblAICImpF.setName("lblAICImpF"); // NOI18N
+
+ lblAICImpAlphaInv.setText(resourceMap
+ .getString("lblAICImpAlphaInv.text")); // NOI18N
+ lblAICImpAlphaInv.setName("lblAICImpAlphaInv"); // NOI18N
+
+ displayAICImpInv
+ .setText(resourceMap.getString("displayAICImpInv.text")); // NOI18N
+ displayAICImpInv.setName("displayAICImpInv"); // NOI18N
+
+ displayAICImpAlpha.setText(resourceMap
+ .getString("displayAICImpAlpha.text")); // NOI18N
+ displayAICImpAlpha.setName("displayAICImpAlpha"); // NOI18N
+
+ displayAICImpAlphaInv.setText(resourceMap
+ .getString("displayAICImpAlphaInv.text")); // NOI18N
+ displayAICImpAlphaInv.setName("displayAICImpAlphaInv"); // NOI18N
+
+ displayAICImpF.setText(resourceMap.getString("displayAICImpF.text")); // NOI18N
+ displayAICImpF.setName("displayAICImpF"); // NOI18N
+
+ javax.swing.GroupLayout aicDataPanelLayout = new javax.swing.GroupLayout(
+ aicDataPanel);
+ aicDataPanel.setLayout(aicDataPanelLayout);
+ aicDataPanelLayout
+ .setHorizontalGroup(aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addGap(44,
+ 44,
+ 44)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ lblAICOverallAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICOverallAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICOverallInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICOverallInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addGap(18,
+ 18,
+ 18)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ displayAICoInv)
+ .addComponent(
+ displayAICoInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICoAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICoAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE))
+ .addGap(40,
+ 40,
+ 40))
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ lblAICOverall,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 366,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ false)
+ .addComponent(
+ lblAICImpAlpha,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICImpInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICImpF,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICImpAlphaInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 59,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ displayAICImpInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 83,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICImpAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICImpAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICImpF,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)))
+ .addComponent(
+ lblAICPI,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 237,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ aicDataPanelLayout
+ .setVerticalGroup(aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICOverall)
+ .addComponent(lblAICPI))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICOverallAlpha)
+ .addComponent(
+ displayAICoAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICOverallAlphaInv)
+ .addComponent(
+ displayAICoAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICOverallInvAlpha)
+ .addComponent(
+ displayAICoInvAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICOverallInv)
+ .addComponent(
+ displayAICoInv)))
+ .addGroup(
+ aicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICImpInv)
+ .addComponent(
+ displayAICImpInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICImpAlpha)
+ .addComponent(
+ displayAICImpAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICImpAlphaInv)
+ .addComponent(
+ displayAICImpAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICImpF)
+ .addComponent(
+ displayAICImpF))))
+ .addContainerGap(
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+
+ javax.swing.GroupLayout aicPanelLayout = new javax.swing.GroupLayout(
+ aicPanel);
+ aicPanel.setLayout(aicPanelLayout);
+ aicPanelLayout
+ .setHorizontalGroup(aicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aicPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ aicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ aicScrollPanel,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 635,
+ Short.MAX_VALUE)
+ .addComponent(
+ aicDataPanel,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ aicPanelLayout
+ .setVerticalGroup(aicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ aicPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ aicScrollPanel,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 300, Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ aicDataPanel,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()));
+
+ resultsTabbedPane.addTab(
+ resourceMap.getString("aicPanel.TabConstraints.tabTitle"),
+ aicPanel); // NOI18N
+
+ bicPanel.setName("bicPanel"); // NOI18N
+
+ bicScrollPanel.setName("bicScrollPanel"); // NOI18N
+
+ bicTableModel = new javax.swing.table.DefaultTableModel() {
+ public Class getColumnClass(int column) {
+ if (column >= 0 && column <= getColumnCount()) {
+ try {
+ return getValueAt(0, column).getClass();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return Object.class;
+ }
+ } else
+ return Object.class;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+ };
+ bicTableModel.addColumn("Model", new String[rows][1]);
+ bicTableModel.addColumn("-LnL", new Double[rows][1]);
+ bicTableModel.addColumn("BIC", new Double[rows][1]);
+ bicTableModel.addColumn("deltaBIC", new Double[rows][1]);
+ bicTableModel.addColumn("BIC weight", new Double[rows][1]);
+ bicTable.setModel(bicTableModel);
+ bicTable.setCellSelectionEnabled(true);
+ bicTable.setName("bicTable"); // NOI18N
+ RowSorter<TableModel> bicSorter = new TableRowSorter<TableModel>(
+ bicTableModel);
+ bicTable.setRowSorter(bicSorter);
+
+ SelectionListener bicListener = new SelectionListener(bicTable);
+ bicTable.getSelectionModel().addListSelectionListener(bicListener);
+ bicTable.getColumnModel().getSelectionModel()
+ .addListSelectionListener(bicListener);
+ bicScrollPanel.setViewportView(bicTable);
+
+ bicDataPanel.setBorder(javax.swing.BorderFactory
+ .createLineBorder(new java.awt.Color(0, 0, 0)));
+ bicDataPanel.setName("bicDataPanel"); // NOI18N
+
+ java.util.ResourceBundle bundle1 = java.util.ResourceBundle
+ .getBundle("es/uvigo/darwin/xprottest/results/Bundle"); // NOI18N
+ lblBICOverall.setText(bundle1.getString("lbl-overall")); // NOI18N
+ lblBICOverall.setName("lblBICOverall"); // NOI18N
+
+ lblBICOverallAlpha.setText(bundle1.getString("lbl-overall-alpha")); // NOI18N
+ lblBICOverallAlpha.setName("lblBICOverallAlpha"); // NOI18N
+
+ lblBICOverallAlphaInv.setText(bundle1
+ .getString("lbl-overall-alpha-inv")); // NOI18N
+ lblBICOverallAlphaInv.setName("lblBICOverallAlphaInv"); // NOI18N
+
+ lblBICOverallInvAlpha.setText(bundle1
+ .getString("lbl-overall-inv-alpha")); // NOI18N
+ lblBICOverallInvAlpha.setName("lblBICOverallInvAlpha"); // NOI18N
+
+ lblBICOverallInv.setText(bundle1.getString("lbl-overall-inv")); // NOI18N
+ lblBICOverallInv.setName("lblBICOverallInv"); // NOI18N
+
+ displayBICoAlpha
+ .setText(resourceMap.getString("displayBICoAlpha.text")); // NOI18N
+ displayBICoAlpha.setName("displayBICoAlpha"); // NOI18N
+
+ displayBICoAlphaInv.setText(resourceMap
+ .getString("displayBICoAlphaInv.text")); // NOI18N
+ displayBICoAlphaInv.setName("displayBICoAlphaInv"); // NOI18N
+
+ displayBICoInvAlpha.setText(resourceMap
+ .getString("displayBICoInvAlpha.text")); // NOI18N
+ displayBICoInvAlpha.setName("displayBICoInvAlpha"); // NOI18N
+
+ displayBICoInv.setText(resourceMap.getString("displayBICoInv.text")); // NOI18N
+ displayBICoInv.setName("displayBICoInv"); // NOI18N
+
+ lblBICImpInv.setText(resourceMap.getString("lblBICImpInv.text")); // NOI18N
+ lblBICImpInv.setName("lblBICImpInv"); // NOI18N
+
+ lblBICImpAlpha.setText(resourceMap.getString("lblBICImpAlpha.text")); // NOI18N
+ lblBICImpAlpha.setName("lblBICImpAlpha"); // NOI18N
+
+ lblBICImpF.setText(resourceMap.getString("lblBICImpF.text")); // NOI18N
+ lblBICImpF.setName("lblBICImpF"); // NOI18N
+
+ lblBICImpAlphaInv.setText(resourceMap
+ .getString("lblBICImpAlphaInv.text")); // NOI18N
+ lblBICImpAlphaInv.setName("lblBICImpAlphaInv"); // NOI18N
+
+ displayBICImpInv
+ .setText(resourceMap.getString("displayBICImpInv.text")); // NOI18N
+ displayBICImpInv.setName("displayBICImpInv"); // NOI18N
+
+ displayBICImpAlpha.setText(resourceMap
+ .getString("displayBICImpAlpha.text")); // NOI18N
+ displayBICImpAlpha.setName("displayBICImpAlpha"); // NOI18N
+
+ displayBICImpAlphaInv.setText(resourceMap
+ .getString("displayBICImpAlphaInv.text")); // NOI18N
+ displayBICImpAlphaInv.setName("displayBICImpAlphaInv"); // NOI18N
+
+ displayBICImpF.setText(resourceMap.getString("displayBICImpF.text")); // NOI18N
+ displayBICImpF.setName("displayBICImpF"); // NOI18N
+
+ lblBICPI.setText(resourceMap.getString("lblBICPI.text")); // NOI18N
+ lblBICPI.setName("lblBICPI"); // NOI18N
+
+ javax.swing.GroupLayout bicDataPanelLayout = new javax.swing.GroupLayout(
+ bicDataPanel);
+ bicDataPanel.setLayout(bicDataPanelLayout);
+ bicDataPanelLayout
+ .setHorizontalGroup(bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addGap(44,
+ 44,
+ 44)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ lblBICOverallAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICOverallAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICOverallInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICOverallInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addGap(18,
+ 18,
+ 18)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ displayBICoInv)
+ .addComponent(
+ displayBICoInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayBICoAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayBICoAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE))
+ .addGap(40,
+ 40,
+ 40))
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ lblBICOverall,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 366,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ false)
+ .addComponent(
+ lblBICImpAlpha,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICImpInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICImpF,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblBICImpAlphaInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 59,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ displayBICImpInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 83,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayBICImpAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayBICImpAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayBICImpF,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)))
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ lblBICPI,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 237,
+ Short.MAX_VALUE)))
+ .addContainerGap()));
+ bicDataPanelLayout
+ .setVerticalGroup(bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICOverall)
+ .addComponent(lblBICPI))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICOverallAlpha)
+ .addComponent(
+ displayBICoAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICOverallAlphaInv)
+ .addComponent(
+ displayBICoAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICOverallInvAlpha)
+ .addComponent(
+ displayBICoInvAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICOverallInv)
+ .addComponent(
+ displayBICoInv)))
+ .addGroup(
+ bicDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICImpInv)
+ .addComponent(
+ displayBICImpInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICImpAlpha)
+ .addComponent(
+ displayBICImpAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICImpAlphaInv)
+ .addComponent(
+ displayBICImpAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ bicDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblBICImpF)
+ .addComponent(
+ displayBICImpF))))
+ .addContainerGap(
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+
+ javax.swing.GroupLayout bicPanelLayout = new javax.swing.GroupLayout(
+ bicPanel);
+ bicPanel.setLayout(bicPanelLayout);
+ bicPanelLayout
+ .setHorizontalGroup(bicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ bicPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ bicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ bicScrollPanel,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 635,
+ Short.MAX_VALUE)
+ .addComponent(
+ bicDataPanel,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ bicPanelLayout
+ .setVerticalGroup(bicPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ bicPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ bicScrollPanel,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 300, Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ bicDataPanel,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()));
+
+ resultsTabbedPane.addTab(
+ resourceMap.getString("bicPanel.TabConstraints.tabTitle"),
+ bicPanel); // NOI18N
+
+ aiccPanel.setName("aiccPanel"); // NOI18N
+
+ aiccScrollPanel.setName("aiccScrollPanel"); // NOI18N
+
+ aiccTableModel = new javax.swing.table.DefaultTableModel() {
+ public Class getColumnClass(int column) {
+ if (column >= 0 && column <= getColumnCount()) {
+ try {
+ return getValueAt(0, column).getClass();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return Object.class;
+ }
+ } else
+ return Object.class;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+ };
+ aiccTableModel.addColumn("Model", new String[rows][1]);
+ aiccTableModel.addColumn("-LnL", new Double[rows][1]);
+ aiccTableModel.addColumn("AICc", new Double[rows][1]);
+ aiccTableModel.addColumn("deltaAICc", new Double[rows][1]);
+ aiccTableModel.addColumn("AICc weight", new Double[rows][1]);
+ aiccTable.setModel(aiccTableModel);
+ aiccTable.setCellSelectionEnabled(true);
+ aiccTable.setName("aiccTable"); // NOI18N
+ RowSorter<TableModel> aiccSorter = new TableRowSorter<TableModel>(
+ aiccTableModel);
+ aiccTable.setRowSorter(aiccSorter);
+
+ SelectionListener aiccListener = new SelectionListener(aiccTable);
+ aiccTable.getSelectionModel().addListSelectionListener(aiccListener);
+ aiccTable.getColumnModel().getSelectionModel()
+ .addListSelectionListener(aiccListener);
+ aiccScrollPanel.setViewportView(aiccTable);
+
+ aiccDataPanel.setBorder(javax.swing.BorderFactory
+ .createLineBorder(new java.awt.Color(0, 0, 0)));
+ aiccDataPanel.setName("aiccDataPanel"); // NOI18N
+
+ lblAICcOverall.setText(bundle1.getString("lbl-overall_1")); // NOI18N
+ lblAICcOverall.setName("lblAICcOverall"); // NOI18N
+
+ lblAICcOverallAlpha.setText(bundle1.getString("lbl-overall-alpha_1")); // NOI18N
+ lblAICcOverallAlpha.setName("lblAICcOverallAlpha"); // NOI18N
+
+ lblAICcOverallAlphaInv.setText(bundle1
+ .getString("lbl-overall-alpha-inv_1")); // NOI18N
+ lblAICcOverallAlphaInv.setName("lblAICcOverallAlphaInv"); // NOI18N
+
+ lblAICcOverallInvAlpha.setText(bundle1
+ .getString("lbl-overall-inv-alpha_1")); // NOI18N
+ lblAICcOverallInvAlpha.setName("lblAICcOverallInvAlpha"); // NOI18N
+
+ lblAICcOverallInv.setText(bundle1.getString("lbl-overall-inv_1")); // NOI18N
+ lblAICcOverallInv.setName("lblAICcOverallInv"); // NOI18N
+
+ displayAICcoAlpha.setText(resourceMap
+ .getString("displayAICcoAlpha.text")); // NOI18N
+ displayAICcoAlpha.setName("displayAICcoAlpha"); // NOI18N
+
+ displayAICcoAlphaInv.setText(resourceMap
+ .getString("displayAICcoAlphaInv.text")); // NOI18N
+ displayAICcoAlphaInv.setName("displayAICcoAlphaInv"); // NOI18N
+
+ displayAICcoInvAlpha.setText(resourceMap
+ .getString("displayAICcoInvAlpha.text")); // NOI18N
+ displayAICcoInvAlpha.setName("displayAICcoInvAlpha"); // NOI18N
+
+ displayAICcoInv.setText(resourceMap.getString("displayAICcoInv.text")); // NOI18N
+ displayAICcoInv.setName("displayAICcoInv"); // NOI18N
+
+ lblAICcPI.setText(resourceMap.getString("lblAICcPI.text")); // NOI18N
+ lblAICcPI.setName("lblAICcPI"); // NOI18N
+
+ lblAICcImpInv.setText(resourceMap.getString("lblAICcImpInv.text")); // NOI18N
+ lblAICcImpInv.setName("lblAICcImpInv"); // NOI18N
+
+ lblAICcImpAlpha.setText(resourceMap.getString("lblAICcImpAlpha.text")); // NOI18N
+ lblAICcImpAlpha.setName("lblAICcImpAlpha"); // NOI18N
+
+ lblAICcImpF.setText(resourceMap.getString("lblAICcImpF.text")); // NOI18N
+ lblAICcImpF.setName("lblAICcImpF"); // NOI18N
+
+ lblAICcImpAlphaInv.setText(resourceMap
+ .getString("lblAICcImpAlphaInv.text")); // NOI18N
+ lblAICcImpAlphaInv.setName("lblAICcImpAlphaInv"); // NOI18N
+
+ displayAICcImpInv.setText(resourceMap
+ .getString("displayAICcImpInv.text")); // NOI18N
+ displayAICcImpInv.setName("displayAICcImpInv"); // NOI18N
+
+ displayAICcImpAlpha.setText(resourceMap
+ .getString("displayAICcImpAlpha.text")); // NOI18N
+ displayAICcImpAlpha.setName("displayAICcImpAlpha"); // NOI18N
+
+ displayAICcImpAlphaInv.setText(resourceMap
+ .getString("displayAICcImpAlphaInv.text")); // NOI18N
+ displayAICcImpAlphaInv.setName("displayAICcImpAlphaInv"); // NOI18N
+
+ displayAICcImpF.setText(resourceMap.getString("displayAICcImpF.text")); // NOI18N
+ displayAICcImpF.setName("displayAICcImpF"); // NOI18N
+
+ javax.swing.GroupLayout aiccDataPanelLayout = new javax.swing.GroupLayout(
+ aiccDataPanel);
+ aiccDataPanel.setLayout(aiccDataPanelLayout);
+ aiccDataPanelLayout
+ .setHorizontalGroup(aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addGap(44,
+ 44,
+ 44)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ lblAICcOverallAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcOverallAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcOverallInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcOverallInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addGap(18,
+ 18,
+ 18)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ displayAICcoInv)
+ .addComponent(
+ displayAICcoInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICcoAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICcoAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE))
+ .addGap(40,
+ 40,
+ 40))
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ lblAICcOverall,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 366,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ false)
+ .addComponent(
+ lblAICcImpAlpha,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcImpInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcImpF,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblAICcImpAlphaInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 59,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ displayAICcImpInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 83,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICcImpAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICcImpAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayAICcImpF,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)))
+ .addComponent(
+ lblAICcPI,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 237,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ aiccDataPanelLayout
+ .setVerticalGroup(aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcOverall)
+ .addComponent(lblAICcPI))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcOverallAlpha)
+ .addComponent(
+ displayAICcoAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcOverallAlphaInv)
+ .addComponent(
+ displayAICcoAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcOverallInvAlpha)
+ .addComponent(
+ displayAICcoInvAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcOverallInv)
+ .addComponent(
+ displayAICcoInv)))
+ .addGroup(
+ aiccDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcImpInv)
+ .addComponent(
+ displayAICcImpInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcImpAlpha)
+ .addComponent(
+ displayAICcImpAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcImpAlphaInv)
+ .addComponent(
+ displayAICcImpAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ aiccDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblAICcImpF)
+ .addComponent(
+ displayAICcImpF))))
+ .addContainerGap(
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+
+ javax.swing.GroupLayout aiccPanelLayout = new javax.swing.GroupLayout(
+ aiccPanel);
+ aiccPanel.setLayout(aiccPanelLayout);
+ aiccPanelLayout
+ .setHorizontalGroup(aiccPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ aiccPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ aiccPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(
+ aiccScrollPanel,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 635,
+ Short.MAX_VALUE)
+ .addComponent(
+ aiccDataPanel,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ aiccPanelLayout
+ .setVerticalGroup(aiccPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ aiccPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ aiccScrollPanel,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 300, Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ aiccDataPanel,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()));
+
+ resultsTabbedPane.addTab(
+ resourceMap.getString("aiccPanel.TabConstraints.tabTitle"),
+ aiccPanel); // NOI18N
+
+ dtPanel.setName("dtPanel"); // NOI18N
+
+ dtScrollPanel.setName("dtScrollPanel"); // NOI18N
+
+ dtTableModel = new javax.swing.table.DefaultTableModel() {
+ public Class getColumnClass(int column) {
+ if (column >= 0 && column <= getColumnCount()) {
+ try {
+ return getValueAt(0, column).getClass();
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return Object.class;
+ }
+ } else
+ return Object.class;
+ }
+
+ public boolean isCellEditable(int row, int col) {
+ return false;
+ }
+ };
+ dtTableModel.addColumn("Model", new String[rows][1]);
+ dtTableModel.addColumn("-LnL", new Double[rows][1]);
+ dtTableModel.addColumn("DT", new Double[rows][1]);
+ dtTableModel.addColumn("deltaDT", new Double[rows][1]);
+ dtTableModel.addColumn("DT weight", new Double[rows][1]);
+ dtTable.setModel(dtTableModel);
+ dtTable.setCellSelectionEnabled(true);
+ dtTable.setName("dtTable"); // NOI18N
+ RowSorter<TableModel> dtSorter = new TableRowSorter<TableModel>(
+ dtTableModel);
+ dtTable.setRowSorter(dtSorter);
+
+ SelectionListener dtListener = new SelectionListener(dtTable);
+ dtTable.getSelectionModel().addListSelectionListener(dtListener);
+ dtTable.getColumnModel().getSelectionModel()
+ .addListSelectionListener(dtListener);
+ dtScrollPanel.setViewportView(dtTable);
+
+ dtDataPanel.setBorder(javax.swing.BorderFactory
+ .createLineBorder(new java.awt.Color(0, 0, 0)));
+ dtDataPanel.setName("dtDataPanel"); // NOI18N
+
+ lblDTOverall.setText(bundle1.getString("lbl-overall_2")); // NOI18N
+ lblDTOverall.setName("lblDTOverall"); // NOI18N
+
+ lblDTOverallAlpha.setText(bundle1.getString("lbl-overall-alpha_2")); // NOI18N
+ lblDTOverallAlpha.setName("lblDTOverallAlpha"); // NOI18N
+
+ lblDTOverallAlphaInv.setText(bundle1
+ .getString("lbl-overall-alpha-inv_2")); // NOI18N
+ lblDTOverallAlphaInv.setName("lblDTOverallAlphaInv"); // NOI18N
+
+ lblDTOverallInvAlpha.setText(bundle1
+ .getString("lbl-overall-inv-alpha_2")); // NOI18N
+ lblDTOverallInvAlpha.setName("lblDTOverallInvAlpha"); // NOI18N
+
+ lblDTOverallInv.setText(bundle1.getString("lbl-overall-inv_2")); // NOI18N
+ lblDTOverallInv.setName("lblDTOverallInv"); // NOI18N
+
+ displayDToAlpha.setText(resourceMap.getString("displayDToAlpha.text")); // NOI18N
+ displayDToAlpha.setName("displayDToAlpha"); // NOI18N
+
+ displayDToAlphaInv.setText(resourceMap
+ .getString("displayDToAlphaInv.text")); // NOI18N
+ displayDToAlphaInv.setName("displayDToAlphaInv"); // NOI18N
+
+ displayDToInvAlpha.setText(resourceMap
+ .getString("displayDToInvAlpha.text")); // NOI18N
+ displayDToInvAlpha.setName("displayDToInvAlpha"); // NOI18N
+
+ displayDToInv.setText(resourceMap.getString("displayDToInv.text")); // NOI18N
+ displayDToInv.setName("displayDToInv"); // NOI18N
+
+ lblDTPI.setText(resourceMap.getString("lblDTPI.text")); // NOI18N
+ lblDTPI.setName("lblDTPI"); // NOI18N
+
+ lblDTImpInv.setText(resourceMap.getString("lblDTImpInv.text")); // NOI18N
+ lblDTImpInv.setName("lblDTImpInv"); // NOI18N
+
+ lblDTImpAlpha.setText(resourceMap.getString("lblDTImpAlpha.text")); // NOI18N
+ lblDTImpAlpha.setName("lblDTImpAlpha"); // NOI18N
+
+ lblDTImpF.setText(resourceMap.getString("lblDTImpF.text")); // NOI18N
+ lblDTImpF.setName("lblDTImpF"); // NOI18N
+
+ lblDTImpAlphaInv
+ .setText(resourceMap.getString("lblDTImpAlphaInv.text")); // NOI18N
+ lblDTImpAlphaInv.setName("lblDTImpAlphaInv"); // NOI18N
+
+ displayDTImpInv.setText(resourceMap.getString("displayDTImpInv.text")); // NOI18N
+ displayDTImpInv.setName("displayDTImpInv"); // NOI18N
+
+ displayDTImpAlpha.setText(resourceMap
+ .getString("displayDTImpAlpha.text")); // NOI18N
+ displayDTImpAlpha.setName("displayDTImpAlpha"); // NOI18N
+
+ displayDTImpAlphaInv.setText(resourceMap
+ .getString("displayDTImpAlphaInv.text")); // NOI18N
+ displayDTImpAlphaInv.setName("displayDTImpAlphaInv"); // NOI18N
+
+ displayDTImpF.setText(resourceMap.getString("displayDTImpF.text")); // NOI18N
+ displayDTImpF.setName("displayDTImpF"); // NOI18N
+
+ javax.swing.GroupLayout dtDataPanelLayout = new javax.swing.GroupLayout(
+ dtDataPanel);
+ dtDataPanel.setLayout(dtDataPanelLayout);
+ dtDataPanelLayout
+ .setHorizontalGroup(dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addGap(44,
+ 44,
+ 44)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ lblDTOverallAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTOverallAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTOverallInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTOverallInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addGap(18,
+ 18,
+ 18)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ displayDToInv)
+ .addComponent(
+ displayDToInvAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayDToAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayDToAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 223,
+ Short.MAX_VALUE))
+ .addGap(40,
+ 40,
+ 40))
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ lblDTOverall,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 366,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ false)
+ .addComponent(
+ lblDTImpAlpha,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTImpInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTImpF,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ lblDTImpAlphaInv,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 59,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ false)
+ .addComponent(
+ displayDTImpInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 83,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayDTImpAlpha,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayDTImpAlphaInv,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)
+ .addComponent(
+ displayDTImpF,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)))
+ .addComponent(
+ lblDTPI,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 237,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ dtDataPanelLayout
+ .setVerticalGroup(dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTOverall)
+ .addComponent(lblDTPI))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTOverallAlpha)
+ .addComponent(
+ displayDToAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTOverallAlphaInv)
+ .addComponent(
+ displayDToAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTOverallInvAlpha)
+ .addComponent(
+ displayDToInvAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTOverallInv)
+ .addComponent(
+ displayDToInv)))
+ .addGroup(
+ dtDataPanelLayout
+ .createSequentialGroup()
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTImpInv)
+ .addComponent(
+ displayDTImpInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTImpAlpha)
+ .addComponent(
+ displayDTImpAlpha))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTImpAlphaInv)
+ .addComponent(
+ displayDTImpAlphaInv))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ dtDataPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblDTImpF)
+ .addComponent(
+ displayDTImpF))))
+ .addContainerGap(
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE)));
+
+ javax.swing.GroupLayout dtPanelLayout = new javax.swing.GroupLayout(
+ dtPanel);
+ dtPanel.setLayout(dtPanelLayout);
+ dtPanelLayout
+ .setHorizontalGroup(dtPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ dtPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ dtPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING)
+ .addComponent(
+ dtScrollPanel,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 635,
+ Short.MAX_VALUE)
+ .addComponent(
+ dtDataPanel,
+ javax.swing.GroupLayout.Alignment.LEADING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ Short.MAX_VALUE))
+ .addContainerGap()));
+ dtPanelLayout
+ .setVerticalGroup(dtPanelLayout
+ .createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ dtPanelLayout
+ .createSequentialGroup()
+ .addContainerGap()
+ .addComponent(
+ dtScrollPanel,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 300, Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ dtDataPanel,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()));
+
+ resultsTabbedPane.addTab(
+ resourceMap.getString("dtPanel.TabConstraints.tabTitle"),
+ dtPanel); // NOI18N
+
+ javax.swing.ActionMap actionMap = org.jdesktop.application.Application
+ .getInstance().getContext()
+ .getActionMap(ResultsView.class, this);
+
+ sliderConfidenceInterval.setValue(100);
+ sliderConfidenceInterval.setMinimum(1);
+ sliderConfidenceInterval.setName("sliderConfidenceInterval"); // NOI18N
+ sliderConfidenceInterval
+ .addMouseListener(new java.awt.event.MouseAdapter() {
+ public void mouseReleased(java.awt.event.MouseEvent evt) {
+ sliderConfidenceIntervalMouseReleased(evt);
+ }
+ });
+ sliderConfidenceInterval
+ .addChangeListener(new javax.swing.event.ChangeListener() {
+ public void stateChanged(javax.swing.event.ChangeEvent evt) {
+ sliderConfidenceIntervalStateChanged(evt);
+ }
+ });
+
+ lblConfInt.setText(resourceMap.getString("lblConfInt.text")); // NOI18N
+ lblConfInt.setName("lblConfInt"); // NOI18N
+
+ jScrollPane1.setName("jScrollPane1"); // NOI18N
+
+ lblCommandLine.setBackground(resourceMap
+ .getColor("lblCommandLine.background")); // NOI18N
+ lblCommandLine.setColumns(20);
+ lblCommandLine.setEditable(false);
+ lblCommandLine.setRows(1);
+ lblCommandLine.setBorder(null);
+ lblCommandLine.setName("lblCommandLine"); // NOI18N
+ jScrollPane1.setViewportView(lblCommandLine);
+
+ lblComandLineLabel.setText(resourceMap
+ .getString("lblComandLineLabel.text")); // NOI18N
+ lblComandLineLabel.setName("lblComandLineLabel"); // NOI18N
+
+ lblSelectedModelLabel.setText(resourceMap
+ .getString("lblSelectedModelLabel.text")); // NOI18N
+ lblSelectedModelLabel.setName("lblSelectedModelLabel"); // NOI18N
+
+ lblSelectedModel
+ .setText(resourceMap.getString("lblSelectedModel.text")); // NOI18N
+ lblSelectedModel.setName("lblSelectedModel"); // NOI18N
+
+ lblNotComplete.setBackground(resourceMap
+ .getColor("lblNotComplete.background")); // NOI18N
+ lblNotComplete.setFont(resourceMap.getFont("lblNotComplete.font")); // NOI18N
+ lblNotComplete.setForeground(resourceMap
+ .getColor("lblNotComplete.foreground")); // NOI18N
+ lblNotComplete
+ .setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
+ java.util.ResourceBundle bundle2 = java.util.ResourceBundle
+ .getBundle("es/uvigo/darwin/xprottest/resources/XProtTestView"); // NOI18N
+ lblNotComplete.setText(bundle2.getString("models-not-complete")); // NOI18N
+ lblNotComplete.setName("lblNotComplete"); // NOI18N
+ lblNotComplete.setOpaque(true);
+
+ lblConfidence.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
+ lblConfidence.setText(resourceMap.getString("lblConfidence.text")); // NOI18N
+ lblConfidence.setName("lblConfidence"); // NOI18N
+
+ btnExport.setAction(actionMap.get("exportData")); // NOI18N
+ btnExport.setName("btnExport"); // NOI18N
+
+ javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
+ getContentPane());
+ getContentPane().setLayout(layout);
+ layout.setHorizontalGroup(layout
+ .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ resultsTabbedPane,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 671, Short.MAX_VALUE)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ lblConfInt))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.TRAILING)
+ .addGroup(
+ javax.swing.GroupLayout.Alignment.LEADING,
+ layout.createSequentialGroup()
+ .addComponent(
+ lblConfidence,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 32,
+ javax.swing.GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ sliderConfidenceInterval,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 489,
+ Short.MAX_VALUE))))
+
+ .addComponent(
+ lblNotComplete,
+ javax.swing.GroupLayout.Alignment.TRAILING,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 671, Short.MAX_VALUE)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addComponent(
+ lblComandLineLabel)
+ .addComponent(
+ lblSelectedModelLabel))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addComponent(
+ lblSelectedModel,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 386,
+ Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ btnExport))
+ .addComponent(
+ jScrollPane1,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 557,
+ Short.MAX_VALUE))))
+ .addContainerGap()));
+ layout.setVerticalGroup(layout
+ .createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addContainerGap()
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblConfInt)
+ .addComponent(
+ lblConfidence))
+ .addComponent(
+ sliderConfidenceInterval,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ javax.swing.GroupLayout.PREFERRED_SIZE))
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(lblNotComplete)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(resultsTabbedPane,
+ javax.swing.GroupLayout.DEFAULT_SIZE,
+ 496, Short.MAX_VALUE)
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.BASELINE)
+ .addComponent(
+ lblSelectedModelLabel)
+ .addComponent(lblSelectedModel)
+ .addComponent(btnExport))
+ .addGroup(
+ layout.createParallelGroup(
+ javax.swing.GroupLayout.Alignment.LEADING)
+ .addGroup(
+ layout.createSequentialGroup()
+ .addGap(11, 11,
+ 11)
+ .addComponent(
+ lblComandLineLabel))
+ .addGroup(
+ layout.createSequentialGroup()
+ .addPreferredGap(
+ javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+ .addComponent(
+ jScrollPane1,
+ javax.swing.GroupLayout.PREFERRED_SIZE,
+ 42,
+ javax.swing.GroupLayout.PREFERRED_SIZE)))
+ .addContainerGap()));
+
+ pack();
+ }// </editor-fold>//GEN-END:initComponents
+
+ private void sliderConfidenceIntervalStateChanged(
+ javax.swing.event.ChangeEvent evt) {// GEN-FIRST:event_sliderConfidenceIntervalStateChanged
+ double confidenceInterval = Double.parseDouble(sliderConfidenceInterval
+ .getValue() + "") / 100;
+ lblConfidence.setText(String.valueOf(confidenceInterval));
+ }// GEN-LAST:event_sliderConfidenceIntervalStateChanged
+
+ private void sliderConfidenceIntervalMouseReleased(
+ java.awt.event.MouseEvent evt) {// GEN-FIRST:event_sliderConfidenceIntervalMouseReleased
+ double confidenceInterval = Double.parseDouble(sliderConfidenceInterval
+ .getValue() + "") / 100;
+ loadCache(confidenceInterval);
+ fillInResults();
+ }// GEN-LAST:event_sliderConfidenceIntervalMouseReleased
+ // Variables declaration - do not modify//GEN-BEGIN:variables
+
+ private javax.swing.JPanel aicDataPanel;
+ private javax.swing.JPanel aicPanel;
+ private javax.swing.JScrollPane aicScrollPanel;
+ private javax.swing.JTable aicTable;
+ private javax.swing.JPanel aiccDataPanel;
+ private javax.swing.JPanel aiccPanel;
+ private javax.swing.JScrollPane aiccScrollPanel;
+ private javax.swing.JTable aiccTable;
+ private javax.swing.JPanel bicDataPanel;
+ private javax.swing.JPanel bicPanel;
+ private javax.swing.JScrollPane bicScrollPanel;
+ private javax.swing.JTable bicTable;
+ private javax.swing.JButton btnExport;
+ private javax.swing.JLabel displayAICImpAlpha;
+ private javax.swing.JLabel displayAICImpAlphaInv;
+ private javax.swing.JLabel displayAICImpF;
+ private javax.swing.JLabel displayAICImpInv;
+ private javax.swing.JLabel displayAICcImpAlpha;
+ private javax.swing.JLabel displayAICcImpAlphaInv;
+ private javax.swing.JLabel displayAICcImpF;
+ private javax.swing.JLabel displayAICcImpInv;
+ private javax.swing.JLabel displayAICcoAlpha;
+ private javax.swing.JLabel displayAICcoAlphaInv;
+ private javax.swing.JLabel displayAICcoInv;
+ private javax.swing.JLabel displayAICcoInvAlpha;
+ private javax.swing.JLabel displayAICoAlpha;
+ private javax.swing.JLabel displayAICoAlphaInv;
+ private javax.swing.JLabel displayAICoInv;
+ private javax.swing.JLabel displayAICoInvAlpha;
+ private javax.swing.JLabel displayBICImpAlpha;
+ private javax.swing.JLabel displayBICImpAlphaInv;
+ private javax.swing.JLabel displayBICImpF;
+ private javax.swing.JLabel displayBICImpInv;
+ private javax.swing.JLabel displayBICoAlpha;
+ private javax.swing.JLabel displayBICoAlphaInv;
+ private javax.swing.JLabel displayBICoInv;
+ private javax.swing.JLabel displayBICoInvAlpha;
+ private javax.swing.JLabel displayDTImpAlpha;
+ private javax.swing.JLabel displayDTImpAlphaInv;
+ private javax.swing.JLabel displayDTImpF;
+ private javax.swing.JLabel displayDTImpInv;
+ private javax.swing.JLabel displayDToAlpha;
+ private javax.swing.JLabel displayDToAlphaInv;
+ private javax.swing.JLabel displayDToInv;
+ private javax.swing.JLabel displayDToInvAlpha;
+ private javax.swing.JPanel dtDataPanel;
+ private javax.swing.JPanel dtPanel;
+ private javax.swing.JScrollPane dtScrollPanel;
+ private javax.swing.JTable dtTable;
+ private javax.swing.JScrollPane jScrollPane1;
+ private javax.swing.JLabel lblAICImpAlpha;
+ private javax.swing.JLabel lblAICImpAlphaInv;
+ private javax.swing.JLabel lblAICImpF;
+ private javax.swing.JLabel lblAICImpInv;
+ private javax.swing.JLabel lblAICOverall;
+ private javax.swing.JLabel lblAICOverallAlpha;
+ private javax.swing.JLabel lblAICOverallAlphaInv;
+ private javax.swing.JLabel lblAICOverallInv;
+ private javax.swing.JLabel lblAICOverallInvAlpha;
+ private javax.swing.JLabel lblAICPI;
+ private javax.swing.JLabel lblAICcImpAlpha;
+ private javax.swing.JLabel lblAICcImpAlphaInv;
+ private javax.swing.JLabel lblAICcImpF;
+ private javax.swing.JLabel lblAICcImpInv;
+ private javax.swing.JLabel lblAICcOverall;
+ private javax.swing.JLabel lblAICcOverallAlpha;
+ private javax.swing.JLabel lblAICcOverallAlphaInv;
+ private javax.swing.JLabel lblAICcOverallInv;
+ private javax.swing.JLabel lblAICcOverallInvAlpha;
+ private javax.swing.JLabel lblAICcPI;
+ private javax.swing.JLabel lblBICImpAlpha;
+ private javax.swing.JLabel lblBICImpAlphaInv;
+ private javax.swing.JLabel lblBICImpF;
+ private javax.swing.JLabel lblBICImpInv;
+ private javax.swing.JLabel lblBICOverall;
+ private javax.swing.JLabel lblBICOverallAlpha;
+ private javax.swing.JLabel lblBICOverallAlphaInv;
+ private javax.swing.JLabel lblBICOverallInv;
+ private javax.swing.JLabel lblBICOverallInvAlpha;
+ private javax.swing.JLabel lblBICPI;
+ private javax.swing.JLabel lblComandLineLabel;
+ private javax.swing.JTextArea lblCommandLine;
+ private javax.swing.JLabel lblConfInt;
+ private javax.swing.JLabel lblConfidence;
+ private javax.swing.JLabel lblDTImpAlpha;
+ private javax.swing.JLabel lblDTImpAlphaInv;
+ private javax.swing.JLabel lblDTImpF;
+ private javax.swing.JLabel lblDTImpInv;
+ private javax.swing.JLabel lblDTOverall;
+ private javax.swing.JLabel lblDTOverallAlpha;
+ private javax.swing.JLabel lblDTOverallAlphaInv;
+ private javax.swing.JLabel lblDTOverallInv;
+ private javax.swing.JLabel lblDTOverallInvAlpha;
+ private javax.swing.JLabel lblDTPI;
+ private javax.swing.JLabel lblNotComplete;
+ private javax.swing.JLabel lblSelectedModel;
+ private javax.swing.JLabel lblSelectedModelLabel;
+ private javax.swing.JTabbedPane resultsTabbedPane;
+ private javax.swing.JSlider sliderConfidenceInterval;
+
+ // End of variables declaration//GEN-END:variables
+
+ private void fillInResults() {
+
+ Collection<SelectionModel> aicIt = aicResults.getConfidenceModels();
+ Collection<SelectionModel> bicIt = bicResults.getConfidenceModels();
+ Collection<SelectionModel> aiccIt = aiccResults.getConfidenceModels();
+ Collection<SelectionModel> dtIt = dtResults.getConfidenceModels();
+
+ aicTableModel.setRowCount(aicIt.size());
+ fillTable(aicIt, aicTable);
+
+ displayAICoAlpha.setText(getDisplayValue(aicResults.getOverallAlpha(),
+ PARAMETER_G, aicResults.existGammaModels()));
+ displayAICoAlphaInv.setText(getDisplayValue(
+ aicResults.getOverallAlphaInv(), PARAMETER_IG,
+ aicResults.existGammaInvModels()));
+ displayAICoInvAlpha.setText(getDisplayValue(
+ aicResults.getOverallInvAlpha(), PARAMETER_IG,
+ aicResults.existGammaInvModels()));
+ displayAICoInv.setText(getDisplayValue(aicResults.getOverallInv(),
+ PARAMETER_I, aicResults.existInvModels()));
+ displayAICImpAlpha.setText(getDisplayValue(
+ aicResults.getAlphaImportance(), PARAMETER_G,
+ aicResults.existGammaModels()));
+ displayAICImpInv.setText(getDisplayValue(aicResults.getInvImportance(),
+ PARAMETER_I, aicResults.existInvModels()));
+ displayAICImpAlphaInv.setText(getDisplayValue(
+ aicResults.getAlphaInvImportance(), PARAMETER_IG,
+ aicResults.existGammaInvModels()));
+ displayAICImpF.setText(getDisplayValue(aicResults.getFImportance(),
+ PARAMETER_F, aicResults.existFModels()));
+
+ bicTableModel.setRowCount(bicIt.size());
+ fillTable(bicIt, bicTable);
+
+ displayBICoAlpha.setText(getDisplayValue(bicResults.getOverallAlpha(),
+ PARAMETER_G, bicResults.existGammaModels()));
+ displayBICoAlphaInv.setText(getDisplayValue(
+ bicResults.getOverallAlphaInv(), PARAMETER_IG,
+ bicResults.existGammaInvModels()));
+ displayBICoInvAlpha.setText(getDisplayValue(
+ bicResults.getOverallInvAlpha(), PARAMETER_IG,
+ bicResults.existGammaInvModels()));
+ displayBICoInv.setText(getDisplayValue(bicResults.getOverallInv(),
+ PARAMETER_I, bicResults.existInvModels()));
+ displayBICImpAlpha.setText(getDisplayValue(
+ bicResults.getAlphaImportance(), PARAMETER_G,
+ bicResults.existGammaModels()));
+ displayBICImpInv.setText(getDisplayValue(bicResults.getInvImportance(),
+ PARAMETER_I, bicResults.existInvModels()));
+ displayBICImpAlphaInv.setText(getDisplayValue(
+ bicResults.getAlphaInvImportance(), PARAMETER_IG,
+ bicResults.existGammaInvModels()));
+ displayBICImpF.setText(getDisplayValue(bicResults.getFImportance(),
+ PARAMETER_F, bicResults.existFModels()));
+
+ aiccTableModel.setRowCount(aiccIt.size());
+ fillTable(aiccIt, aiccTable);
+
+ displayAICcoAlpha.setText(getDisplayValue(
+ aiccResults.getOverallAlpha(), PARAMETER_G,
+ aiccResults.existGammaModels()));
+ displayAICcoAlphaInv.setText(getDisplayValue(
+ aiccResults.getOverallAlphaInv(), PARAMETER_IG,
+ aiccResults.existGammaInvModels()));
+ displayAICcoInvAlpha.setText(getDisplayValue(
+ aiccResults.getOverallInvAlpha(), PARAMETER_IG,
+ aiccResults.existGammaInvModels()));
+ displayAICcoInv.setText(getDisplayValue(aiccResults.getOverallInv(),
+ PARAMETER_I, aiccResults.existInvModels()));
+ displayAICcImpAlpha.setText(getDisplayValue(
+ aiccResults.getAlphaImportance(), PARAMETER_G,
+ aiccResults.existGammaModels()));
+ displayAICcImpInv.setText(getDisplayValue(
+ aiccResults.getInvImportance(), PARAMETER_I,
+ aiccResults.existInvModels()));
+ displayAICcImpAlphaInv.setText(getDisplayValue(
+ aiccResults.getAlphaInvImportance(), PARAMETER_IG,
+ aiccResults.existGammaInvModels()));
+ displayAICcImpF.setText(getDisplayValue(aiccResults.getFImportance(),
+ PARAMETER_F, aiccResults.existFModels()));
+
+ dtTableModel.setRowCount(dtIt.size());
+ fillTable(dtIt, dtTable);
+
+ displayDToAlpha.setText(getDisplayValue(dtResults.getOverallAlpha(),
+ PARAMETER_G, dtResults.existGammaModels()));
+ displayDToAlphaInv.setText(getDisplayValue(
+ dtResults.getOverallAlphaInv(), PARAMETER_IG,
+ dtResults.existGammaInvModels()));
+ displayDToInvAlpha.setText(getDisplayValue(
+ dtResults.getOverallInvAlpha(), PARAMETER_IG,
+ dtResults.existGammaInvModels()));
+ displayDToInv.setText(getDisplayValue(dtResults.getOverallInv(),
+ PARAMETER_I, dtResults.existInvModels()));
+ displayDTImpAlpha.setText(getDisplayValue(
+ dtResults.getAlphaImportance(), PARAMETER_G,
+ dtResults.existGammaModels()));
+ displayDTImpInv.setText(getDisplayValue(dtResults.getInvImportance(),
+ PARAMETER_I, dtResults.existInvModels()));
+ displayDTImpAlphaInv.setText(getDisplayValue(
+ dtResults.getAlphaInvImportance(), PARAMETER_IG,
+ dtResults.existGammaInvModels()));
+ displayDTImpF.setText(getDisplayValue(dtResults.getFImportance(),
+ PARAMETER_F, dtResults.existFModels()));
+ }
+
+ private void fillTable(Collection<SelectionModel> iterator, JTable table) {
+ int row = 0;
+ for (SelectionModel model : iterator) {
+ table.setValueAt(model.getModel().getModelName(), row, 0);
+ table.setValueAt(model.getModel().getLk(), row, 1);
+ try {
+ table.setValueAt(
+ new Double(ProtTestFormattedOutput.getDecimalString(
+ model.getValue(), CRITERION_PRECISSION)), row,
+ 2);
+ table.setValueAt(
+ new Double(ProtTestFormattedOutput.getDecimalString(
+ model.getDeltaValue(), CRITERION_PRECISSION)),
+ row, 3);
+ table.setValueAt(
+ new Double(ProtTestFormattedOutput.getDecimalString(
+ model.getWeightValue(), CRITERION_PRECISSION)),
+ row, 4);
+ } catch (NumberFormatException e) {
+ table.setValueAt(Double.NaN, row, 2);
+ table.setValueAt(Double.NaN, row, 3);
+ table.setValueAt(Double.NaN, row, 4);
+ }
+ row++;
+ }
+ }
+
+ private void showCommandLine(String modelName) {
+ for (Model model : models) {
+ if (model.getModelName().equals(modelName)) {
+ lblSelectedModel.setText(modelName);
+ StringBuilder command = new StringBuilder();
+ for (int i = 1; i < model.getCommandLine().length; i++) {
+ command.append(model.getCommandLine()[i]).append(" ");
+ }
+ lblCommandLine.setText(command.toString());
+ break;
+ }
+ }
+ }
+
+ class SelectionListener implements ListSelectionListener {
+
+ JTable table;
+
+ // It is necessary to keep the table since it is not possible
+ // to determine the table from the event's source
+ SelectionListener(JTable table) {
+ this.table = table;
+ }
+
+ public void valueChanged(ListSelectionEvent e) {
+ // If cell selection is enabled, both row and column change events
+ // are fired
+ int first = 0, last = 0;
+ if (e.getSource() == table.getSelectionModel()
+ && table.getRowSelectionAllowed()) {
+ // Column selection changed
+ first = e.getFirstIndex();
+ last = e.getLastIndex();
+ } else if (e.getSource() == table.getColumnModel()
+ .getSelectionModel() && table.getColumnSelectionAllowed()) {
+ // Row selection changed
+ first = e.getFirstIndex();
+ last = e.getLastIndex();
+ }
+
+ if (e.getValueIsAdjusting()) {
+ // The mouse button has not yet been released
+ } else {
+ try {
+ showCommandLine(table.getValueAt(table.getSelectedRow(), 0)
+ .toString());
+ } catch (IndexOutOfBoundsException ex) {
+ // Clear
+ lblCommandLine.setText("");
+ lblSelectedModel.setText("");
+ }
+ }
+ }
+ }
+
+ // private String getDisplayValue(double value, String parameter) {
+ // String toDisplay;
+ // boolean existModels = false;
+ // if (parameter.equals(PARAMETER_I)) {
+ // existModels = existInvModels;
+ // } else if (parameter.equals(PARAMETER_G)) {
+ // existModels = existGammaModels;
+ // } else if (parameter.equals(PARAMETER_IG)) {
+ // existModels = existGammaInvModels;
+ // } else if (parameter.equals(PARAMETER_F)) {
+ // existModels = existFModels;
+ // }
+ //
+ // if (existModels) {
+ // toDisplay = ProtTestFormattedOutput.getDecimalString(value,
+ // IMPORTANCE_PRECISSION);
+ // } else {
+ // toDisplay = "No " + parameter + " models";
+ // }
+ // return toDisplay;
+ // }
+
+ @Action
+ public void exportData() {
+ InformationCriterion ic = null;
+ switch (resultsTabbedPane.getSelectedIndex()) {
+ case AIC_TAB:
+ ic = aicResults.getInformationCriterion();
+ break;
+ case BIC_TAB:
+ ic = bicResults.getInformationCriterion();
+ break;
+ case AICC_TAB:
+ ic = aiccResults.getInformationCriterion();
+ break;
+ case DT_TAB:
+ ic = dtResults.getInformationCriterion();
+ break;
+ }
+ if (ic != null) {
+ mainFrame.enableHandler();
+ ProtTestPrinter
+ .printSelectionHeader(CRITERION_NAMES[resultsTabbedPane
+ .getSelectedIndex()]);
+ mainFrame.getFacade().printModelsSorted(ic);
+ mainFrame.disableHandler();
+ }
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/results/resources/ErrorLogView.properties b/src/main/java/es/uvigo/darwin/xprottest/results/resources/ErrorLogView.properties
new file mode 100755
index 0000000..234ec39
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/results/resources/ErrorLogView.properties
@@ -0,0 +1,6 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+#NOI18N
+errorTextArea.font=Dialog 12 12 Plain
+Form.title=Error Log
diff --git a/src/main/java/es/uvigo/darwin/xprottest/results/resources/ResultsView.properties b/src/main/java/es/uvigo/darwin/xprottest/results/resources/ResultsView.properties
new file mode 100755
index 0000000..2977391
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/results/resources/ResultsView.properties
@@ -0,0 +1,78 @@
+aiccPanel.TabConstraints.tabTitle=AICc
+aiccScrollPanel.TabConstraints.tabTitle=AICc
+aicPanel.TabConstraints.tabTitle=AIC
+aicScrollPanel.TabConstraints.tabTitle=AIC
+bicPanel.TabConstraints.tabTitle=BIC
+bicScrollPanel.TabConstraints.tabTitle=BIC
+btnExport=Export to main console
+displayAICcImpAlphaInv.text=+I+G Imp
+displayAICcImpAlpha.text=+G Imp
+displayAICcImpF.text=+F Imp
+displayAICcImpInv.text=+I Imp
+displayAICcoAlphaInv.text=AICc-AI
+displayAICcoAlpha.text=AICc-Alpha
+displayAICcoInvAlpha.text=AICc-IA
+displayAICcoInv.text=AICc-Inv
+displayAICImpAlphaInv.text=+I+G Imp
+displayAICImpAlpha.text=+G Imp
+displayAICImpF.text=+F Imp
+displayAICImpInv.text=+I Imp
+displayAICoAlphaInv.text=AIC-AI
+displayAICoAlpha.text=AIC-Alpha
+displayAICoInvAlpha.text=AIC-IA
+displayAICoInv.text=AIC-Inv
+displayBICImpAlphaInv.text=+I+G Imp
+displayBICImpAlpha.text=+G Imp
+displayBICImpF.text=+F Imp
+displayBICImpInv.text=+I Imp
+displayBICoAlphaInv.text=BIC-AI
+displayBICoAlpha.text=BIC-Alpha
+displayBICoInvAlpha.text=BIC-IA
+displayBICoInv.text=BIC-Inv
+displayDTImpAlphaInv.text=+I+G Imp
+displayDTImpAlpha.text=+G Imp
+displayDTImpF.text=+F Imp
+displayDTImpInv.text=+I Imp
+displayDToAlphaInv.text=DT-AI
+displayDToAlpha.text=DT-Alpha
+displayDToInvAlpha.text=DT-IA
+displayDToInv.text=DT-Inv
+dtPanel.TabConstraints.tabTitle=DT
+exportData.Action.shortDescription=Export to main console
+exportData.Action.text=Export to main console
+export-data=Export to main console
+Form.title=Results
+lblAICcImpAlphaInv.text=+I+G
+lblAICcImpAlpha.text=+G
+lblAICcImpF.text=+F
+lblAICcImpInv.text=+I
+lblAICcPI.text=Parameter Importance
+lblAICImpAlphaInv.text=+I+G
+lblAICImpAlpha.text=+G
+lblAICImpF.text=+F
+lblAICImpInv.text=+I
+lblAICPI.text=Parameter Importance
+lblBICImpAlphaInv.text=+I+G
+lblBICImpAlpha.text=+G
+lblBICImpF.text=+F
+lblBICImpInv.text=+I
+lblBICPI.text=Parameter Importance
+lblComandLineLabel.text=Command Line:
+lblCommandLine.background=235, 237, 237
+lblConfidence.text=1.0
+lblConfInt.text=Confidence Interval:
+lblDTImpAlphaInv.text=+I+G
+lblDTImpAlpha.text=+G
+lblDTImpF.text=+F
+lblDTImpInv.text=+I
+lblDTPI.text=Parameter Importance
+lblNotComplete.background=255, 0, 51
+lblNotComplete.font=Dialog-Plain-12
+lblNotComplete.foreground=0, 0, 0
+lbl-overall-alpha=Alpha
+lbl-overall-alpha-inv=Alpha-Inv
+lbl-overall-inv-alpha=Inv-Alpha
+lbl-overall-inv=Inv
+lbl-overall=Model-averaged estimates
+lblSelectedModelLabel.text=Selected Model:
+lblSelectedModel.text=
diff --git a/src/main/java/es/uvigo/darwin/xprottest/util/BrowserLauncher.java b/src/main/java/es/uvigo/darwin/xprottest/util/BrowserLauncher.java
new file mode 100755
index 0000000..1ee8533
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/util/BrowserLauncher.java
@@ -0,0 +1,583 @@
+package es.uvigo.darwin.xprottest.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * BrowserLauncher is a class that provides one static method, openURL, which opens the default
+ * web browser for the current user of the system to the given URL. It may support other
+ * protocols depending on the system -- mailto, ftp, etc. -- but that has not been rigorously
+ * tested and is not guaranteed to work.
+ * <p>
+ * Yes, this is platform-specific code, and yes, it may rely on classes on certain platforms
+ * that are not part of the standard JDK. What we're trying to do, though, is to take something
+ * that's frequently desirable but inherently platform-specific -- opening a default browser --
+ * and allow programmers (you, for example) to do so without worrying about dropping into native
+ * code or doing anything else similarly evil.
+ * <p>
+ * Anyway, this code is completely in Java and will run on all JDK 1.1-compliant systems without
+ * modification or a need for additional libraries. All classes that are required on certain
+ * platforms to allow this to run are dynamically loaded at runtime via reflection and, if not
+ * found, will not cause this to do anything other than returning an error when opening the
+ * browser.
+ * <p>
+ * There are certain system requirements for this class, as it's running through Runtime.exec(),
+ * which is Java's way of making a native system call. Currently, this requires that a Macintosh
+ * have a Finder which supports the GURL event, which is true for Mac OS 8.0 and 8.1 systems that
+ * have the Internet Scripting AppleScript dictionary installed in the Scripting Additions folder
+ * in the Extensions folder (which is installed by default as far as I know under Mac OS 8.0 and
+ * 8.1), and for all Mac OS 8.5 and later systems. On Windows, it only runs under Win32 systems
+ * (Windows 95, 98, and NT 4.0, as well as later versions of all). On other systems, this drops
+ * back from the inherently platform-sensitive concept of a default browser and simply attempts
+ * to launch Netscape via a shell command.
+ * <p>
+ * This code is Copyright 1999-2001 by Eric Albert (ejalbert at cs.stanford.edu) and may be
+ * redistributed or modified in any form without restrictions as long as the portion of this
+ * comment from this paragraph through the end of the comment is not removed. The author
+ * requests that he be notified of any application, applet, or other binary that makes use of
+ * this code, but that's more out of curiosity than anything and is not required. This software
+ * includes no warranty. The author is not repsonsible for any loss of data or functionality
+ * or any adverse or unexpected effects of using this software.
+ * <p>
+ * Credits:
+ * <br>Steven Spencer, JavaWorld magazine (<a href="http://www.javaworld.com/javaworld/javatips/jw-javatip66.html">Java Tip 66</a>)
+ * <br>Thanks also to Ron B. Yeh, Eric Shapiro, Ben Engber, Paul Teitlebaum, Andrea Cantatore,
+ * Larry Barowski, Trevor Bedzek, Frank Miedrich, and Ron Rabakukk
+ *
+ * @author Eric Albert (<a href="mailto:ejalbert at cs.stanford.edu">ejalbert at cs.stanford.edu</a>)
+ * @version 1.4b1 (Released June 20, 2001)
+ */
+public class BrowserLauncher {
+
+ /**
+ * The Java virtual machine that we are running on. Actually, in most cases we only care
+ * about the operating system, but some operating systems require us to switch on the VM. */
+ private static int jvm;
+
+ /** The browser for the system */
+ private static Object browser;
+
+ /**
+ * Caches whether any classes, methods, and fields that are not part of the JDK and need to
+ * be dynamically loaded at runtime loaded successfully.
+ * <p>
+ * Note that if this is <code>false</code>, <code>openURL()</code> will always return an
+ * IOException.
+ */
+ private static boolean loadedWithoutErrors;
+
+ /** The com.apple.mrj.MRJFileUtils class */
+ private static Class mrjFileUtilsClass;
+
+ /** The com.apple.mrj.MRJOSType class */
+ private static Class mrjOSTypeClass;
+
+ /** The com.apple.MacOS.AEDesc class */
+ private static Class aeDescClass;
+
+ /** The <init>(int) method of com.apple.MacOS.AETarget */
+ private static Constructor aeTargetConstructor;
+
+ /** The <init>(int, int, int) method of com.apple.MacOS.AppleEvent */
+ private static Constructor appleEventConstructor;
+
+ /** The <init>(String) method of com.apple.MacOS.AEDesc */
+ private static Constructor aeDescConstructor;
+
+ /** The findFolder method of com.apple.mrj.MRJFileUtils */
+ private static Method findFolder;
+
+ /** The getFileCreator method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileCreator;
+
+ /** The getFileType method of com.apple.mrj.MRJFileUtils */
+ private static Method getFileType;
+
+ /** The openURL method of com.apple.mrj.MRJFileUtils */
+ private static Method openURL;
+
+ /** The makeOSType method of com.apple.MacOS.OSUtils */
+ private static Method makeOSType;
+
+ /** The putParameter method of com.apple.MacOS.AppleEvent */
+ private static Method putParameter;
+
+ /** The sendNoReply method of com.apple.MacOS.AppleEvent */
+ private static Method sendNoReply;
+
+ /** Actually an MRJOSType pointing to the System Folder on a Macintosh */
+ private static Object kSystemFolderType;
+
+ /** The keyDirectObject AppleEvent parameter type */
+ private static Integer keyDirectObject;
+
+ /** The kAutoGenerateReturnID AppleEvent code */
+ private static Integer kAutoGenerateReturnID;
+
+ /** The kAnyTransactionID AppleEvent code */
+ private static Integer kAnyTransactionID;
+
+ /** The linkage object required for JDirect 3 on Mac OS X. */
+ private static Object linkage;
+
+ /** The framework to reference on Mac OS X */
+ private static final String JDirect_MacOSX = "/System/Library/Frameworks/Carbon.framework/Frameworks/HIToolbox.framework/HIToolbox";
+
+ /** JVM constant for MRJ 2.0 */
+ private static final int MRJ_2_0 = 0;
+
+ /** JVM constant for MRJ 2.1 or later */
+ private static final int MRJ_2_1 = 1;
+
+ /** JVM constant for Java on Mac OS X 10.0 (MRJ 3.0) */
+ private static final int MRJ_3_0 = 3;
+
+ /** JVM constant for MRJ 3.1 */
+ private static final int MRJ_3_1 = 4;
+
+ /** JVM constant for any Windows NT JVM */
+ private static final int WINDOWS_NT = 5;
+
+ /** JVM constant for any Windows 9x JVM */
+ private static final int WINDOWS_9x = 6;
+
+ /** JVM constant for any other platform */
+ private static final int OTHER = -1;
+
+ /**
+ * The file type of the Finder on a Macintosh. Hardcoding "Finder" would keep non-U.S. English
+ * systems from working properly.
+ */
+ private static final String FINDER_TYPE = "FNDR";
+
+ /**
+ * The creator code of the Finder on a Macintosh, which is needed to send AppleEvents to the
+ * application.
+ */
+ private static final String FINDER_CREATOR = "MACS";
+
+ /** The name for the AppleEvent type corresponding to a GetURL event. */
+ private static final String GURL_EVENT = "GURL";
+
+ /**
+ * The first parameter that needs to be passed into Runtime.exec() to open the default web
+ * browser on Windows.
+ */
+ private static final String FIRST_WINDOWS_PARAMETER = "/c";
+
+ /** The second parameter for Runtime.exec() on Windows. */
+ private static final String SECOND_WINDOWS_PARAMETER = "start";
+
+ /**
+ * The third parameter for Runtime.exec() on Windows. This is a "title"
+ * parameter that the command line expects. Setting this parameter allows
+ * URLs containing spaces to work.
+ */
+ private static final String THIRD_WINDOWS_PARAMETER = "\"\"";
+
+ /**
+ * The shell parameters for Netscape that opens a given URL in an already-open copy of Netscape
+ * on many command-line systems.
+ */
+ private static final String NETSCAPE_REMOTE_PARAMETER = "-remote";
+ private static final String NETSCAPE_OPEN_PARAMETER_START = "'openURL(";
+ private static final String NETSCAPE_OPEN_PARAMETER_END = ")'";
+
+ /**
+ * The message from any exception thrown throughout the initialization process.
+ */
+ private static String errorMessage;
+
+ /**
+ * An initialization block that determines the operating system and loads the necessary
+ * runtime data.
+ */
+ static {
+ loadedWithoutErrors = true;
+ String osName = System.getProperty("os.name");
+ if (osName.startsWith("Mac OS")) {
+ String mrjVersion = System.getProperty("mrj.version");
+ String majorMRJVersion = mrjVersion.substring(0, 3);
+ try {
+ double version = Double.valueOf(majorMRJVersion).doubleValue();
+ if (version == 2) {
+ jvm = MRJ_2_0;
+ } else if (version >= 2.1 && version < 3) {
+ // Assume that all 2.x versions of MRJ work the same. MRJ 2.1 actually
+ // works via Runtime.exec() and 2.2 supports that but has an openURL() method
+ // as well that we currently ignore.
+ jvm = MRJ_2_1;
+ } else if (version == 3.0) {
+ jvm = MRJ_3_0;
+ } else if (version >= 3.1) {
+ // Assume that all 3.1 and later versions of MRJ work the same.
+ jvm = MRJ_3_1;
+ } else {
+ loadedWithoutErrors = false;
+ errorMessage = "Unsupported MRJ version: " + version;
+ }
+ } catch (NumberFormatException nfe) {
+ loadedWithoutErrors = false;
+ errorMessage = "Invalid MRJ version: " + mrjVersion;
+ }
+ } else if (osName.startsWith("Windows")) {
+ if (osName.indexOf("9") != -1) {
+ jvm = WINDOWS_9x;
+ } else {
+ jvm = WINDOWS_NT;
+ }
+ } else {
+ jvm = OTHER;
+ }
+
+ if (loadedWithoutErrors) { // if we haven't hit any errors yet
+ loadedWithoutErrors = loadClasses();
+ }
+ }
+
+ /**
+ * This class should be never be instantiated; this just ensures so.
+ */
+ private BrowserLauncher() { }
+
+ /**
+ * Called by a static initializer to load any classes, fields, and methods required at runtime
+ * to locate the user's web browser.
+ * @return <code>true</code> if all intialization succeeded
+ * <code>false</code> if any portion of the initialization failed
+ */
+ private static boolean loadClasses() {
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Class aeTargetClass = Class.forName("com.apple.MacOS.AETarget");
+ Class osUtilsClass = Class.forName("com.apple.MacOS.OSUtils");
+ Class appleEventClass = Class.forName("com.apple.MacOS.AppleEvent");
+ Class aeClass = Class.forName("com.apple.MacOS.ae");
+ aeDescClass = Class.forName("com.apple.MacOS.AEDesc");
+
+ aeTargetConstructor = aeTargetClass.getDeclaredConstructor(new Class [] { int.class });
+ appleEventConstructor = appleEventClass.getDeclaredConstructor(new Class[] { int.class, int.class, aeTargetClass, int.class, int.class });
+ aeDescConstructor = aeDescClass.getDeclaredConstructor(new Class[] { String.class });
+
+ makeOSType = osUtilsClass.getDeclaredMethod("makeOSType", new Class [] { String.class });
+ putParameter = appleEventClass.getDeclaredMethod("putParameter", new Class[] { int.class, aeDescClass });
+ sendNoReply = appleEventClass.getDeclaredMethod("sendNoReply", new Class[] { });
+
+ Field keyDirectObjectField = aeClass.getDeclaredField("keyDirectObject");
+ keyDirectObject = (Integer) keyDirectObjectField.get(null);
+ Field autoGenerateReturnIDField = appleEventClass.getDeclaredField("kAutoGenerateReturnID");
+ kAutoGenerateReturnID = (Integer) autoGenerateReturnIDField.get(null);
+ Field anyTransactionIDField = appleEventClass.getDeclaredField("kAnyTransactionID");
+ kAnyTransactionID = (Integer) anyTransactionIDField.get(null);
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_2_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ mrjOSTypeClass = Class.forName("com.apple.mrj.MRJOSType");
+ Field systemFolderField = mrjFileUtilsClass.getDeclaredField("kSystemFolderType");
+ kSystemFolderType = systemFolderField.get(null);
+ findFolder = mrjFileUtilsClass.getDeclaredMethod("findFolder", new Class[] { mrjOSTypeClass });
+ getFileCreator = mrjFileUtilsClass.getDeclaredMethod("getFileCreator", new Class[] { File.class });
+ getFileType = mrjFileUtilsClass.getDeclaredMethod("getFileType", new Class[] { File.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchFieldException nsfe) {
+ errorMessage = nsfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (SecurityException se) {
+ errorMessage = se.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_0:
+ try {
+ Class linker = Class.forName("com.apple.mrj.jdirect.Linker");
+ Constructor constructor = linker.getConstructor(new Class[]{ Class.class });
+ linkage = constructor.newInstance(new Object[] { BrowserLauncher.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ } catch (InvocationTargetException ite) {
+ errorMessage = ite.getMessage();
+ return false;
+ } catch (InstantiationException ie) {
+ errorMessage = ie.getMessage();
+ return false;
+ } catch (IllegalAccessException iae) {
+ errorMessage = iae.getMessage();
+ return false;
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ mrjFileUtilsClass = Class.forName("com.apple.mrj.MRJFileUtils");
+ openURL = mrjFileUtilsClass.getDeclaredMethod("openURL", new Class[] { String.class });
+ } catch (ClassNotFoundException cnfe) {
+ errorMessage = cnfe.getMessage();
+ return false;
+ } catch (NoSuchMethodException nsme) {
+ errorMessage = nsme.getMessage();
+ return false;
+ }
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+ /**
+ * Attempts to locate the default web browser on the local system. Caches results so it
+ * only locates the browser once for each use of this class per JVM instance.
+ * @return The browser for the system. Note that this may not be what you would consider
+ * to be a standard web browser; instead, it's the application that gets called to
+ * open the default web browser. In some cases, this will be a non-String object
+ * that provides the means of calling the default browser.
+ */
+ private static Object locateBrowser() {
+ if (browser != null) {
+ return browser;
+ }
+ switch (jvm) {
+ case MRJ_2_0:
+ try {
+ Integer finderCreatorCode = (Integer) makeOSType.invoke(null, new Object[] { FINDER_CREATOR });
+ Object aeTarget = aeTargetConstructor.newInstance(new Object[] { finderCreatorCode });
+ Integer gurlType = (Integer) makeOSType.invoke(null, new Object[] { GURL_EVENT });
+ Object appleEvent = appleEventConstructor.newInstance(new Object[] { gurlType, gurlType, aeTarget, kAutoGenerateReturnID, kAnyTransactionID });
+ // Don't set browser = appleEvent because then the next time we call
+ // locateBrowser(), we'll get the same AppleEvent, to which we'll already have
+ // added the relevant parameter. Instead, regenerate the AppleEvent every time.
+ // There's probably a way to do this better; if any has any ideas, please let
+ // me know.
+ return appleEvent;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InstantiationException ie) {
+ browser = null;
+ errorMessage = ie.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getMessage();
+ return browser;
+ }
+ case MRJ_2_1:
+ File systemFolder;
+ try {
+ systemFolder = (File) findFolder.invoke(null, new Object[] { kSystemFolderType });
+ } catch (IllegalArgumentException iare) {
+ browser = null;
+ errorMessage = iare.getMessage();
+ return browser;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ String[] systemFolderFiles = systemFolder.list();
+ // Avoid a FilenameFilter because that can't be stopped mid-list
+ for(int i = 0; i < systemFolderFiles.length; i++) {
+ try {
+ File file = new File(systemFolder, systemFolderFiles[i]);
+ if (!file.isFile()) {
+ continue;
+ }
+ // We're looking for a file with a creator code of 'MACS' and
+ // a type of 'FNDR'. Only requiring the type results in non-Finder
+ // applications being picked up on certain Mac OS 9 systems,
+ // especially German ones, and sending a GURL event to those
+ // applications results in a logout under Multiple Users.
+ Object fileType = getFileType.invoke(null, new Object[] { file });
+ if (FINDER_TYPE.equals(fileType.toString())) {
+ Object fileCreator = getFileCreator.invoke(null, new Object[] { file });
+ if (FINDER_CREATOR.equals(fileCreator.toString())) {
+ browser = file.toString(); // Actually the Finder, but that's OK
+ return browser;
+ }
+ }
+ } catch (IllegalArgumentException iare) {
+ browser = browser;
+ errorMessage = iare.getMessage();
+ return null;
+ } catch (IllegalAccessException iae) {
+ browser = null;
+ errorMessage = iae.getMessage();
+ return browser;
+ } catch (InvocationTargetException ite) {
+ browser = null;
+ errorMessage = ite.getTargetException().getClass() + ": " + ite.getTargetException().getMessage();
+ return browser;
+ }
+ }
+ browser = null;
+ break;
+ case MRJ_3_0:
+ case MRJ_3_1:
+ browser = ""; // Return something non-null
+ break;
+ case WINDOWS_NT:
+ browser = "cmd.exe";
+ break;
+ case WINDOWS_9x:
+ browser = "command.com";
+ break;
+ case OTHER:
+ default:
+ browser = "netscape";
+ break;
+ }
+ return browser;
+ }
+
+ /**
+ * Attempts to open the default web browser to the given URL.
+ * @param url The URL to open
+ * @throws IOException If the web browser could not be located or does not run
+ */
+ public static void openURL(String url) throws IOException {
+ if (!loadedWithoutErrors) {
+ throw new IOException("Exception in finding browser: " + errorMessage);
+ }
+ Object browser = locateBrowser();
+ if (browser == null) {
+ throw new IOException("Unable to locate browser: " + errorMessage);
+ }
+
+ switch (jvm) {
+ case MRJ_2_0:
+ Object aeDesc = null;
+ try {
+ aeDesc = aeDescConstructor.newInstance(new Object[] { url });
+ putParameter.invoke(browser, new Object[] { keyDirectObject, aeDesc });
+ sendNoReply.invoke(browser, new Object[] { });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while creating AEDesc: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while building AppleEvent: " + iae.getMessage());
+ } catch (InstantiationException ie) {
+ throw new IOException("InstantiationException while creating AEDesc: " + ie.getMessage());
+ } finally {
+ aeDesc = null; // Encourage it to get disposed if it was created
+ browser = null; // Ditto
+ }
+ break;
+ case MRJ_2_1:
+ Runtime.getRuntime().exec(new String[] { (String) browser, url } );
+ break;
+ case MRJ_3_0:
+ int[] instance = new int[1];
+ int result = ICStart(instance, 0);
+ if (result == 0) {
+ int[] selectionStart = new int[] { 0 };
+ byte[] urlBytes = url.getBytes();
+ int[] selectionEnd = new int[] { urlBytes.length };
+ result = ICLaunchURL(instance[0], new byte[] { 0 }, urlBytes,
+ urlBytes.length, selectionStart,
+ selectionEnd);
+ if (result == 0) {
+ // Ignore the return value; the URL was launched successfully
+ // regardless of what happens here.
+ ICStop(instance);
+ } else {
+ throw new IOException("Unable to launch URL: " + result);
+ }
+ } else {
+ throw new IOException("Unable to create an Internet Config instance: " + result);
+ }
+ break;
+ case MRJ_3_1:
+ try {
+ openURL.invoke(null, new Object[] { url });
+ } catch (InvocationTargetException ite) {
+ throw new IOException("InvocationTargetException while calling openURL: " + ite.getMessage());
+ } catch (IllegalAccessException iae) {
+ throw new IOException("IllegalAccessException while calling openURL: " + iae.getMessage());
+ }
+ break;
+ case WINDOWS_NT:
+ case WINDOWS_9x:
+ // Add quotes around the URL to allow ampersands and other special
+ // characters to work.
+ Process process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ FIRST_WINDOWS_PARAMETER,
+ SECOND_WINDOWS_PARAMETER,
+ THIRD_WINDOWS_PARAMETER,
+ '"' + url + '"' });
+ // This avoids a memory leak on some versions of Java on Windows.
+ // That's hinted at in <http://developer.java.sun.com/developer/qow/archive/68/>.
+ try {
+ process.waitFor();
+ process.exitValue();
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ case OTHER:
+ // Assume that we're on Unix and that Netscape is installed
+
+ // First, attempt to open the URL in a currently running session of Netscape
+ process = Runtime.getRuntime().exec(new String[] { (String) browser,
+ NETSCAPE_REMOTE_PARAMETER,
+ NETSCAPE_OPEN_PARAMETER_START +
+ url +
+ NETSCAPE_OPEN_PARAMETER_END });
+ try {
+ int exitCode = process.waitFor();
+ if (exitCode != 0) { // if Netscape was not open
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ }
+ } catch (InterruptedException ie) {
+ throw new IOException("InterruptedException while launching browser: " + ie.getMessage());
+ }
+ break;
+ default:
+ // This should never occur, but if it does, we'll try the simplest thing possible
+ Runtime.getRuntime().exec(new String[] { (String) browser, url });
+ break;
+ }
+ }
+
+ /**
+ * Methods required for Mac OS X. The presence of native methods does not cause
+ * any problems on other platforms.
+ */
+ private native static int ICStart(int[] instance, int signature);
+ private native static int ICStop(int[] instance);
+ private native static int ICLaunchURL(int instance, byte[] hint, byte[] data, int len,
+ int[] selectionStart, int[] selectionEnd);
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/util/OptimizationStrategyWrapper.java b/src/main/java/es/uvigo/darwin/xprottest/util/OptimizationStrategyWrapper.java
new file mode 100755
index 0000000..b431998
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/util/OptimizationStrategyWrapper.java
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 2009 Diego Darriba
+
+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
+*/
+package es.uvigo.darwin.xprottest.util;
+
+/**
+ * The class OptimizationStrategyWrapper models a ProtTest optimization
+ * strategy (about topology usage), providing a description and a option
+ * value together.
+ *
+ * @author Diego Darriba
+ */
+public class OptimizationStrategyWrapper {
+
+ private String description;
+ private int value;
+
+ public int getValue() {
+ return value;
+ }
+
+ public OptimizationStrategyWrapper(String description, int value) {
+ this.description = description;
+ this.value = value;
+ }
+
+ @Override
+ public String toString() {
+ return description;
+ }
+
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaAppender.java b/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaAppender.java
new file mode 100755
index 0000000..c447024
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaAppender.java
@@ -0,0 +1,31 @@
+package es.uvigo.darwin.xprottest.util;
+
+import java.io.IOException;
+import javax.swing.JTextArea;
+import java.io.Writer;
+
+/**
+ * Simple way to "print" to a JTextArea; just say
+ * PrintWriter out = new PrintWriter(new TextAreaAppender(myTextArea));
+ * Then out.println() et all will all appear in the TextArea.
+ */
+public final class TextAreaAppender extends Writer {
+
+ private final JTextArea textArea;
+
+ public TextAreaAppender(final JTextArea textArea) {
+ this.textArea = textArea;
+ }
+
+ @Override
+ public void flush(){ }
+
+ @Override
+ public void close(){ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ textArea.append(new String(cbuf, off, len));
+ textArea.setCaretPosition(textArea.getDocument().getLength());
+ }
+}
diff --git a/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaWriter.java b/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaWriter.java
new file mode 100755
index 0000000..1626ca1
--- /dev/null
+++ b/src/main/java/es/uvigo/darwin/xprottest/util/TextAreaWriter.java
@@ -0,0 +1,31 @@
+package es.uvigo.darwin.xprottest.util;
+
+import java.io.IOException;
+import javax.swing.JTextArea;
+import java.io.Writer;
+
+/**
+ * Simple way to "print" to a JTextArea; just say
+ * PrintWriter out = new PrintWriter(new TextAreaAppender(myTextArea));
+ * Then out.println() et all will all appear in the TextArea.
+ */
+public final class TextAreaWriter extends Writer {
+
+ private final JTextArea textArea;
+
+ public TextAreaWriter(final JTextArea textArea) {
+ this.textArea = textArea;
+ }
+
+ @Override
+ public void flush(){ }
+
+ @Override
+ public void close(){ }
+
+ @Override
+ public void write(char[] cbuf, int off, int len) throws IOException {
+ textArea.append(new String(cbuf, off, len));
+ textArea.setCaretPosition(off);
+ }
+}
diff --git a/src/main/resources/CHANGELOG b/src/main/resources/CHANGELOG
new file mode 100644
index 0000000..638c215
--- /dev/null
+++ b/src/main/resources/CHANGELOG
@@ -0,0 +1,40 @@
+-----------------------------------------------------------------------------
+ProtTest 3 Change Log - 23/Jan/2014
+
+Diego Darriba (ddarriba at udc.es)
+Guillermo L. Taboada (taboada at udc.es)
+Ramón Doallo (doallo at udc.es)
+David Posada (dposada at uvigo.es)
+
+(c) Universidad de Vigo, Vigo, Spain
+(c) Grupo de Arquitectura de Computadores, UDC, Spain
+
+-----------------------------------------------------------------------------
+
+ProtTest 3.4 (23/Jan/2014)
+
+ * Fix : Fixed problem while trying to execute ProtTest from outside its home directory.
+
+ * Enhancement : Added configuration property for disable logging.
+ Added configuration property for using a system-wide installed PhyML.
+
+ProtTest 3.3 (16/Jul/2013)
+
+ * Enhancement : Added real-time PhyML logging.
+
+ * Enhancement : Removed sample size selection. Fixed to alignment length.
+
+ProtTest 3.2 (16/Mar/2012)
+
+ * Enhancement: Enable the model selection and phylogenetic averaging
+ using more than one single Information Criterion:
+
+ "-sort" argument is replaced by -AIC, -BIC, -AICC and -DT arguments.
+
+ * Enhancement: By default, all model matrices are computed unless you
+ explicitly specify a subset.
+
+ProtTest 3.1 (5/Mar/2012)
+
+ * Enhancement: Added suport for old PhyML versions that does not support
+ the --no-memory-check option, through prottest.properties file.
diff --git a/src/main/resources/COPYING b/src/main/resources/COPYING
new file mode 100755
index 0000000..d60c31a
--- /dev/null
+++ b/src/main/resources/COPYING
@@ -0,0 +1,340 @@
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <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 Library General
+Public License instead of this License.
diff --git a/src/main/resources/README b/src/main/resources/README
new file mode 100755
index 0000000..3368595
--- /dev/null
+++ b/src/main/resources/README
@@ -0,0 +1,311 @@
+-----------------------------------------------------------------------------
+ProtTest 3 Readme - 23/Jan/2014
+
+Diego Darriba (ddarriba at udc.es)
+Guillermo L. Taboada (taboada at udc.es)
+Ramón Doallo (doallo at udc.es)
+David Posada (dposada at uvigo.es)
+
+(c) Universidad de Vigo, Vigo, Spain
+(c) Grupo de Arquitectura de Computadores, UDC, Spain
+
+Citation:
+
+ Darriba D, Taboada GL, Doallo R, Posada D. ProtTest 3: fast selection of
+ best-fit models of protein evolution. Bioinformatics, 27:1164-1165, 2011
+
+ In addition, given that ProtTest uses Phyml intensively, we encourage users to
+ cite this program as well when using ProtTest:
+
+ Guindon S, Gascuel O. 2003. A simple, fast, and accurate algorithm to
+ estimate large phylogenies by maximum likelihood. Syst Biol. 52: 696-704.
+ [Phyml]
+
+-----------------------------------------------------------------------------
+
+TOC
+
+0. Quick Start
+1. Introduction
+2. Installation
+3. Structure
+4. How to run
+ 4.1. Required conditions
+ 4.2. Console execution
+ 4.2.1. Sequential execution
+ 4.2.2. Multithread execution
+ 4.2.3. Cluster execution
+ 4.2.4. Cluster hybrid execution
+ 4.3. Graphical user interface execution
+5. Frequently Asked Questions
+
+-----------------------------------------------------------------------------
+0. Quick Start
+-----------------------------------------------------------------------------
+
+Console version
+
+$ tar zvxf prottest-3.4-yyyymmdd.tar.gz
+(Linux/Unix/OS X)
+$ export PROTTEST_HOME=$PWD/prottest3
+(Windows)
+$ set PROTTEST_HOME=$CWD\prottest3
+$ cd $PROTTEST_HOME
+$ java -jar prottest-3.4.jar -i examples/COX2_PF0016/alignment -all-matrices -all-distributions -threads 2
+
+Graphical version
+
+$ tar zvxf prottest-3.4-yyyymmdd.tar.gz
+(Linux/Unix/OS X)
+$ export PROTTEST_HOME=$PWD/prottest3
+(Windows)
+$ set PROTTEST_HOME=$CWD\prottest3
+$ cd $PROTTEST_HOME
+$ ./runXProtTest.sh
+
+-----------------------------------------------------------------------------
+1. Introduction
+-----------------------------------------------------------------------------
+
+ProtTest3 is a High Performance Computing implementation of ProtTest, for
+selection of best-fit models of protein evolution. It is currently under
+development so it could have some errors and the documentation is pending.
+
+Please, report bugs and enquiries about ProtTest 3 to: ddarriba at udc.es,
+dposada at uvigo.es.
+
+The main page of the ProtTest project is located at
+https://bitbucket.org/diegodl/prottest3
+
+-----------------------------------------------------------------------------
+2. Installation
+-----------------------------------------------------------------------------
+
+All required software is included in the distributions. For further information,
+please refer to the 'How to run' section.
+
+-----------------------------------------------------------------------------
+3. Structure
+-----------------------------------------------------------------------------
+
+Inside the ProtTest 3 directory you should find the following structure:
+
+$PROTTEST_HOME/
+ |
+ |
+ |--bin/
+ # auxiliary binaries to calculate models likelihood
+ |--examples/
+ # some test alignments and trees
+ |
+ | filecluster8.conf.template # machines file template for 8 node cluster
+ | machines # machines file for cluster execution
+ | prottest.properties # ProtTest3 configuration file (always required)
+ | prottest-3.4.jar # ProtTest3 package
+ | README # this README file
+ | COPYING # ProtTest3 licese
+ | runProtTestHPC.sh # basic script for ProtTest3 cluster execution
+ | runXProtTestHPC.sh # basic script for ProtTest3 graphical version
+
+- The ProtTest properties (prottest.properties) file must be located in the
+ProtTest root directory. It has the execution preferences. Please refer to such
+file to know more about the execution properties.
+
+- The external applications should be located on "bin" directory under the
+ProtTest root, where at least the one which matches your computer architecture
+must exist.
+
+-----------------------------------------------------------------------------
+4. How to run
+-----------------------------------------------------------------------------
+
+There are several ways to run ProtTest according to the resources you want
+to use.
+
+It's preferred to use JRE 1.6 to run ProtTest, in fact, the graphical user
+interface will only work with JRE 1.6 or newer version.
+
+You can download the newest version at http://java.sun.com/javase/
+
+-----------------------------------------------------------------------------
+ 4.1. Required conditions
+-----------------------------------------------------------------------------
+
+In order to run ProtTest there will be some general constraints you have to
+satisfy:
+
+- You should run it from the ProtTest root directory (i.e. the directory where
+you have unpackaged the distribution).
+
+-----------------------------------------------------------------------------
+ 4.2. Console execution
+-----------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------
+ 4.2.1 Sequential execution
+-----------------------------------------------------------------------------
+
+Under command line you can use several parallel executions of ProtTest, but first
+it is important to understand how to run the sequential execution.
+
+These are the parameters of the sequential execution:
+
+ -i alignment_filename
+ Alignment input file (required)
+ -t tree_filename
+ Tree file (optional) [default: NJ tree]
+ -o output_filename
+ Output file (optional) [default: standard output]
+ -log enabled/disabled
+ Enables / Disables PhyML logging into log directory (see prottest.properties)
+ -[matrix]
+ Include matrix (Amino-acid) = JTT LG DCMut MtREV MtMam MtArt Dayhoff WAG
+ RtREV CpREV Blosum62 VT HIVb HIVw FLU
+ If you don't specify any matrix, all matrices displayed above will
+ be included.
+ -I
+ Include models with a proportion of invariable sites
+ -G
+ Include models with rate variation among sites and number of categories
+ -IG
+ include models with both +I and +G properties
+ -all-distributions
+ Include models with rate variation among sites, number of categories and both
+ -ncat number_of_categories
+ Define number of categories for +G and +I+G models [default: 4]
+ -F
+ Include models with empirical frequency estimation
+ -AIC
+ Display models sorted by Akaike Information Criterion (AIC)
+ -BIC
+ Display models sorted by Bayesian Information Criterion (BIC)
+ -AICC
+ Display models sorted by Corrected Akaike Information Criterion (AICc)
+ -DT
+ Display models sorted by Decision Theory Criterion
+ -all
+ Displays a 7-framework comparison table
+ -S optimization_strategy
+ Optimization strategy mode: [default: 0]
+ 0: Fixed BIONJ JTT
+ 1: BIONJ Tree
+ 2: Maximum Likelihood tree
+ 3: User defined topology
+ -s moves
+ Tree search operation for ML search:
+ NNI (fastest), SPR (slowest), BEST (best of NNI and SPR) [default: NNI]
+ -t1
+ Display best-model's newick tree [default: false]
+ -t2
+ Display best-model's ASCII tree [default: false]
+ -tc consensus_threshold
+ Display consensus tree with the specified threshold, between 0.5 and 1.0
+ [0.5 = majority rule consensus ; 1.0 = strict consensus]
+ -threads number_or_threads
+ Number of threads requested to compute (only if MPJ is not used) [default: 1]
+ -verbose
+ Verbose mode [default: false]
+
+
+Basic execution example:
+
+ $ cd $PROTTEST_HOME
+ $ java -jar prottest-3.4.jar -i examples/COX2_PF0016/alignment -all-distributions -F -AIC -BIC -tc
+
+
+-----------------------------------------------------------------------------
+ 4.2.2 Multithread execution
+-----------------------------------------------------------------------------
+
+Just like the sequential execution, but adding the number of threads option. You
+can use up to the number of cores in your machine and beyond. Following the basic
+execution example, a recommended multithread execution in a quad-core machine will be:
+
+ $ cd $PROTTEST_HOME
+ $ java -jar prottest-3.4.jar -i examples/COX2_PF0016/alignment -all-distributions -F -AIC -BIC -tc -threads 4
+
+It is remarkable that the substitution models will not be computed in a specific
+order, so the full output will be shown once all models have been computed.
+Meanwhile, the main thread will notify each executed model by the standard output.
+
+-----------------------------------------------------------------------------
+ 4.2.3 Cluster execution
+-----------------------------------------------------------------------------
+
+1. Besides the multithreading support, it is possible to run ProtTest in
+a cluster. This support has been implemented using a Java message-passing
+(MPJ) library, MPJ Express (http://mpj-express.org/). To execute ProtTest
+in a cluster environment you have to:
+
+$ cd $PROTTEST_HOME
+$ export MPJ_HOME=$PROTTEST_HOME/mpj
+$ export PATH=$MPJ_HOME/bin:$PATH
+
+You can also add the last two lines to ~/.bashrc to automatically set this
+variables at console startup.
+
+2. $PROTTEST_HOME/machines file contains the set of compute nodes amongst the
+mpj processes will be executed. By default it points to the localhost machine,
+so you should change it if you want to run parallel exeecution over a cluster
+machine, just writing on each line the compute nodes (e.g. see
+filecluster8.conf.template).
+
+3. Start the MPJ Express daemons:
+
+$ mpjboot machines
+
+The application "mpjboot" should be in the execution path (it is located at
+$MPJ_HOME/bin). A ssh service must be running in the machines listed in the
+machines file. Moreover, port 10000 should be free. For more details refer to
+the MPJ Express documentation.
+
+4. Run ProtTest. For the execution the ProtTest distribution provides a
+bash script: 'runProtTestHPC.sh'
+
+The basic syntax is:
+ ./runProtTestHPC.sh $NUMBER_OF_PROCESSORS $APPLICATION_PARAMETERS
+
+$ ./runProtTestHPC.sh 2 -i examples/COX2_PF0016/alignment -all-distributions -F -AIC -BIC -tc
+
+-----------------------------------------------------------------------------
+ 4.2.4 Cluster hybrid execution
+-----------------------------------------------------------------------------
+
+This strategy relies on a thread-based implementation of phyml together with the
+distributed memory of ProtTest version. Please request us the thread-based
+phyml source code and further documentation.
+
+-----------------------------------------------------------------------------
+ 4.3. Graphical user interface execution
+-----------------------------------------------------------------------------
+
+If you are running ProtTest on your desktop computer, you'd better use the
+graphical user interface, provided by the XProtTest package. It will be
+show results clearer to the user and will be easier to manipulate them too.
+
+The graphical interface can use a sequential or a shared memory execution
+of the application, so it will be the best choice for running ProtTest on
+a local multicore machine.
+
+$ cd $PROTTEST_HOME
+$ ./runXProtTestHPC.sh
+
+-----------------------------------------------------------------------------
+5. Frequently Asked Questions
+-----------------------------------------------------------------------------
+
+ 5.1. I got this error when running ProtTest 3
+
+ ./phyml-prottest-linux: /lib/libc.so.6: version `GLIBC_2.7' not found
+
+ ---
+
+ You can try to update GLIB to the required version (2.7). However, this is
+ not always possible, for example when running ProtTest on a cluster. If
+ you have an old version of PhyML you can try to use it just linking the
+ binary file to $PROTTEST_HOME/bin/phyml
+
+ If this does not work, it is possible that your "old" version of PhyML
+ does not support the --no-memory-check argument, included in lattest PhyML
+ versions. In this case, edit the prottest.properties file and change the
+ "no-memory-check" property to "no".
diff --git a/src/main/resources/THIRDPARTYLICENSES b/src/main/resources/THIRDPARTYLICENSES
new file mode 100755
index 0000000..e725d98
--- /dev/null
+++ b/src/main/resources/THIRDPARTYLICENSES
@@ -0,0 +1,576 @@
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'MPJ Express'
+http://mpj-express.org
++++++++++++++++++++++++++++++++++++++++++++
+
+1. The license statement
+
+ The MIT License
+
+ Copyright (c) 2005 - 2007
+ 1. Distributed Systems Group, University of Portsmouth (2005)
+ 2. Aamir Shafi (2005 - 2007)
+ 3. Bryan Carpenter (2005 - 2007)
+ 4. Mark Baker (2005 - 2007)
+
+ The bulk of code in this distribution was developed by the Distributed Systems
+ Group at the University of Portsmouth. Some sections of the code like
+ the buffering API and derived datatypes include contributions developed at
+ the Community Grids Lab at Indiana University.
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be included
+ in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
+ NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+2. MPJ uses two third party softwares: Jetty and Java Service Wrapper project.
+ The licenses for these two projects can be seen in
+ $MPJ_HOME/THIRDPARTYLICENSES file.
+
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'PAL' Library
+http://www.cebl.auckland.ac.nz/pal-project/
++++++++++++++++++++++++++++++++++++++++++++
+
+Copyright (c) 1999-2002 by the PAL Development Core Team
+This package may be distributed under the terms of the
+GNU Lesser General Public License (LGPL):
+http://www.cebl.auckland.ac.nz/pal-project/license.html
+
+PAL Development Core Team:
+
+Alexei Drummond, School of Biological Sciences, University of Auckland
+Korbinian Strimmer, Department of Zoology, University of Oxford
+Ed Buckler, Department of Genetics, North Carolina State University
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'PhyML' Library
+http://code.google.com/p/phyml/
++++++++++++++++++++++++++++++++++++++++++++
+
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <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 Library General
+Public License instead of this License.
+
++++++++++++++++++++++++++++++++++++++++++++
+LICENSE FOR 'Alter' Library
+http://sing.ei.uvigo.es/ALTER
++++++++++++++++++++++++++++++++++++++++++++
+
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/src/main/resources/examples/COX2_PF0016/alignment b/src/main/resources/examples/COX2_PF0016/alignment
new file mode 100755
index 0000000..1a78cb2
--- /dev/null
+++ b/src/main/resources/examples/COX2_PF0016/alignment
@@ -0,0 +1,30 @@
+28 149
+COX2_SYNY3 MAHNHMGHMGSMGNMVAMAGDGDVALGIGLDSEEQGVNPLMVDVKGIQYAWIFTYPETGIISGELHAPIDRPVQLNMEAGDVIHAFWIPQLRLKQDVIPGRGSTLVFNASTPGQYPVICAELCGAYHGGMKSVFYAHTPEEYDDWVAAN
+COX2_ZOOAN MTIKTIGHQWYWSYEYSDFI------KVEFDS-------YMTPYEEDNKK----MFRLLETDNHVTLPMNSFIRIIVTAADVLHSWTIPSLGIKADATPGRLNQSSFMINRPGLLYGQCSEICGANHSFMPIVIESVSTKKFIEWIKNL
+COX2_PERAM VTLKTIGHQWYWSYEYSDFA------KVEFDS-------YMIPQDEMDHS----MFRLLDVDNRAVLPMNTFIRIIVTAADVLHSWTIPSLGVKADATPGRLNQVSFLINRPGVLYGQCSEICGANHSFMPIVIESISTNGFINWILKM
+COX2_SYMST ITLKTIGHQWYWSYEYSDFK------HIEFDS-------YMIPYNEMEES----GLRLLEVDNRTTLPMQTQVRILITAADVLHSWTVPSLGIKVDATPGRLNQTSFFINRPGIFFGQCSEICGANHSFMPIMIESVNIKSFINWIQNM
+COX2_ACHDO ITMKTIGHQWYWSYEYMDFKN-----IIEFDS-------YMSALDKLSS------FRLLDVDNRTILPMNTQIRTLVTAADVIHSWTVSALGVKTDATPGRLNQINFMINRPGLFYGQCSEICGANHSFMPIVIESVNLKNFINWIKNY
+COX2_ONCFA MTLKVIGHQWYWSYEYSDFK------NIEFDS-------YMKPTNELMNN----EFRLLEVDNRVLLPMNKQIRILITAADVLHSWAIPSLGVKIDATPGRLNQGSIKINRPGILFGQCSEICGANHSFMPIVIESVPIKNFLKWINKS
+COX2_CTEFE ISLKAIGHQWYWSYEYTDFN------NISFDS-------YMIPSNELNLN----SFRLLDVDNRIILPINSQIRILITATDVLHSWTIPSLGIKIDATPGRLNQSNFMMNRPGLYFGQCSEICGANHSFMPIVIESILINSFIKWISSN
+COX2_ANOGA ITLKSIGHQWYWSYEYSDFL------NLEFDS-------YMVPTNELETN----GFRLLDVDNRVVLPMNNQIRILVTATDVLHSWTVPSLGVKVDATPGRLNQLNFLINRPGLFFGQCSEICGANHSFMPIVIESIPMNYFIKWITSM
+COX2_LOCMI ITIKTIGRQWYWSYEYSDFI------NVEFDT-------YMTPENELNTD----EFRLLEVDNRTTLPMNTEVRVLTSASDVLHSWAVPALVLKIDATPGRLNQGMFMINRPGLFFGQCSEICGANHSFMPIVIESTSIKLFIKWLSNM
+COX2_SITGR LLIKIIGHQWYWSYEYSDYK------NIEFDS-------YMIPTKELNSF----NFRLLEVDNRTPIPYKTQIRILVTSADVIHSWTIPSMSIKIDGTPGRLNQANLIANRSSIFFGQCSEICGANHSFMPIVLESITPNLFLNWVISK
+COX2_ADABI VTLKTIGHQWYWTYEYSDFK------KLEFDS-------YMLSYDNLNPF----NFRLLEVDNRTILPYLSNIRLLTSSADVIHSWTIPSSGVKIDASPGRLNQMSFTLNRTGIFYGQCSEICGANHSFMPISIESISPSNFIKWVNKS
+COX2_LASSP ITIKSVGHQWYWSYEYSDFL------NIEFDS-------FMIPSNQLNPN----EFRLLDTDNRCILPFNYPIRILTTSMDVIHSWTVPSLGIKMDSTPGRLNQSLLYMYRPGLYFGQCSEICGTNHSFMPIVIESTNFSYFKNWLKSF
+COX2_EXERO MTIKSIGHQWYWSYEYSDFK------NIDFNS-------FMINSK--NLN----HFRLLDVDNRMIIPMNNQIRMLINSADVIHSWTVPSLGVKIDSVPGRINQTLMMINRPGIYFGQCSEICGMNHSFMPIVIESTSNNNFISWLKSL
+COX2_APILI FSIKSIGHQWYWSYEYPEFN------NIEFDS-------YMLNYN--NLN----QFRLLETDNRMVIPMKIPLRLITTSTDVIHSWTVPSLGIKVDAVPGRINQLNLISKRPGIFFGQCSEICGMNHSFMPIMIESTSFQYFLNWVNKQ
+COX2_PARLI LTIKAIGHQWYWSYEYTDYN------DLEFDS-------YMVPTSDVSLG----NPRLLEVDNRLILPMQNPIRVLVSSADVLHSWAVPSLGVKMDAVPGRLNQTTFFAARAGLFYGQCSEICGANHSFMPILIESVPFSNFENWVAQY
+COX2_BALMU LTVKTMGHQWYWSYEYTDYE------DLSFDS-------YMIPTSDLKPG----ELRLLEVDNRVVLPMEMTIRMLVSSEDVLHSWAVPSLGLKTDAIPGRLNQTTLMSTRPGLFYGQCSEICGSNHSFMPIVLELVPLEFFEKWSASM
+COX2_CROLA LTIKAMGHQWYWSYEYTDYE------NLSFDS-------YMIPTQDLTPG----QFRLLETDHRMVVPMESPIRILVSAEDVLHSWALPAMGVKMDAVPGRLNQTAFIASRPGVFYGQCSEICGANHSFMPIVVEAVPLSHFENWSTLM
+COX2_CHICK LTLKAIGHQWYWTYEYTDFK------DLSFDS-------YMTPTTDLPLG----HFRLLEVDHRIVIPMESPIRVIITADDVLHSWAVPALGVKTDAIPGRLNQTSFITTRPGVFYGQCSEICGANHSYMPIVVESTPLKHFEAWSSLL
+COX2_CERAE FTIKSIGHQWYWTYEYTDYG------GLIFNS-------YMLPPLFLNPG----DLRLLEVDNRVVLPIEAPVRMMITSQDVLHSWTIPTLGLKTDAVPGRLNQTTFTATRPGVYYGQCSEICGANHSFMPIVAELIPLKIFEMGPVFT
+COX2_BETVU ITIKAIGHQWYRSYEYSDYNS-SDEQSLTFDS-------YTIPEDDPELG----QSRLLEVDNRVVVPAKTHIRIIVTSADVLHSWAVPSSGVKCDAVPGRLNQTSILVQREGVYYGQCSEICGTNHAFMPIVVEAVSRKDYGSRVSNQ
+COX2_ALBTU IVLKAIGHQWYWSYEMPSMN------VSSIDS-------YMIPEDDLKPG----EYRLLEVDNRPTVPYGMDINVIATSADVIHAWALPSMGVKMDAVPGRLNSMGFHANLPGIYYGQCSEICGANHSFMPIAIEAVDVKDFINMCN--
+COX2_CANGA MTIKAIGYQWYWKYEYSDFIN-DNGETIEFES-------YVIPDDLLEEG----QLRLLDTDTSVVVPVDTHIRFVVTGADVIHDFAIPSLGIKVDANPGRLNQVSALIQREGVFYGQCSELCGVNHAAMPIKIEAVSLPKFLEWLNEQ
+COX2_BREAN MTIKAMGLQWYWKYEYSDFMD-DKGETMEFES-------YMIPEDLLEEG----QLRQLDVDSPMVCPVDTHMRFMVTAADVMHDFAMPSLGIKIDAVPGRLNQTSALIQREGVYYGQCSELCGVMHSSMPMKIEAVSLGEFLAWIDEQ
+COX2_NEUCR MSVLAEGHQWYWSYQYPDFLD-SNDEFIEFDS-------YIVPESDLEEG----ALRMLEVDNRVILPELTHVRFIITAGDVIHDFAVPSLGVKCDAYPRRLNQVSVFINREGVFYGQCSEICGILHSSMPIVIESVSLEKFLTWLEEQ
+COX2_EMENI LVVYAEGHQWYWSYQYPDFTN-EDNEFIEFDS-------YIVPESDLEEG----QFRMLEVDNRVIIPELTHTAFVIS-ADVIHSYACPSLGIKADAYPGRLNQASVYINGPGTFFGQCSEICGILHSSMNIAIQSVSIKDFLLWLRDQ
+COX2_SCHPO MTVKAIGRQWFWTYELNDFVT-NENEPVSFDS-------YMVPEEDLEEG----SLRQLEVDNRLVLPIDTRIRLILTSGDVIHSWAVPSLGIKCDCIPGRLNQVSLSIDREGLFYGQCSELCGVLHSSMPIVVQGVSLEDFLAWLEEN
+COX2_ASCSU LTVKVTGHQWYWSYEFSDIP------GLEFDS-------YMKSLDQLELG----EPRLLEVDNRCVVPCDVNIRFCITSGDVIHSWALPSMSIKLDAMSGILSTLSYSFPVVGVFYGQCSEICGANHSFMPVALEVTLLDNFKSWCVGL
+COX2_PARDE LVIKAIGHQWYWSYEYPNDG-------VAFDA-------LMLEKEALADAGYSEDEYLLATDNPVVVPVGKKVLVQVTATDVIHAWTIPAFAVKQDAVPGRIAQLWFSVDQEGVYFGQCSELCGINHAYMPIVVKAVSQEKYEAWLAGA
+
diff --git a/src/main/resources/examples/COX2_PF0016/tree b/src/main/resources/examples/COX2_PF0016/tree
new file mode 100755
index 0000000..05bc1be
--- /dev/null
+++ b/src/main/resources/examples/COX2_PF0016/tree
@@ -0,0 +1 @@
+((((((((((COX2_PERAM:0.12268,COX2_ZOOAN:0.14756):0.11296,((COX2_LOCMI:0.20148,((COX2_ANOGA:0.10575,COX2_CTEFE:0.14893):0.07661,COX2_ONCFA:0.14446):0.02458):0.03199,COX2_SYMST:0.14364):0.02951):0.02164,COX2_ACHDO:0.15257):0.02391,(((COX2_APILI:0.28114,COX2_LASSP:0.19564):0.06636,COX2_EXERO:0.14195):0.10415,COX2_SITGR:0.26620):0.05473):0.02165,COX2_ADABI:0.29483):0.12302,((COX2_PARLI:0.18778,(COX2_BALMU:0.16978,(COX2_CROLA:0.10531,COX2_CHICK:0.19774):0.08705):0.05161):0.00000,COX2_CERAE:0. [...]
diff --git a/src/main/resources/examples/HIV1.2008.pol.nex b/src/main/resources/examples/HIV1.2008.pol.nex
new file mode 100755
index 0000000..14db7cd
--- /dev/null
+++ b/src/main/resources/examples/HIV1.2008.pol.nex
@@ -0,0 +1,37 @@
+36 1034
+A1.AU.03. FFRENLAFQQ-GEARKFPSEQTRANS-----------PTSGALWDGG-----RDNLPSEAGAEGQGTG---------PTLSFPQITLWQRPIVTVRIEGQLREALLDTGADDTVLEDIDLPGKWKPRMIGGIGGFIKVKQYDQISIEICGKRAIGTVLVGPTPVNIIGRNMXXQIGCTLNXPISPIETVPVKLKPGMDGPKVKQWPLTAEKIKALTEICTDMEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDENFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPYRAKNPDIIIYQYMDDLYVGSDLEIGQHRAKIEELRAHLLSWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPINLPEKESWTVNDIQKLVGKLNWASQIYAGIKVKQLCKLLRGAKALTDVVTLTEEAEL [...]
+A1.KE.94. FFRENLAFQK-GEAREFSSEQTGTNS-----------STSRDLWDGG-----RDSLPSEAGAERQGTG---------PTLSFPQITLWQRPLVTVRIGGQLKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVKQYDQILIEICGKKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLHEEFRKYTAFTIPSTNNETPGVRYQYNVLPQGWKGSPAIFQSSMTKILEPFRSKNPEIVIYQYMDDLYVGSDLEIGQHRAKIEELRAHLLSWGLITPDKKHQKEPPFLWMGYELHPDKWTVQPIELPEKDSWTVNDIQKLVGKLNWASQIYAGIKVKQLCKLLRGAKALTDVVTLTEEAEL [...]
+A1.RW.92. FFRENLAFQQ-GEARKFSSEQTGAIS-----------PTSRDLWDRG-----RDSLPSEAGAERQGTG---------PTFSFPQITLWQRPLVTVRIGGQLKEALLDTGADDTVLEDINLPGKWKPRMIGGIGGFIKVKQYDQILIEICGKKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICSEMEKEGKISRIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDESFRKYTAFTIPSTNNETPGTRYQYNVLPQGWKGSPAIFQSSMTRILEPVRSKNPDIIIYQYMDDLYVGSDLEIGQHRAKIEELRAHLLSWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIVLPDKDHWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLRGAKALTDIVTLTEEAEL [...]
+A1.UG.92. FFRENLAFQQ-REARKFSSEQTRTNS----------PTSSRDLWDEG-----RDSLPSEAGAERQGPE---------PTFSFPQITLWQRPLVTVKIGGQLKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVKQYDQILIEICGKKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPISTVPVKLKPGMDGPRIKQWPLTEEKIKALTEICADMEREGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDESFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQASMTKILEPFRSKNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIELPEKESWTVNDIQKLVGKLNWASQIYAGIKVKQLCKLLRGAKALTDIVTLTEEAEL [...]
+B.FR.83.H FFREDLAFLQ-GKAREFSSEQTRANS-----------PTRRELQVWG-----RDNNSPSEAGADRQGT---------VSFNFPQVTLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMSLPGRWKPKMIGGIGGFIKVRQYDQILIEICGHKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELRQHLLRWGLTTPDKKHQKEPPFLWMGYELHPDKWTVQPIVLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGTKALTEVIPLTEEAEL [...]
+B.NL.00.6 FFREDLAFPQ-GEAREFSSEQTRANSPFSEQTRANS-PTRRELQVWG-----RDNNSLSEAGANRQGT---------VSFSFPQITLWQRPIVTIKIGGQLKEALLDTGADDTVLEEMDLPGRWKPKMIGGIGGFIKVRQYDQILIEISGHKTIGTVLVGPTPVNIIGRNLLTQLGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTELEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPDIVIYQYMDDLYVGSDLEMGQHRTRIEELRQHLLKWGFDTPDKKHQKEPPFLWMGYELHPDKWTVQPIVLPEKDXWXVNDIQKLVGKXNWASQIYPGIKVRQLCKLLRGTKALTEIVPLTAEAEL [...]
+B.TH.90.B FFRENLAFPQ-GKAREFSSEQTRADS-----------PTSRELQVWG-----RDNNSLSEAGDNRQGT---------ISFNCPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMNLPGRWKPKMIGGIGGFIKVRQYDQILVEICGHKAIGTVLIGPTPVNIIGRNLLTQLGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRKQNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELRQHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIVLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLRGTKALTEVVPLTKEAEL [...]
+B.US.98.1 FFREDLAFPQ-RKAREFSSEQTRANS-----------PTSRELQVWG-----GDNNSLSEAGATRIS------------FSFPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMNLPGRWKPKMIGGIGGFIKVRQYDQIPIEICGNKAIGTVLIGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALAEICAEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKKTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDREFRKYTAFTIPSVNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEIVIYQYVDDLYVGSDLEIGQHRTKIEELRQHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIVLPEKDTWTVNDIQKLVGKLNWASQIYAGIKVRHLCKLLRGTKALTEVIPLTEEAEL [...]
+C.BR.92.B FFRENLAFPQ-GEARKSSSEQNRANS-----------PTRRELQVWG-----RDNNSLSEAGDDRQGT----------ALNFPQITLWQRPLVNIKVGGQLKEALLDTGADDTVLEEIKLPGNWKPKMIGGIGGFIKVRQYDQILIEICGKKAIGTVLVGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKVKQWLLTEEKIKALTAICDEMEREGKITKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRT?DFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEGFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPSIFQSSTTKILEPFRAQNPEIIIYQYMDDLYVGSDLEIGQHRAKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGAKALTDIVPLTEEAEL [...]
+C.ET.86.E FFRETLAFQQ-GKAREFPSEQTRANSPTRESQTRANSPTTRELQVR------GS-NTFSEAGAERQGS-----------LNFPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYDQIIIEICGKKAIGTVLVGPTPVNIIGRNMLTQLGRTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTAICEEMEQEGKISRIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEGFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPPIFQSSMPQILEPFRAPNPEIVIYQYMDDLYVGSDLEIGQHRAPIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGAKALTDIVTLTEEAEL [...]
+C.IN.95.9 FFRENLAFPQ-GEAREFPPE?TRANS-----------STSRELQVR------GD-NPSSEAGAERQGT-----------FNFPQITLWQRPLVSIRVGGQIKEALLDTGADDTVLEEVSLPGKWRPKMIGGIGGFIKVRQYEEIPIEICGKKAIGTVLVGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTAICDEMEKEGKITKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLYEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQNSMTRILEPFRAQNPEIVIYQYMDDLYVGSDLEIGQHRAKIEELRKHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGTKALTDIVPLTEEAEL [...]
+C.ZA.04.S FFRENLAFPE-GEAREFSPEQTRANS-----------PTSRELQVR------GD-DPCSETGAERQGT-----------FNFPQITLWQRPLVSIKIGGQTREALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYDQILIEICGKKAIGTVLVGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLSEEKIKALTAICEEMEKEGKITKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEGFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRAKNPEIAIYQYMDDLYVGSDLEIGQHRAKIEELREHLLR?GFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKDSWTVNDIQKLVGKLNWASQIYPGIQVKQLCRLLRGAKALTDIVPLTEEAEL [...]
+D.CD.83.E FFRENLAFPQ-GKAGELSPKQTRANS-----------PTSRELRVWG-----RD-NPLSKTGAERQGT---------VSFNFPQITLWQRPLVAIKIGGQLKEALLDTGADDTVLEEMNLPGKWKPKMIGGIGGFIKVRQYDQIPIEICGQKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTDMEKEGKISRIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEDFRKYTAFTISSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEMVIYQYMDDLYVGSDLEIGQHRTKIEKLREHLLRWGFTRPDKKHQKEPPFLWMGYELHPDKWTVQSIKLPEKESWTVNDIQNLVERLNWASQIYPGIKVRQLCKLLRGTKALTEVIPLTEEAEL [...]
+D.CM.01.0 FFRENLAFQQ-GKARELSSEQTRANS-----------PTSRELRVRG-----GD-SPLSETGAERQRP-------GTVSFNFPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVRQYDQIPIEICGQKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKIKQWPLTEEKIKALTDICKEMEKEGKISRIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFKKQNPELIIYSYMDDLYVGSDLEIGQHRAKIEKLREHLLKWGLTTPDKKHQKEPPFLWMGYELHPDKWTVQPITLPEKESWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGAKALTEIIPLTKEAEL [...]
+D.TZ.01.A FFRENLAFPQ-RKARELPSEQTRANS-----------PTSRDLRVWG-----GD-KTLSETGAERQGQ-------GTVSFSFPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEEMSLPGKWKPKMIGGIGGFIKVRQYDQILIEICGQKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIATVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISRIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEIVIYQYMDDLYVGSDLEIGQHRTKIEELRDHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIKLPEKESWTVNDIQKLVGKLNWASQIYSGIKVKQLCKLLRGAKALTEVIPLTKEAEL [...]
+D.UG.94.9 FFRENLAFPQ-WKAREFPSEQTPSRANS---------PTSRDLRIRG-----GD-NTSSETGAERQGT---------VSFNLPQITLWQRPVVTVKIGGQLKEALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYDQIPLEICGHKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALIEICSELEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLHEDFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEMIIYQYMDDLYVGSDLEIGQHRIKIEELRGHLLKWGFTTPDKKYQKEPPFLWMGYELHPDKWTVQPIHLPEKESWTVNDIQKLVGKLNWASQIYPGIKVRQLCKCLRGAKALTEVIPLTAEAEL [...]
+F1.BE.93. FFRENLAFQQ-GEARKFPSEQTRANS-----------PTSRELRVQR-----GD-NPLSEAGAERRGT--------VPSLSFPQITLWQRPLVTIKIGGQIKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVKQYDNILIEICGHKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPVSPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICLEMEKEGKISKIGPENPYNTPVFAIKKKDSSKWRKLVDFKELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFKKYTAFTIPSVNNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRMKNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLRWGFTTPDKKHQKEPPFLWMGHELHPDKWTVQPIQLPNKDSWTVNDIQKLVGKLNWASQIYPGIKVRPLCKLLRGAKALTDIVPLTAEAEL [...]
+F1.BR.93. FFRENLAFQQ-GEARKLHPEQARAVS-----------PASRELQVRG-----GD-NPISEAGAERRGT--------VPSLSFPQITLWQRPLVTIRVGGQLKEALLDTGADDTVLEDVNLPGKWKPKMIGGIGGFIKVKQYDSILIEICGHRAIGTVLVGPTPVNIIGRNMLTQIGCTLHFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICMEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTASTIPSTNNETPGVRYQYNVLPQGWKGSPAIFQYSMTKILDPFRAKNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLKWGLTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPDKDSWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLRGAKALTDIVPLTTEAEL [...]
+F1.FI.93. FFRENLAFQQ-GEARKFPSE?TRANS-----------PASREPRDQR-----RG-NSLSEAGAERRGT--------VPSLSFPQITLWQRPLVTIKIGGQLKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVKQYDHILIEICGHKAIGTVLVGPTPVNIVGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTDMEKEGKISRIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSVNNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRTRNPDIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPDKDSWTVDDIQKLVGKLNWASXIYPGIKVRQLCKLLRGAKALTDMVPLTAEANL [...]
+F1.FR.96. FFRENLAFQQ-GEARKFSSEQARANS-----------PASGELRVQR-----GN-NPLSEAGAEGRGT------GTVSSLSLPQITFWQRPLVTIRVGGQLREALLDTGADDTVLEDIDLPGKWKPKIIGGIGGFIKVKQYDQITIDICGHKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTDMEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSLNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRAKNPDIVIYQYMDDLYVGSDLELGQHRMKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKDSWTVNDIQKLVGKLNWASQIYPGIKIKQLCKLLRGAKALTDIVPLTEEAEL [...]
+F2.CM.02. FFRENLAFQQ-REAWEFHSEQTRANG-----------PASRGLRVRR-----RD-NSLPEAGAERQGT--------VSSLDFPQITLWQRPVVTIKVEGQLREALLDTGADDTVLEDINLSGKWKPRMIGGIGGFIKVRQYDQVPIEICGQKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRARNPEIVVYQYMDDLYVGSDLEIGQHRAKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQAIQLPNKSSWTVNDIQKLVGKLNWASQIYPGIRVKHLCKLLRGAKALTDVVPLTAEAEL [...]
+F2.CM.95. FFRENLAFQQ-GEARKFSSEQTRANS-----------PASRELRVRR-----GD-NPLPEAGAERRGT--------GSSLSFPQITLWQRPLVAIRVGGQLREALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVRQYDQIPIEICGQKAIGTVLVGPTPVNIIGRNLLTQLGCTLNFPISPIETVPVKLKPGMDGPRVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRAKNPEIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKSSWTVNDIQKLVGKLNWASQIYPGIRIKHLCRLLRGAKALTDVVPLTAEAEL [...]
+F2.CM.95b FFRENVAFQQ-GEARKFSSEQTRANS-----------PASRELRVRG-----GD-SSLPEAGAERQGT--------GSSLDFPQITLWQRPVVTIKVGGQLREALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVRQYDQVSIEICGQKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKRSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMIKILEPFRKENPEIVIYQYMDDLYVGSDLEIGQHRAKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQAIQLPDKSSWTVNDIQKLVGKLNWASQIYPGIRVKHLCKLLRGTKALTDVVPLTAEAEL [...]
+F2.CM.97. FFRENLAFQQ-GEAWKFSSEQTRANS-----------PASRKLRVRR-----RD-NSLPEAGAERQGN--------VPSLDFPQITLWQRPLVTIKVEGQLREALLDTGADDTVLEDINLSGKWKPRMIGGIGGFIKVRQYDQIPIEICGQKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISSIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKEFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRVKNPEIVIYQYMDDLYVGSDLEIGQHRTKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQAIQLPDKSSWTVNDIQKLVGKLNWASQIYPGIRVKHLCKLLRGAKALTDVVPLTVEAEL [...]
+G.BE.96.D FFRENLAFQQ-GEAREFPSEQARANS-----------PTRRELRVRG-----GD-SPLPEAGAEGKGT---------ISSIFPQITLWQRPIVKVRIGGQLIEALLDTGADDTVLEEIDLPGKWKPKMIGGIGGFIKVRQYDQILIEISGKRAIGTVLVGPTPINIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPRVKQWPLTEEKIKALTEICNEMEKEGKISKIGPENPYNTPIFAIKKKDSTRWRKLVDFRELNKRTQDFWEVPLGIPHPGGLKQKRSVTVLDVGDAYFSVPLDENFRKYTAFTIPSTNNETPGIRYQY--?PQGWKGSPAIFQSSMTKILEPFRTQNPEIVIYQYMDDLYVGSDLEIGQHRAKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPNKENWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLIRGAKALTDIVSMTAEAEM [...]
+G.KE.93.H F?RENLAFQQ-GEAREFSSEQARANS-----------PTRRELRVRR-----GN-SPLPEARAEGKGD---------TSLSFPQITLWQRPLVTVKIGGQLIEALLDTGADDTVLEDIKLPGKWKPKMIGGIGGFIKVRQYDQILIEISGKKAIGTVLVGPTPINIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEREGKISKIGPENPYNTPIFAIRKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDESFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPPIFQSSMTKILEPFRIKNPEMVIYQYMDDLYVGSDLEIGQHRAKIKELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKESWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGAKALTDIVPLTAEAEL [...]
+G.NG.92.9 FFRENLAFQQ-GEARKLSPEQDRANS-----------PTSRELRIRR-----GD-SPLPEAGAKGEGA---------ISLNFPQITLWQRPLVTVKIGGQLIEALLDTGADDTVLEGINLPGKWKPKMIGGIGGFIKVRQYDQILIEIGGKKAIGTVLVGPTPINIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPRVKQWPLTEEKIKALTEICKDMEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKRSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPSRTKNPEMVIYQYMDDLYVGSDLEIGQHRAKIEELREHLLKWGLTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKEDWTVNDIQKLVGKLNWASQIYPGIKVKHLCRLLRGAKALTDIVPLTAEAEM [...]
+G.PT.x.PT FFRENLAFQQ-GEAREFSPEQARANS-----------PTRRELRVRR-----GD-SPLPEARAEGQGV---------IPLNLPQITLWQRPLVTVRIGGQLIEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVRQYDQILIEICGKKAIGTVLVGPTPINIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEREGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPSGLKKKKSVTVLDVGDAYFSVPLDESFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRIKNPEIVIYQYMDDLYVGSDLEIGQHRAKIEELRKHLLNWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPDKESWTVNDIQKLVGKLNWASQIYPGIKIKQLCKLLRGAKALTDIVPLTAEAEL [...]
+H.BE.93.V FFRENLAFQQ-GKAREFPPEEARANS-----------PTSRELRVRR-----GD-HPLSEAGAERTGT----------SFNFPQITLWQRPIVTVKIEGQLKEALLDTGADDTVLEDINLPGKWKPKMIGGIGGFIKVRQYEQVAIEIFGKKAIGTVLVGPTPVNIIGRNILTQMGCTLNLPISPIETVPVTLKPGMDGPKVKQWPLTEEKIKALTEICLEMEKEGKISKIGPENPYNTPIFAIKKKNSTRWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVSVLDVGGAYFSVPLHEDFRKYTAFTIPSTNNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEVIIYQYMDDLYVGSDLEIGQHREKIEELRAHLLRWGFTTPDQKHQKEPPFLWMGYELHPDKWTVQPVKLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVKQLCXLLRGAKALTEIVPLTKEAEL [...]
+H.BE.93.W FFRENLAFQQ-REARKFSPEQARANS-----------PTSRELRVRG-----GD-DLLPEAGAEGQGT----------SLCFPQITLWQRPLVTVKIEGQLREALLDTGADDTVLEEINLLGRWKPKMIGGIGGFIKVRQYDQVAIEICGKKAIGTVLVGPTPVNIIGRNILTQIGCTLNFPISPIETVPVKLKPGMDGPRVKQWPLTEEKIKALTEICMEMEKEGKISKIGPENPYNTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVSVLDVGDAYFSVPLDKDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPEIIIYQYMDDLYVGSDLEIGQHRAKIEELRAHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPVKLPEKDSWTVNDIQKLVGKLNWASQIYPGIKVRQLCKLLRGAKALTDVVPLTKEAEL [...]
+H.CF.90.0 FFRENLAFQQ-REARKFSPEQARTNS-----------PTSRELRVRR-----GD-DPLSEAGAAEGQG---------TSLSFPQITLWQRPLVTVKIEGQLREALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYEQVAIEICGKKAIGTVLVGPTPVNIIGRNILTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISRIGPENPYSTPIFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVSVLDVGDAYFSVPLDKEFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILAPFREQNPEMVIYQYMDDLYVGSDLEIGQHRAKIEELRAHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQTVKLPEKDSWTVNDIQKLVGKLNWASQIYPNIKVKQLCKLLRGAKALTDIIPLTKEAEL [...]
+J.CD.97.J FFRESLAFQQ-GEARELSPEQARTNS-----------PTSRKLRVRG-----ED-NSLPETGTEEGTI----------SFSFPQITLWQRPLVTVRVGGQLKEALLDTGADDTVLEEIDLPGKWKPKMIGGIGGFIKVRQYNDILIEIEGKKAIGTVLVGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKIKQWPLTREKIEALTQICEEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRK?VDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLYEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRAKNPEVVIYQYMDDLYVGSDLEIEQHRKKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPVQLPEKESWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLRGTKALTDIVALTAEAEL [...]
+J.SE.93.S FFREDLAFQQ-REARELSPEQTRANS-----------PTSREPRAR------RG-DPLPETGAEGQGT---------VSSNFPQITLWQRPLVTIRIGGQLREALLDTGADDTVLEDIDLPRKWKPKMIGGIGGFIKVRQYNEVPIEIEGKKAIGTVLIGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKIKQWPLTEEKIKALTQICAEMEEEGKISRVGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLYEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILKPFRERNPEIVIYQYMDDLYVGSDLEIEQHRRKIKELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKEDWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLKGAKALTDIVPLTREAEL [...]
+J.SE.94.S FFREDLAFQQ-REAREFSPEQTRANS-----------PTSREPRVR------RG-DPLPETGAEGQGT---------VSSNFPQITLWQRPLVTIRIGGQLREALLDTGADDTVLEEIDLPGKWKPKMIGGIGGFIKVRQYNEVPIEIEGKKAIGTVLIGPTPVNIIGRNMLTQLGCTLNFPISPIETVPVKLKPGMDGPKIKQWPLTEEKIKALTQICAELEEEGKISRIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLYEDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILKPFRERNPEIVIYQYMDDLYVGSDLEIEQHRRKIKELREHLLKWGFYTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPEKEDWTVNDIQKLVGKLNWASQIYPGIKIKELCKLIRGAKALTDIVPLTREAEL [...]
+K.CD.97.E FFREVLASQQ-REARKFSSEQTRANS-----------PTSRELWVRG-----ED-NPLSETGNERSGT--------GSSFNFPQITLWQRPVVTVKVGGQLREALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYDQVCMEICGQKAIGTVLVGPTPVNIIGRNMLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWIKLVDFRELNKRTPDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQCSMTKILEPFRRKNPDMVLYQYMDDLYVGSDLEIGQHRAKIEELREHLLRWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPDKDSWTVNDIQKLVGKLNWASQIFPGIKVKQLCKLLRGVKALTDIVPLTAEAEL [...]
+K.CM.96.M FFRENLAFPQ-GEAREFSSEQTRANS-----------PTSRELRVRG-----GD-NPLSEAGDQRQGT--------EPSFNFPQITLWQRPIVTIKVGGQLREALLDTGADDTVLEEINLPGKWKPKMIGGIGGFIKVRQYDQVLIEICGQKAIGTVLVGPTPVNIIGRNLLTQIGCTLNFPISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALTEICTEMEKEGKISKIGPENPYNTPVFAIKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDKDFRKYTAFTIPSINNETPGVRYQYNVLPQGWKGSPAIFQHSMTKILEPFRIKNPEMVIYQYMDDLYVGSDLEIGQPRTKIEELREHLLKWGFTTPDKKHQKEPPFLWMGYELHPDKWTVQPIQLPDKDSWTVNDIQKLVGKLNWASQIYPGIKVKQLCKLLRGVKALTDIVPLTAEAEL [...]
diff --git a/src/main/resources/examples/Ribosomal_L5_PF00673/alignment b/src/main/resources/examples/Ribosomal_L5_PF00673/alignment
new file mode 100755
index 0000000..89347db
--- /dev/null
+++ b/src/main/resources/examples/Ribosomal_L5_PF00673/alignment
@@ -0,0 +1,23 @@
+21 113
+RL5X_THETH PIGLRVTLRRDRMWIFLEKLLNVALPRIRDFRGLN--PNSFDGRGNYNLGLREQLIFPEITYDMVDALRGMDIAVVT------TAETDEE----------ARALLELLGFPFR
+RL5_THEMA PIGLKVTLRGARMYNFLYKLINIVLPKVRDFRGLD--PNSFDGRGNYSFGLSEQLVFPELNPDEVRRIQGMDITIVT------TAKTDQE----------ARRLLELFGMPFK
+RL5_MYCCA AIGAKVTLRGKKMYDFLDKLINVALPRVRDFRGVS--KTSFDGFGNFYTGIKEQIIFPEVDHDKVIRLRGMDITIVT------SAKTNKE----------AFALLQKIGMPFE
+RK5_CYAPA PIGVMVTLRGDYMYAFLDRLINLSLPRIRDFRGIT--AKSFDGRGNYNLGLKEQLIFPEVDYDGIEQIRGMDISIVT------TAKTDQE----------GLALLKSLGMPFA
+RL5_MICLU PIGTHATLRGDRMWEFLDRLVTLPLPRIRDFRGLS--DRQFDGNGNYTFGLSEQTVFHEIDQDKIDRVRGMDITVVT------TAKNDDE----------GRALLKALGFPFK
+RL5_BUCAK PIGCKVTLRGERMWEFFERLISIAVPRIRDFRGLS--AKSFDGRGNYSMGVREQIIFPEIDYDKVDRVRGLDITITT------TAKSDDE----------GRALLAAFNFPFR
+RL5_MYCGE LIGCKVTLRNKKMWSFLEKLIYIALPRVRDFRGLS--LRSFDGKGNYTIGIKEQIIFPEIVYDDIKRIRGFDITIVT------STNKDSE----------ALALLRALKMPFV
+RK5_EUGGR PVGMFLTLRSEKMYSFLDRLINLSLPRIRDFQGIN--KNCFDGSGNFSFGLSEQSMFPEINFDKMIKVQGLNITIVT------TAETNQE----------AFFLLKELGIPFR
+RK5_ODOSI ELGLTVTLRGSKMYSFLTKLIFFTFAQIRDFRGLS--VRSFDKAGNYTLGLKEQLIFPEIDYDDVDQTQGFSITLVF------SSTAPKSRSKTMDRVLNGMVLFKFLRFPLN
+RL5_SULAC PIGVKATLRRQAAVEFLKKVL-----PAVNFRLK---QSSFDNYGNVSFGIAEHVLIPGTRYDPEIGIFGMDVAITLVRPGYRTMKRKRKKA----SIPRRHRVTKEEAINFM
+RL5_METVA PIGLKVTLRGKNAEEFLENAF-----VAFKVSGKVLYASSFDKVGNFSFGVPEHIDFPGQKYDPTVGIYGMDICVTFEKPGYRVKSRKLKRS----HIPAKHLVKKEEAIEYI
+RL5_METJA PIGLKVTLRGKKAEEFLKNAF-----EAFQKEGKKLYDYSFDDYGNFSFGIHEHIDFPGQKYDPMIGIFGMDVCVTLERPGFRVKRRKRCRA----KIPRRHRLTREEAIEFI
+RL5_HALMA PIGAKVTLRDEMAEEFLQTAL-----PLAELATS-----QFDDTGNFSFGVEEHTEFPSQEYDPSIGIYGLDVTVNLVRPGYRVAKRDKASR----SIPTKHRLNPADAVAFI
+RL11_YEAST KIAVHVTVRGPKAEEILERGL-----KVKEYQLR---DRNFSATGNFGFGIDEHIDL-GIKYDPSIGIFGMDFYVVMNRPGARVTRRKRCKG----TVGNSHKTTKEDTVSWF
+RL11_SCHPO KIACHVTVRGPKAEEILERGL-----KVKEYELK---KRNFSATGNFGFGIQEHIDL-GIKYDPSIGIYGMDFYVVMDRPGMRVARRKAQRG----RVGYTHKINAEDTINWF
+RL11_LEICH KIAVHCTVRGKKAEELLEKGL-----KVKEFELK---SYNFSDTGSFGFGIDEHIDL-GIKYDPSTGIYGMDFYVVLGRRGERVAHRKRKCS----RVGHSHHVTKEEAMKWF
+RL11_DROME KIAVHCTVRGAKAEEILERGL-----KVREYELR---RENFSSTGNFGFGIQEHIDL-GIKYDPSIGIYGLDFYVVLGRPGYNVNHRKRKSG----TVGFQHRLTKEDAMKWF
+RL11_HUMAN KIAVHCTVRGAKAEEILEKGL-----KVREYELR---KNNFSDTGNFGFGIQEHIDL-GIKYDPSIGIYGLDFYVVLGRPGFSIADKKRRTG----CIGAKHRISKEEAMRWF
+RL11_CHLRE KISCYVTVRGEKAYDLVKRGL-----AVKEFELI---RKNFSDTGNFGFGIQEHIDL-GLKYDPSTGIYGMDFYVCLERRGYRVARRRKQKA----HVGVKHKVTKEDAIKWF
+R111_ARATH KIACYVTVRGEKAMQLLESGL-----KVKEYELL---RRNFSDTGCFGFGIQEHIDL-GIKYDPSTGIYGMDFYVVLERPGYRVARRRRCKA----RVGIQHRVTKDDAMKWF
+RL11_TETTH KMAVHVTIRGDKARDILTRGL-----KVKEMELR---KKNFSNTGNFGFGIQEHIDL-GMKYDPSTGIFGMDFYVVLERPGTRVARRRRATS----RVGNNQMISKEECINWF
+
diff --git a/src/main/resources/examples/Ribosomal_L5_PF00673/tree b/src/main/resources/examples/Ribosomal_L5_PF00673/tree
new file mode 100755
index 0000000..6c892ba
--- /dev/null
+++ b/src/main/resources/examples/Ribosomal_L5_PF00673/tree
@@ -0,0 +1,9 @@
+(((((((((((RL11_HUMAN:0.1551800,RL11_DROME:0.0854900):0.0882500,(((RL11_YEAST:
+0.1429600,RL11_SCHPO:0.0875000):0.0873900,RL11_TETTH:0.2339800):0.0652200,
+(R111_ARATH:0.0698900,RL11_CHLRE:0.1904000):0.0941200):0.0839000):0.0287300,
+RL11_LEICH:0.1414200):0.4521600,((RL5_METJA:0.1374100,RL5_METVA:0.2718300)
+:0.1528200,RL5_SULAC:0.3595300):0.0839100):0.0845700,RL5_HALMA:0.3691600)
+:0.8932200,RL5_MYCCA:0.1851800):0.1082600,RL5_MYCGE:0.2360800):0.0507100,
+RK5_ODOSI:0.6278600):0.0727300,(RL5_BUCAK:0.1570200,RL5_MICLU:0.2811600)
+:0.1017400):0.0420600,(RK5_CYAPA:0.1638300,RK5_EUGGR:0.4177100):0.0974800)
+:0.0807800,RL5X_THETH:0.2117200,RL5_THEMA:0.2253200);
diff --git a/src/main/resources/filecluster8.conf.template b/src/main/resources/filecluster8.conf.template
new file mode 100755
index 0000000..9a90c18
--- /dev/null
+++ b/src/main/resources/filecluster8.conf.template
@@ -0,0 +1,8 @@
+compute-node-1-0
+compute-node-1-1
+compute-node-1-2
+compute-node-1-3
+compute-node-1-4
+compute-node-1-5
+compute-node-1-6
+compute-node-1-7
diff --git a/src/main/resources/machines b/src/main/resources/machines
new file mode 100755
index 0000000..2fbb50c
--- /dev/null
+++ b/src/main/resources/machines
@@ -0,0 +1 @@
+localhost
diff --git a/src/main/resources/models/FLU b/src/main/resources/models/FLU
new file mode 100755
index 0000000..4594d9f
--- /dev/null
+++ b/src/main/resources/models/FLU
@@ -0,0 +1,22 @@
+
+0.138658764751059
+0.0533665787145181 0.161000889039552
+0.584852305649886 0.00677184253227681 7.73739287051356
+0.0264470951166826 0.16720700818221 1.30249856764315e-005 0.014132062548787
+0.353753981649393 3.29271694159791 0.530642655337477 0.145469388422239 0.00254733397966779
+1.4842345032161 0.124897616909194 0.0616521921873234 5.37051127867923 3.91106992668137e-011 1.19562912226203
+1.13231312248046 1.19062446519178 0.322524647863997 1.93483278448943 0.116941459124876 0.108051341246072 1.59309882471598
+0.214757862168721 1.87956993845887 1.38709603234116 0.887570549414031 0.0218446166959521 5.33031341222104 0.256491863423002 0.0587745274250666
+0.149926734229061 0.246117171830255 0.21857197541607 0.0140859174993809 0.00111215807314139 0.0288399502994541 0.0142107118685268 1.62662283098296e-005 0.243190142026506
+0.0231169515264061 0.296045557460629 0.000835873174542931 0.00573068208525287 0.00561362724916376 1.02036695531654 0.016499535540562 0.00651622937676521 0.321611693603646 3.51207228207807
+0.474333610192982 15.3000966197798 2.6468479652886 0.290042980143818 3.83228119049152e-006 2.559587177122 3.88148880863814 0.264148929349066 0.347302791211758 0.227707997165566 0.129223639195248
+0.0587454231508643 0.890162345593224 0.00525168778853117 0.0417629637305017 0.111457310321926 0.190259181297527 0.313974351356074 0.00150046692269255 0.00127350890508147 9.01795420287895 6.74693648486614 1.33129161941264
+0.0804909094320368 0.0160550314767596 0.000836445615590923 1.0600102849456e-006 0.10405366623526 0.0326806570137471 0.00100350082518749 0.00123664495412902 0.119028506158521 1.46335727834648 2.98680003596399 0.319895904499071 0.279910508981581
+0.659311477863896 0.154027179890711 0.0364417719063219 0.188539456415654 1.59312060172652e-013 0.712769599068934 0.319558828428154 0.0386317614553493 0.924466914225534 0.0805433268150369 0.634308520867322 0.195750631825315 0.0568693216513547 0.0071324304661639
+3.01134451903854 0.950138410087378 3.88131053061457 0.338372183381345 0.336263344504404 0.487822498528951 0.307140298031341 1.58564657669139 0.580704249811294 0.290381075260226 0.570766693213698 0.283807671568883 0.00702658828739369 0.996685669575839 2.08738534433198
+5.4182981753166 0.183076905018197 2.14033231636063 0.135481232622983 0.011975265782196 0.60234096342392 0.2801248951174 0.0188080299490973 0.368713573381758 2.90405228596936 0.0449263566753846 1.52696419998775 2.03151132062208 0.000134906239484254 0.54225109402693 2.2068599339404
+0.195966354027106 1.36942940801512 0.000536284040016542 1.4893873721753e-005 0.0941066800969967 0.0440205200833047 0.155245492137294 0.196486447133033 0.0223729191088972 0.0321321499585514 0.431277662888057 4.97641445484395e-005 0.0704600385245663 0.814753093809928 0.000431020702277328 0.0998357527014247 0.207066205546908
+0.0182892882245349 0.0998554972524385 0.373101926513925 0.525398542949365 0.601692431136271 0.0722059354079545 0.104092870343653 0.0748149970972622 6.44895444648517 0.273934263183281 0.340058468374384 0.0124162215506117 0.874272174533394 5.39392424532822 0.000182294881489116 0.392552239890831 0.124898020409882 0.42775543040588
+3.53200526987468 0.103964386383736 0.0102575172450253 0.297123975243582 0.0549045639492389 0.406697814049488 0.285047948309311 0.337229618868315 0.0986313546653266 14.3940521944257 0.890598579382591 0.0731279296372675 4.90484223478739 0.592587985458668 0.0589719751511691 0.0882564232979724 0.654109108255219 0.256900461407996 0.167581646770807
+
+0.0470718 0.0509102 0.0742143 0.0478596 0.0250216 0.0333036 0.0545874 0.0763734 0.0199642 0.0671336 0.0714981 0.0567845 0.0181507 0.0304961 0.0506561 0.0884091 0.0743386 0.0185237 0.0314741 0.0632292
diff --git a/src/main/resources/mpj.tar.gz b/src/main/resources/mpj.tar.gz
new file mode 100755
index 0000000..46151f6
Binary files /dev/null and b/src/main/resources/mpj.tar.gz differ
diff --git a/src/main/resources/prottest.properties b/src/main/resources/prottest.properties
new file mode 100755
index 0000000..2571159
--- /dev/null
+++ b/src/main/resources/prottest.properties
@@ -0,0 +1,102 @@
+# -------------------------------------------------------------------
+# Likelihood analyzer
+#
+# 'phyml' PhyML is the only supported stable analyzer right now.
+# 'raxml' RAxML is not supported yet, but it is in development stage.
+# -------------------------------------------------------------------
+analyzer=phyml
+
+# ------------------------------------------------------------------
+# Phyml Binaries path
+#
+# By default, ProtTest will search for the PhyML executables in
+# $PROTTEST_HOME/bin. Users can define a different path, wether
+# absolute (starting with '/' or 'C:\\') or relative to
+# $PROTTEST_HOME directory using exe-dir property.
+#
+# If an usable version of PhyML is installed system-wide
+# (for example, from the Ubuntu/Debian repositories),
+# the user can set 'global-phyml-exe' property to true
+# and jModelTest will use the global binary instead of
+# local ones.
+# ------------------------------------------------------------------
+global-phyml-exe = false
+exe-dir = bin
+
+# -------------------------------------------------------------------
+# Use --no-memory-check argument (only for PhyML)
+#
+# Latest versions of PhyML support this argument. Without this
+# argument, huge input alignments could crash during the model
+# optimization waiting for the user to check the memory requirements.
+# However, using this argument the user should be aware of the memory
+# that the model optimization process will require in each node
+# (number of processes per node times the memory requirement per
+# single optimization. If not, a single node could run out of memory.
+# -------------------------------------------------------------------
+no-memory-check=yes
+
+# -------------------------------------------------------------------
+# Parallel strategy
+#
+# if using MPJExpress you can choose the parallel strategy
+# to follow:
+#
+# 'static' by default. It distributes models amongst processors in
+# a static way. This is the best choice for a little number
+# of processors.
+#
+# 'dynamic' It does a better distribution of the computation load,
+# but the root process doesn't compute any likelihood data, so it will
+# be one processor less available to compute.
+#
+# 'dynamic_improved' Like the dynamic distribution, but there will be
+# an extra thread to do the distribution, so the whole group of
+# processors will compute the likelihood data.
+#
+# 'hybrid' An hybrid distribution coupling a distributed memory
+# implementation of ProtTest-HPC with a threaded version of the
+# likelihood computation.
+# -------------------------------------------------------------------
+parallel_strategy=dynamic_improved
+
+# -------------------------------------------------------------------
+# Thread Scheduling
+#
+# Uncomment line below to schedule openMP threads among the machine
+# cores.
+#
+# number_of_threads declares the maximum of process elements which
+# can be used from each node. If it is commented, the maximum number
+# of processors available will be used.
+#
+# -------------------------------------------------------------------
+#phyml_thread_scheduling=true
+#number_of_threads=2
+
+# -------------------------------------------------------------------
+# Snapshot directory
+#
+# ProtTestHPC provides fault-tolerance adding checkpointing support.
+# This is, being capable of resume a stopped execution just executing
+# the application again with the same parameters.
+#
+# The snapshot directory will be the place where the temporary status
+# files will be saved and loaded.
+# -------------------------------------------------------------------
+snapshot_dir=snapshot/
+
+# -------------------------------------------------------------------
+# Logging directory
+#
+# ProtTestHPC allows automatic logging for the user activity. Every
+# execution generates a log file.
+#
+# Log level is configurable:
+# 'info' Only general information messages are logged (default)
+# 'fine' General debug information is also logged
+# 'finer' More complex debug information is logged
+# 'finest' All activity is tracked
+# -------------------------------------------------------------------
+log_dir=log/
+log_level=info
diff --git a/src/main/resources/runProtTestHPC.sh b/src/main/resources/runProtTestHPC.sh
new file mode 100755
index 0000000..5d08a4a
--- /dev/null
+++ b/src/main/resources/runProtTestHPC.sh
@@ -0,0 +1,4 @@
+export MPJ_HOME=$PWD/mpj
+export NP=$1
+shift
+$MPJ_HOME/bin/mpjrun.sh -dev niodev -wdir $PWD/ -np $NP -jar prottest-3.4.jar $*
diff --git a/src/main/resources/runXProtTestHPC.bat b/src/main/resources/runXProtTestHPC.bat
new file mode 100755
index 0000000..e1bd4bf
--- /dev/null
+++ b/src/main/resources/runXProtTestHPC.bat
@@ -0,0 +1 @@
+java -cp prottest-3.4.jar es.uvigo.darwin.xprottest.XProtTestApp
diff --git a/src/main/resources/runXProtTestHPC.sh b/src/main/resources/runXProtTestHPC.sh
new file mode 100755
index 0000000..e1bd4bf
--- /dev/null
+++ b/src/main/resources/runXProtTestHPC.sh
@@ -0,0 +1 @@
+java -cp prottest-3.4.jar es.uvigo.darwin.xprottest.XProtTestApp
diff --git a/src/test/resources/VertCOII.trees b/src/test/resources/VertCOII.trees
new file mode 100755
index 0000000..50c14da
--- /dev/null
+++ b/src/test/resources/VertCOII.trees
@@ -0,0 +1,8 @@
+(1,2,(3,((6,7),(4,5)))) [0.707865];
+(1,(2,3),((6,7),(4,5))) [0.132335];
+(1,2,(3,(7,(6,(4,5))))) [0.082397];
+(1,(2,3),(7,(6,(4,5)))) [0.051186];
+(1,3,(2,((6,7),(4,5)))) [0.013733];
+(1,2,(3,(6,(7,(4,5))))) [0.007491];
+(1,3,(2,(7,(6,(4,5))))) [0.003745];
+(1,(2,3),(6,(7,(4,5)))) [0.001248];
diff --git a/src/test/resources/VertCOII.trprobs b/src/test/resources/VertCOII.trprobs
new file mode 100755
index 0000000..2103126
--- /dev/null
+++ b/src/test/resources/VertCOII.trprobs
@@ -0,0 +1,26 @@
+#NEXUS
+
+[ID: 0256489503]
+[This file contains the trees that were found during the MCMC
+search, sorted by posterior probability. "p" indicates the
+posterior probability of the tree whereas "P" indicates the
+cumulative posterior probability.]
+
+begin trees;
+ translate
+ 1 Trout,
+ 2 Frog,
+ 3 Chicken,
+ 4 Rat,
+ 5 Mouse,
+ 6 Cow,
+ 7 Whale;
+ tree tree_1 [p = 0.708, P = 0.708] = [&W 0.707865] (1,2,(3,((6,7),(4,5))));
+ tree tree_2 [p = 0.132, P = 0.840] = [&W 0.132335] (1,(2,3),((6,7),(4,5)));
+ tree tree_3 [p = 0.082, P = 0.923] = [&W 0.082397] (1,2,(3,(7,(6,(4,5)))));
+ tree tree_4 [p = 0.051, P = 0.974] = [&W 0.051186] (1,(2,3),(7,(6,(4,5))));
+ tree tree_5 [p = 0.014, P = 0.988] = [&W 0.013733] (1,3,(2,((6,7),(4,5))));
+ tree tree_6 [p = 0.007, P = 0.995] = [&W 0.007491] (1,2,(3,(6,(7,(4,5)))));
+ tree tree_7 [p = 0.004, P = 0.999] = [&W 0.003745] (1,3,(2,(7,(6,(4,5)))));
+ tree tree_8 [p = 0.001, P = 1.000] = [&W 0.001248] (1,(2,3),(6,(7,(4,5))));
+end;
diff --git a/src/test/resources/testConsensus.sh b/src/test/resources/testConsensus.sh
new file mode 100755
index 0000000..212dd06
--- /dev/null
+++ b/src/test/resources/testConsensus.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Usage:
+# sh testConsensus.sh FILENAME THRESHOLD
+#
+
+java -cp prottest-hpc.jar es.uvigo.darwin.prottest.consensus.Consensus $1 $2
diff --git a/src/test/resources/treeweights b/src/test/resources/treeweights
new file mode 100755
index 0000000..9fb98a4
--- /dev/null
+++ b/src/test/resources/treeweights
@@ -0,0 +1,25 @@
+((((((seq05:0.0077052441,(seq02:0.0111145304,(seq04:0.0020223938,seq03:0.0010157336):0.0075797472):0.0007496592):0.0171711541,seq01:0.0215304231):0.0092866832,seq06:0.0234123934):0.0839055134,seq10:0.2162744040):0.0678883105,seq07:0.0045842099):0.0033768164,seq09:0.0052205651,seq08:0.0060496451)[0.6044448518027933];
+((((((seq05:0.0077019984,(seq02:0.0111043579,(seq04:0.0020189219,seq03:0.0010140227):0.0075786575):0.0007397696):0.0171540818,seq01:0.0216147652):0.0093065511,seq06:0.0234637037):0.0850988342,seq10:0.2198141537):0.0681983513,seq07:0.0045539427):0.0033889360,seq09:0.0052200230,seq08:0.0060390825)[0.3122925586551285];
+(((((((seq04:0.0020072367,seq03:0.0010099963):0.0068295666,(seq02:0.0110746329,seq05:0.0082779326):0.0007704663):0.0172809633,seq01:0.0212924422):0.0076864019,seq06:0.0235197630):0.0798131754,seq10:0.2041408437):0.0647571261,seq07:0.0046699330):0.0032809253,seq09:0.0051113643,seq08:0.0060034254)[0.04015353319722536];
+((((((((seq04:0.0020263474,seq03:0.0010154378):0.0075716365,seq02:0.0111432259):0.0007110708,seq05:0.0077410097):0.0172619298,seq01:0.0215902855):0.0096043288,seq06:0.0231079057):0.0840300827,seq10:0.2149918557):0.0678403508,seq07:0.0046391422):0.0033165272,seq09:0.0052592579,seq08:0.0060534982)[0.027155794158633294];
+((((((seq05:0.0077465523,(seq02:0.0111430058,(seq04:0.0020244012,seq03:0.0010144860):0.0075765991):0.0006962556):0.0172655570,seq01:0.0216940056):0.0096262212,seq06:0.0231716075):0.0853867698,seq10:0.2189915255):0.0681779032,seq07:0.0046008122):0.0033351156,seq09:0.0052648635,seq08:0.0060457251)[0.014153903283194807];
+(((((((seq04:0.0020077813,seq03:0.0010087652):0.0068387708,(seq05:0.0082749335,seq02:0.0110769293):0.0007408180):0.0173425670,seq01:0.0212708925):0.0080434376,seq06:0.0232204283):0.0798564918,seq10:0.2032317054):0.0647363574,seq07:0.0047183263):0.0032403931,seq09:0.0051361082,seq08:0.0060009611)[0.001799358902984481];
+(((((((seq04:0.0020066427,seq03:0.0010057269):0.0066005758,(seq02:0.0109545639,seq05:0.0082288953):0.0009075007):0.0167646862,seq01:0.0201471031):0.0079147042,seq06:0.0220762149):0.0625656035,seq10:0.1496005616):0.0604749727,seq07:0.0052497997):0.0028439565,seq09:0.0050053208,seq08:0.0060419296)[3.8246098397130133E-14];
+(((((((seq04:0.0020089207,seq03:0.0010063352):0.0066175633,(seq05:0.0082360811,seq02:0.0109689813):0.0008858127):0.0168244215,seq01:0.0201504467):0.0081607986,seq06:0.0219457398):0.0626475214,seq10:0.1495585895):0.0604826110,seq07:0.0053271195):0.0028070525,seq09:0.0050167148,seq08:0.0060477153)[2.0605471459815532E-15];
+(((((((seq04:0.0019580958,seq03:0.0009758187):0.0066926874,(seq02:0.0110554554,seq05:0.0077880968):0.0008423307):0.0161959005,seq01:0.0211843004):0.0082359303,seq06:0.0215600694):0.0766275178,seq10:0.2056305491):0.0688321995,seq07:0.0046770599):0.0031912170,seq09:0.0053392070,seq08:0.0059538554)[6.541197018992573E-54];
+((((((seq05:0.0073248171,(seq02:0.0108517006,(seq04:0.0019554045,seq03:0.0009739229):0.0072029740):0.0008294110):0.0162862942,seq01:0.0207057765):0.0094779049,seq06:0.0212873196):0.0784846448,seq10:0.2113501151):0.0692184451,seq07:0.0046440279):0.0032081617,seq09:0.0053646732,seq08:0.0059524572)[4.219979115694137E-54];
+(((((((seq04:0.0019384486,seq03:0.0009700175):0.0065709567,(seq02:0.0109362246,seq05:0.0076986496):0.0008852850):0.0159233437,seq01:0.0207508000):0.0078865942,seq06:0.0213188047):0.0736050585,seq10:0.1962459426):0.0657553238,seq07:0.0047122770):0.0031519672,seq09:0.0051949011,seq08:0.0058870096)[3.533345910935345E-55];
+((((((seq05:0.0075146892,(seq02:0.0112664485,(seq04:0.0020281975,seq03:0.0010169502):0.0074765820):0.0009128315):0.0166409570,seq01:0.0214075315):0.0090209014,seq06:0.0228607022):0.0784238564,seq10:0.2087226511):0.0706491533,seq07:0.0050107284):0.0032010821,seq09:0.0053195750,seq08:0.0061319835)[2.0035396837899554E-57];
+((((((seq05:0.0075041280,(seq02:0.0112571504,(seq04:0.0020247149,seq03:0.0010151551):0.0074778361):0.0009104218):0.0166371342,seq01:0.0215129779):0.0090366986,seq06:0.0229536870):0.0800606769,seq10:0.2140114474):0.0712798148,seq07:0.0049744579):0.0032156966,seq09:0.0053289942,seq08:0.0061227020)[1.2844176925995497E-57];
+(((((((seq04:0.0020093312,seq03:0.0010096022):0.0069365358,(seq02:0.0113749375,seq05:0.0079949171):0.0007923111):0.0166256990,seq01:0.0213384957):0.0075699254,seq06:0.0229288389):0.0759084974,seq10:0.2012177218):0.0683135220,seq07:0.0050070486):0.0031722589,seq09:0.0052172273,seq08:0.0060826276)[1.2547050827258674E-58];
+((((((seq05:0.0074449819,(seq02:0.0111012907,(seq04:0.0020270019,seq03:0.0009973045):0.0073888637):0.0010896807):0.0164691675,seq01:0.0205783703):0.0091903908,seq06:0.0220758046):0.0677359174,seq10:0.1776723548):0.0655628028,seq07:0.0064365161):0.0016679435,seq09:0.0051508249,seq08:0.0060470243)[2.2832403590625373E-59];
+((((((seq05:0.0074369935,(seq02:0.0110945016,(seq04:0.0020252484,seq03:0.0009961127):0.0073869722):0.0010870647):0.0164578918,seq01:0.0205916388):0.0091792951,seq06:0.0221071518):0.0681371054,seq10:0.1791495483):0.0656647816,seq07:0.0064641602):0.0016290156,seq09:0.0051504246,seq08:0.0060391689)[1.016236039095543E-59];
+((((((seq05:0.0074283331,(seq02:0.0110219182,(seq04:0.0020131047,seq03:0.0009948961):0.0073286220):0.0010708984):0.0163947221,seq01:0.0203080535):0.0090280585,seq06:0.0218301832):0.0658207365,seq10:0.1728346403):0.0645232415,seq07:0.0062913235):0.0017849410,seq09:0.0050864725,seq08:0.0060272634)[1.7726413761399364E-60];
+(((((((seq04:0.0019341546,seq03:0.0009675243):0.0064546901,(seq02:0.0108336211,seq05:0.0076303300):0.0009293048):0.0153954205,seq01:0.0197297019):0.0078691272,seq06:0.0204324657):0.0578353178,seq10:0.1402602763):0.0588056578,seq07:0.0051935077):0.0027894076,seq09:0.0049312950,seq08:0.0058474190)[2.8550135068966413E-69];
+((((((seq05:0.0074050367,(seq02:0.0110047986,(seq04:0.0020212650,seq03:0.0010050635):0.0072993043):0.0011436254):0.0162097019,seq01:0.0198985425):0.0090719450,seq06:0.0212066823):0.0591739431,seq10:0.1426713016):0.0603002256,seq07:0.0060650127):0.0021053210,seq09:0.0050434256,seq08:0.0060928522)[2.1250209625413596E-70];
+(((((((seq04:0.0020039070,seq03:0.0010035673):0.0067284599,(seq02:0.0112377794,seq05:0.0079095215):0.0009235712):0.0160433685,seq01:0.0203392313):0.0077845136,seq06:0.0215830772):0.0602238630,seq10:0.1443002872):0.0611760826,seq07:0.0054445870):0.0027871862,seq09:0.0050528257,seq08:0.0060518337)[2.0740056894741138E-72];
+((((((seq05:0.0074821173,(seq02:0.0113030757,(seq04:0.0020267279,seq03:0.0010015074):0.0072204442):0.0011071576):0.0160962400,seq01:0.0208426467):0.0090799287,seq06:0.0216939651):0.0660874416,seq10:0.1740781555):0.0667885362,seq07:0.0063431934):0.0018941720,seq09:0.0052215599,seq08:0.0060441980)[5.8586243815199E-104];
+((((((seq05:0.0074681896,(seq02:0.0112904172,(seq04:0.0020242012,seq03:0.0009999433):0.0072187543):0.0011055276):0.0160814837,seq01:0.0208530480):0.0090857063,seq06:0.0217065056):0.0664546405,seq10:0.1755240452):0.0669507862,seq07:0.0063586917):0.0018650513,seq09:0.0052221492,seq08:0.0060340033)[2.757500983613677E-104];
+((((((seq05:0.0074620947,(seq02:0.0112215490,(seq04:0.0020114478,seq03:0.0009972352):0.0071500887):0.0010818454):0.0159899536,seq01:0.0205670556):0.0088603188,seq06:0.0214990066):0.0642369545,seq10:0.1692837552):0.0656716571,seq07:0.0062379978):0.0019634889,seq09:0.0051485359,seq08:0.0060212578)[3.908094526533152E-105];
+((((((seq05:0.0074178676,(seq02:0.0111284547,(seq04:0.0020057572,seq03:0.0009990083):0.0070451850):0.0011428865):0.0157078653,seq01:0.0200370209):0.0087090219,seq06:0.0209345894):0.0581338862,seq10:0.1391897197):0.0602068296,seq07:0.0060543462):0.0021623486,seq09:0.0050467770,seq08:0.0060316591)[6.962968867234838E-116];
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/prottest.git
More information about the debian-med-commit
mailing list