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.datatypes.PhyloDataset;
034
035import ptolemy.actor.TypedAtomicActor;
036import ptolemy.actor.TypedIOPort;
037import ptolemy.data.ObjectToken;
038import ptolemy.data.StringToken;
039import ptolemy.data.type.BaseType;
040import ptolemy.kernel.CompositeEntity;
041import ptolemy.kernel.util.IllegalActionException;
042import ptolemy.kernel.util.NameDuplicationException;
043
044//////////////////////////////////////////////////////////////////////////
045//// PhyloDataReader
046/**
047 * The PhyloDataReader actor reads and parses the data stored in Nexus format.
048 * This actor uses the data structure defined in the CIPRes software package.
049 * 
050 * @author Zhijie Guan
051 * @version $Id: PhyloDataReader.java 24234 2010-05-06 05:21:26Z welker $
052 */
053
054public class PhyloDataReader extends TypedAtomicActor {
055
056        /**
057         * Construct a PhyloDataReader actor with the given container and name.
058         * 
059         * @param container
060         *            The container.
061         * @param name
062         *            The name of this actor.
063         * @exception IllegalActionException
064         *                If the entity cannot be contained by the proposed
065         *                container.
066         * @exception NameDuplicationException
067         *                If the container already has an actor with this name.
068         */
069
070        public PhyloDataReader(CompositeEntity container, String name)
071                        throws NameDuplicationException, IllegalActionException {
072                super(container, name);
073
074                // construct the input port inputNexusData
075                inputNexusData = new TypedIOPort(this, "inputNexusData", true, false);
076                inputNexusData.setDisplayName("Nexus File Content");
077                inputNexusData.setTypeEquals(BaseType.GENERAL);
078
079                // construct the output port outputDataMatrix
080                outputDataMatrix = new TypedIOPort(this, "outputDataMatrix", false,
081                                true);
082                outputDataMatrix.setDisplayName("Data Matrix");
083                // Set the type constraint.
084                outputDataMatrix.setTypeEquals(BaseType.GENERAL);
085
086                // construct the output port outputTree
087                outputTree = new TypedIOPort(this, "outputTree", false, true);
088                outputTree.setDisplayName("Tree");
089                // Set the type constraint.
090                outputTree.setTypeEquals(BaseType.GENERAL);
091
092                // construct the output port outputTaxaInfo
093                outputTaxaInfo = new TypedIOPort(this, "outputTaxaInfo", false, true);
094                outputTaxaInfo.setDisplayName("Taxa Info");
095                // Set the type constraint.
096                outputTaxaInfo.setTypeEquals(BaseType.GENERAL);
097
098                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
099                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
100                                + "</svg>\n");
101
102        }
103
104        // /////////////////////////////////////////////////////////////////
105        // // ports and parameters ////
106
107        /**
108         * The phylogenetic data in Nexus format is passed to the PhyloDataReader
109         * actor through this input port. The data could contain information about
110         * the phylogenetic tree, data matrix, and/or Taxa. Generally this data is
111         * read from a Nexus input file, or retrieved from a phylogenetic info
112         * database, like TreeBase. This port is an input port of type GENERAL.
113         */
114        public TypedIOPort inputNexusData = null;
115
116        /**
117         * The tree information contained in the input data is parsed and sent out
118         * through this output port. This port is an output port of type GENERAL.
119         */
120        public TypedIOPort outputTree = null;
121
122        /**
123         * The data matrix information contained in the input data is parsed and
124         * sent out through this output port. This port is an output port of type
125         * GENERAL.
126         */
127        public TypedIOPort outputDataMatrix = null;
128
129        /**
130         * The taxa information contained in the input data is parsed and sent out
131         * through this output port. This port is an output port of type GENERAL.
132         */
133        public TypedIOPort outputTaxaInfo = null;
134
135        // /////////////////////////////////////////////////////////////////
136        // // functional variables ////
137        // tree structure
138        private org.cipres.CipresIDL.api1.Tree _tree = null;
139        // data matrix
140        private org.cipres.CipresIDL.api1.DataMatrix _dataMatrix = null;
141        // taxa info
142        private String[] _taxaInfo = null;
143        // phylodataset used to store and parse the input data
144        private org.cipres.datatypes.PhyloDataset _phyloDataset;
145
146        // /////////////////////////////////////////////////////////////////
147        // // public methods ////
148
149        /**
150         * Read and parse the Nexus data.
151         * 
152         * @exception IllegalActionException
153         *                If it is thrown by the send() method sending out the
154         *                token.
155         */
156        public void fire() throws IllegalActionException {
157                super.fire();
158
159                if (inputNexusData.hasToken(0)) {
160
161                        try {
162                                _phyloDataset = new PhyloDataset();
163                                // initialize the phylodataset with the input data
164                                _phyloDataset.initialize(((StringToken) inputNexusData.get(0))
165                                                .stringValue());
166
167                                // parse the phylodataset to get the tree, data matrix, and taxa
168                                // info
169                                _tree = _phyloDataset.getFirstTree();
170                                _dataMatrix = _phyloDataset.getDataMatrix();
171                                _taxaInfo = _phyloDataset.getTaxaInfo();
172                        } catch (Exception ex) {
173                                System.out.println("Exception on read the phylo data set: ");
174                                ex.printStackTrace();
175                        }
176
177                        // send out the object tokens
178                        ObjectToken treeToken = new ObjectToken(_tree);
179                        outputTree.send(0, treeToken);
180
181                        ObjectToken dataMatrixToken = new ObjectToken(_dataMatrix);
182                        outputDataMatrix.send(0, dataMatrixToken);
183
184                        ObjectToken taxaInfoToken = new ObjectToken(_taxaInfo);
185                        outputTaxaInfo.send(0, taxaInfoToken);
186                }
187
188        }
189
190        /**
191         * Post fire the actor. Return false to indicated that the process has
192         * finished. If it returns true, the process will continue indefinitely.
193         */
194        public boolean postfire() {
195                return false;
196        }
197}