001/*
002 * Copyright (c) 2004-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.cipres.kepler;
031
032// Ptolemy package
033import org.cipres.CipresIDL.api1.DataMatrix;
034import org.cipres.CipresIDL.api1.Tree;
035import org.cipres.CipresIDL.api1.TreeImprove;
036import org.cipres.CipresIDL.api1.TreeScore;
037import org.cipres.helpers.CipresRegistry;
038import org.cipres.helpers.CipresServiceDialog;
039import org.cipres.helpers.RegistryEntryWrapper;
040
041import ptolemy.actor.TypedAtomicActor;
042import ptolemy.actor.TypedIOPort;
043import ptolemy.data.ObjectToken;
044import ptolemy.data.type.BaseType;
045import ptolemy.kernel.CompositeEntity;
046import ptolemy.kernel.util.IllegalActionException;
047import ptolemy.kernel.util.NameDuplicationException;
048
049//////////////////////////////////////////////////////////////////////////
050//// TreeImprover
051/**
052 * The TreeImprover actor improves a phylogenetic tree according to the settings
053 * configured by the user through the GUIGen interface. This actor uses the
054 * TreeImprove CORBA service provided by the CIPRes registry.
055 * 
056 * @author Zhijie Guan
057 * @version $Id: TreeImprover.java 24234 2010-05-06 05:21:26Z welker $
058 */
059
060public class TreeImprover extends TypedAtomicActor {
061
062        /**
063         * Construct a TreeImprover actor with the given container and name.
064         * 
065         * @param container
066         *            The container.
067         * @param name
068         *            The name of this actor.
069         * @exception IllegalActionException
070         *                If the entity cannot be contained by the proposed
071         *                container.
072         * @exception NameDuplicationException
073         *                If the container already has an actor with this name.
074         */
075
076        public TreeImprover(CompositeEntity container, String name)
077                        throws NameDuplicationException, IllegalActionException {
078                super(container, name);
079
080                // construct the input port inputMatrix
081                inputMatrix = new TypedIOPort(this, "inputMatrix", true, false);
082                inputMatrix.setDisplayName("Original Data Matrix");
083                inputMatrix.setTypeEquals(BaseType.GENERAL);
084
085                // construct the input port inputTree
086                inputTree = new TypedIOPort(this, "inputTree", true, false);
087                inputTree.setDisplayName("Original Tree");
088                inputTree.setTypeEquals(BaseType.GENERAL);
089
090                // construct the output port outputTree
091                outputTree = new TypedIOPort(this, "outputTree", false, true);
092                outputTree.setDisplayName("Improved Tree");
093                // Set the type constraint.
094                outputTree.setTypeEquals(BaseType.GENERAL);
095
096                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
097                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
098                                + "</svg>\n");
099
100        }
101
102        // /////////////////////////////////////////////////////////////////
103        // // ports and parameters ////
104        /**
105         * A tree in CIPRes tree data structure is passed to the TreeImprover actor
106         * through this input port. This port is an input port of type GENERAL.
107         */
108        public TypedIOPort inputTree = null;
109
110        /**
111         * A matrix containing the characters information of the analyzed taxa is
112         * passed to the TreeImprover actor through this input port. This port is an
113         * input port of type GENERAL.
114         */
115        public TypedIOPort inputMatrix = null;
116
117        /**
118         * The improved tree is sent through this output port. This port is an
119         * output port of type GENERAL.
120         */
121        public TypedIOPort outputTree = null;
122
123        // /////////////////////////////////////////////////////////////////
124        // // functional variables ////
125        // Cipres tree data structure
126        private org.cipres.CipresIDL.api1.Tree _finalTree = null;
127
128        // /////////////////////////////////////////////////////////////////
129        // // public methods ////
130
131        /**
132         * Improve a tree and send the final tree to the output port.
133         * 
134         * @exception IllegalActionException
135         *                If it is thrown by the send() method sending out the
136         *                token.
137         */
138        public void fire() throws IllegalActionException {
139                super.fire();
140                if ((inputTree.hasToken(0)) && (inputMatrix.hasToken(0))) {
141
142                        RegistryEntryWrapper treeImproverWrapper = null;
143                        try {
144                                // get the TreeImprove CORBA service
145                                treeImproverWrapper = CipresRegistry.getCipresServiceWrapper(
146                                                TreeImprove.class, null, null);
147                                // with GUI version
148                                CipresServiceDialog dialog = treeImproverWrapper
149                                                .getServiceDialog(null);
150                                int status = dialog.showAndInitialize();
151                                if (status == CipresServiceDialog.OK) {
152                                        TreeImprove service = (TreeImprove) treeImproverWrapper
153                                                        .getService();
154                                        // set the tree and matrix for the TreeImprove service
155                                        service.setTree((Tree) ((ObjectToken) inputTree.get(0))
156                                                        .getValue());
157                                        service.setMatrix((DataMatrix) ((ObjectToken) inputMatrix
158                                                        .get(0)).getValue());
159                                        _finalTree = service.improveTree(null);
160
161                                        // fix _finalTree. This section should be replaced once the
162                                        // fix_tree is open to public access
163                                        _finalTree.m_newick = _finalTree.m_newick.trim();
164                                        if (_finalTree.m_newick.lastIndexOf(';') == -1) {
165                                                _finalTree.m_newick += ";";
166                                        }
167                                        if (_finalTree.m_score == null) {
168                                                _finalTree.m_score = new TreeScore();
169                                                _finalTree.m_score.noScore(0);
170                                        }
171
172                                } else if (status == CipresServiceDialog.ERROR) {
173                                        throw new IllegalActionException(this,
174                                                        "error initializing service");
175                                }
176                        } catch (Exception e) {
177                                e.printStackTrace();
178                        } finally {
179                                if (treeImproverWrapper != null) {
180                                        // release TreeImprove service
181                                        treeImproverWrapper.releaseService();
182                                }
183                        }
184
185                        // send out the improved tree
186                        outputTree.send(0, new ObjectToken(_finalTree));
187                }
188        }
189}