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.Rid3TreeImprove;
035import org.cipres.CipresIDL.api1.Tree;
036import org.cipres.helpers.CipresRegistry;
037import org.cipres.helpers.CipresServiceDialog;
038import org.cipres.helpers.RegistryEntryWrapper;
039
040import ptolemy.actor.TypedAtomicActor;
041import ptolemy.actor.TypedIOPort;
042import ptolemy.data.ObjectToken;
043import ptolemy.data.type.BaseType;
044import ptolemy.kernel.CompositeEntity;
045import ptolemy.kernel.util.IllegalActionException;
046import ptolemy.kernel.util.NameDuplicationException;
047
048//////////////////////////////////////////////////////////////////////////
049//// RecIDCM3
050/**
051 * This RecIDCM3 actor wraps the RecIDCM3 CORBA service provided by the CIPRes
052 * software package. The RecIDCM3 service implements the Recursive, Iterative,
053 * DCM3 (Disk Coverage Method) algorithm, which could be find in detail at
054 * http://www.cs.njit.edu/~usman/RecIDCM3.html
055 * 
056 * @author Zhijie Guan
057 * @version $Id: RecIDCM3.java 24234 2010-05-06 05:21:26Z welker $
058 */
059
060public class RecIDCM3 extends TypedAtomicActor {
061
062        /**
063         * Construct a RecIDCM3 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 RecIDCM3(CompositeEntity container, String name)
077                        throws NameDuplicationException, IllegalActionException {
078                super(container, name);
079
080                // construct the input port inputDataMatrix
081                inputDataMatrix = new TypedIOPort(this, "inputDataMatrix", true, false);
082                inputDataMatrix.setDisplayName("Data Matrix");
083                inputTree = new TypedIOPort(this, "inputTree", true, false);
084                inputTree.setDisplayName("Tree");
085
086                // construct the output port outputTree
087                outputTree = new TypedIOPort(this, "outputTree", false, true);
088                outputTree.setDisplayName("Tree after RecIDCM3");
089                // Set the type constraint.
090                outputTree.setTypeEquals(BaseType.GENERAL);
091
092                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
093                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
094                                + "</svg>\n");
095
096        }
097
098        // /////////////////////////////////////////////////////////////////
099        // // ports and parameters ////
100        /**
101         * A matrix containing the characters information of the analyzed taxa is
102         * passed to the RecIDCM3 actor through this input port. This port is an
103         * input port of type GENERAL.
104         */
105        public TypedIOPort inputDataMatrix = null;
106
107        /**
108         * A tree in CIPRes tree data structure is passed to the RecIDCM3 actor
109         * through this input port. This tree is treated as an initial tree for the
110         * RecIDCM3 algorithm. This port is an input port of type GENERAL.
111         */
112        public TypedIOPort inputTree = null;
113
114        /**
115         * The inferred tree is sent through this output port. This port is an
116         * output port of type GENERAL.
117         */
118        public TypedIOPort outputTree = null;
119
120        // /////////////////////////////////////////////////////////////////
121        // // functional variables ////
122        // a tree data structure in CIPRes IDL format
123        private org.cipres.CipresIDL.api1.Tree _finalTree = null;
124
125        // /////////////////////////////////////////////////////////////////
126        // // public methods ////
127
128        /**
129         * Improve the tree using RecIDCM3 CORBA service, and send the result tree
130         * to the output port.
131         * 
132         * @exception IllegalActionException
133         *                If it is thrown by the send() method sending out the
134         *                token.
135         */
136        public void fire() throws IllegalActionException {
137                super.fire();
138
139                if ((inputTree.hasToken(0)) && (inputDataMatrix.hasToken(0))) {
140
141                        RegistryEntryWrapper rid3Wrapper = null;
142                        try {
143                                // get RecIDCM3 algorithm wrapper
144                                rid3Wrapper = CipresRegistry.getCipresServiceWrapper(
145                                                Rid3TreeImprove.class, null, null);
146                                // use GuiGen to get users' settings
147                                CipresServiceDialog dialog = rid3Wrapper.getServiceDialog(null);
148                                int status = dialog.showAndInitialize();
149                                if (status == CipresServiceDialog.OK) {
150                                        // get the RecIDCM3 algorithm wrapper
151                                        Rid3TreeImprove service = (Rid3TreeImprove) rid3Wrapper
152                                                        .getService();
153                                        // set the tree and matrix into the CORBA service
154                                        service.setTree((Tree) ((ObjectToken) inputTree.get(0))
155                                                        .getValue());
156                                        service
157                                                        .setMatrix((DataMatrix) ((ObjectToken) inputDataMatrix
158                                                                        .get(0)).getValue());
159                                        // infer the result tree
160                                        _finalTree = service.improveTree(null);
161                                } else if (status == CipresServiceDialog.ERROR) {
162                                        throw new IllegalActionException(this,
163                                                        "error initializing service");
164                                }
165
166                        } catch (Exception e) {
167                                e.printStackTrace();
168                        } finally {
169                                if (rid3Wrapper != null) {
170                                        // release the RecIDCM3 service
171                                        rid3Wrapper.releaseService();
172                                }
173                        }
174
175                        // send out the inferred tree to the output port
176                        outputTree.send(0, new ObjectToken(_finalTree));
177                }
178        }
179
180        /**
181         * Post fire the actor. Return false to indicated that the process has
182         * finished. If it returns true, the process will continue indefinitely.
183         */
184        /*
185         * public boolean postfire() { return false; }
186         */
187}