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 java.io.File;
034
035import org.cipres.CipresIDL.api1.MatrixAlign;
036import org.cipres.CipresIDL.api1.Tree;
037import org.cipres.datatypes.PhyloDataset;
038import org.cipres.guigen.ServiceCommandPanel;
039import org.cipres.helpers.CipresRegistry;
040import org.cipres.helpers.RegistryEntryWrapper;
041import org.cipres.util.Config;
042
043import ptolemy.actor.TypedAtomicActor;
044import ptolemy.actor.TypedIOPort;
045import ptolemy.data.type.BaseType;
046import ptolemy.kernel.CompositeEntity;
047import ptolemy.kernel.util.IllegalActionException;
048import ptolemy.kernel.util.NameDuplicationException;
049
050//////////////////////////////////////////////////////////////////////////
051//// MatrixAligner
052/**
053 * This MatrixAligner actor wraps the MatrixAligner CORBA service provided by
054 * the CIPRes software package. The MatrixAligner service implements the
055 * multipler sequence alignment directed by a guide tree.
056 * 
057 * @author Zhijie Guan, Alex Borchers
058 * @version $Id: MatrixAligner.java 24234 2010-05-06 05:21:26Z welker $
059 */
060
061public class MatrixAligner extends TypedAtomicActor {
062
063        /**
064         * Construct a MatrixAligner actor with the given container and name.
065         * 
066         * @param container
067         *            The container.
068         * @param name
069         *            The name of this actor.
070         * @exception IllegalActionException
071         *                If the entity cannot be contained by the proposed
072         *                container.
073         * @exception NameDuplicationException
074         *                If the container already has an actor with this name.
075         */
076
077        public MatrixAligner(CompositeEntity container, String name)
078                        throws NameDuplicationException, IllegalActionException {
079                super(container, name);
080
081                // construct the input port inputDataMatrix
082                inputDataMatrix = new TypedIOPort(this, "inputDataMatrix", true, false);
083                inputDataMatrix.setDisplayName("Data Matrix");
084                inputTree = new TypedIOPort(this, "inputTree", true, false);
085                inputTree.setDisplayName("Tree");
086
087                // construct the output port outputTree
088                outputTree = new TypedIOPort(this, "outputTree", false, true);
089                outputTree.setDisplayName("Tree after RecIDCM3");
090                // Set the type constraint.
091                outputTree.setTypeEquals(BaseType.GENERAL);
092
093                _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" "
094                                + "width=\"60\" height=\"20\" " + "style=\"fill:white\"/>\n"
095                                + "</svg>\n");
096
097        }
098
099        // /////////////////////////////////////////////////////////////////
100        // // ports and parameters ////
101        /**
102         * A matrix containing the characters information of the analyzed taxa is
103         * passed to the RecIDCM3 actor through this input port. This port is an
104         * input port of type GENERAL.
105         */
106        public TypedIOPort inputDataMatrix = null;
107
108        /**
109         * A tree in CIPRes tree data structure is passed to the RecIDCM3 actor
110         * through this input port. This tree is treated as an initial tree for the
111         * RecIDCM3 algorithm. This port is an input port of type GENERAL.
112         */
113        public TypedIOPort inputTree = null;
114
115        /**
116         * The inferred tree is sent through this output port. This port is an
117         * output port of type GENERAL.
118         */
119        public TypedIOPort outputTree = null;
120
121        // /////////////////////////////////////////////////////////////////
122        // // functional variables ////
123        // a tree data structure in CIPRes IDL format
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                RegistryEntryWrapper matrixAlignWrapper = null;
140                try {
141
142                        matrixAlignWrapper = CipresRegistry.getCipresServiceWrapper(
143                                        MatrixAlign.class, null, null);
144                        MatrixAlign service = (MatrixAlign) matrixAlignWrapper.getService();
145                        org.omg.CORBA.StringHolder reply = new org.omg.CORBA.StringHolder();
146                        boolean executeSucceeded = false;
147
148                        // if args[0]="0" uses guigen
149                        if (option == 0) {
150                                File guiXmlFile = new File(Config.getInstance().getXmlGuiDir()
151                                                + Config.getInstance().getSlash() + "clustalw.xml");
152                                ServiceCommandPanel pnl = new ServiceCommandPanel(guiXmlFile);
153
154                                // TODO implement Cancel functionality
155                                pnl.setHideCancelButton(true);
156
157                                // for deugging/testing - automatically sets infile and outfile
158                                // params
159                                // --------------------------------------------------------
160                                String outFilePath = Config.getInstance().getUniqueTmpFilename(
161                                                "clustalOut_", ".nex");
162                                String inFilePath = Config.getInstance().getSampleFilesDir()
163                                                + Config.getInstance().getSlash()
164                                                + "zfish_nt_12T.fasta";
165                                pnl.setParameterValue("infile", inFilePath);
166                                pnl.setParameterValue("outfile", outFilePath);
167                                // --------------------------------------------------------
168                                // end for deugging/testing
169
170                                pnl
171                                                .setNotifyButtonDisplayMode(ServiceCommandPanel.NOTIFY_BUTTON_DISPLAY_MODE_LAUNCH);
172                                pnl.showServicePanelAsDialog();
173
174                                executeSucceeded = service.execute(pnl.getCmdBlock(), reply);
175                        }
176
177                        if (option == 1) {
178                                File nexFile = new File(Config.getInstance()
179                                                .getSampleFilesDir()
180                                                + Config.getInstance().getSlash() + "TestNexusFile.nex");
181                                PhyloDataset pdIn = new PhyloDataset();
182                                pdIn.initialize(nexFile);
183                                service.setTaxa(pdIn.getTaxaInfo());
184                                service.setInputMatrix(pdIn.getDataMatrix());
185                                service.setGuideTree(pdIn.getFirstTree());
186                                executeSucceeded = service.execute("", reply);
187                                // now get output tree and matrix
188                                PhyloDataset pdOut = new PhyloDataset();
189                                pdOut.setDataMatrix(service.getAlignedMatrix());
190                                pdOut.setTrees(new Tree[] { service.getTree(null) });
191                                pdOut.setTaxaInfo(service.getTaxa());
192                                pdOut.writeToNexus(new File(Config.getInstance()
193                                                .getUniqueTmpFilename("ClustalExOut_", ".nex")));
194                                System.out.println("nexus written");
195                        }
196
197                        if (executeSucceeded) {
198                                System.out.println("Clustal executed successfully");
199                        } else {
200                                System.out.println(reply.value);
201                        }
202
203                } catch (Exception e) {
204                        e.printStackTrace();
205                } finally {
206                        if (matrixAlignWrapper != null) {
207                                matrixAlignWrapper.releaseService();
208                        }
209                        // System.exit(0);
210                }
211                /*
212                 * if ( (inputTree.hasToken(0)) && (inputDataMatrix.hasToken(0)) ) {
213                 * 
214                 * RegistryEntryWrapper rid3Wrapper = null; try { // get RecIDCM3
215                 * algorithm wrapper rid3Wrapper =
216                 * CipresRegistry.getCipresServiceWrapper(Rid3TreeImprove.class, null,
217                 * null); // use GuiGen to get users' settings CipresServiceDialog
218                 * dialog = rid3Wrapper.getServiceDialog(null); int status =
219                 * dialog.showAndInitialize(); if (status == CipresServiceDialog.OK) {
220                 * // get the RecIDCM3 algorithm wrapper Rid3TreeImprove service =
221                 * (Rid3TreeImprove)rid3Wrapper.getService(); // set the tree and matrix
222                 * into the CORBA service service.setTree(
223                 * (Tree)((ObjectToken)inputTree.get(0)).getValue() );
224                 * service.setMatrix(
225                 * (DataMatrix)((ObjectToken)inputDataMatrix.get(0)).getValue() ); //
226                 * infer the result tree _finalTree = service.improveTree(null); } else
227                 * if (status == CipresServiceDialog.ERROR) { throw new
228                 * IllegalActionException(this, "error initializing CIPRES service, "
229                 * " service dialog returned error"); }
230                 * 
231                 * } catch (Exception e) { e.printStackTrace(); } finally { if
232                 * (rid3Wrapper != null) { // release the RecIDCM3 service
233                 * rid3Wrapper.releaseService(); } }
234                 * 
235                 * // send out the inferred tree to the output port outputTree.send(0,
236                 * new ObjectToken( _finalTree )); }
237                 */}
238
239        /**
240         * Post fire the actor. Return false to indicated that the process has
241         * finished. If it returns true, the process will continue indefinitely.
242         */
243        /*
244         * public boolean postfire() { return false; }
245         */
246        private int option = 0;
247}