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
032import java.io.File;
033import java.io.FileInputStream;
034import java.io.FileOutputStream;
035import java.nio.channels.FileChannel;
036
037import org.cipres.helpers.GUIRun;
038import org.cipres.kepler.registry.ActorInfo;
039import org.cipres.kepler.registry.CipresKeplerRegistry;
040import org.cipres.kepler.registry.Globals;
041import org.cipres.util.file.cipresFile;
042
043import ptolemy.data.IntToken;
044import ptolemy.data.StringToken;
045import ptolemy.data.expr.Parameter;
046import ptolemy.kernel.CompositeEntity;
047import ptolemy.kernel.util.IllegalActionException;
048import ptolemy.kernel.util.NameDuplicationException;
049
050//////////////////////////////////////////////////////////////////////////
051////PAUPConsensusTrees
052/**
053 * This actor calls PAUP to find consensus trees for a group of trees.
054 * 
055 * @author Zhijie Guan, Alex Borchers
056 * @version $Id: PAUPConsensusTrees.java 24234 2010-05-06 05:21:26Z welker $
057 */
058
059public class PAUPConsensusTrees extends GUIRunCIPRes {
060
061        /**
062         * Construct PAUPConsensusTrees source with the given container and name.
063         * 
064         * @param container
065         *            The container.
066         * @param name
067         *            The name of this actor.
068         * @exception IllegalActionException
069         *                If the entity cannot be contained by the proposed
070         *                container.
071         * @exception NameDuplicationException
072         *                If the container already has an actor with this name.
073         */
074
075        public PAUPConsensusTrees(CompositeEntity container, String name)
076                        throws NameDuplicationException, IllegalActionException {
077                super(container, name);
078
079                // get program information
080                CipresKeplerRegistry registry = Globals.getInstance().getRegistry();
081                _paupActor = registry.getActor("ConsensusTree_Paup");
082
083                // set program related information
084                command.setToken(new StringToken(_paupActor.getAppPathForOS()));
085                uiXMLFile.setToken(new StringToken(_paupActor.getGuiXmlFile()));
086                outputFile.setToken(new StringToken(registry.getDefaultStdOutDir()
087                                + "PAUPConsensusOut.log"));
088                errorFile.setToken(new StringToken(registry.getDefaultStdOutDir()
089                                + "PAUPConsensusError.log"));
090                workingDirectory.setToken(new StringToken(_paupActor
091                                .getWorkingDirecotry()));
092                parameterForOutput.setToken(new StringToken("outfile"));
093                paupCmdFile = new Parameter(this, "paupCmdFile", new StringToken(
094                                registry.getDefaultStdOutDir() + "paup_consensus_cmds.nex"));
095                paupCmdFile.setDisplayName("PAUP Command File Name");
096        }
097
098        // /////////////////////////////////////////////////////////////////
099        // // ports and parameters ////
100
101        /**
102         * The parameter for PAUP command file. This parameter will be set to
103         * String.
104         */
105        public Parameter paupCmdFile;
106
107        // /////////////////////////////////////////////////////////////////
108        // // functional variables ////
109
110        // /////////////////////////////////////////////////////////////////
111        // // public methods ////
112
113        /**
114         * Run PAUP for finding consensus trees.
115         * 
116         * @exception IllegalActionException
117         *                If it is thrown by the send() method sending out the
118         *                token.
119         */
120        public void fire() throws IllegalActionException {
121                if (inputParameterValue.hasToken(0) && inputParameterName.hasToken(0)) {
122                        try {
123                                GUIRun grun = new GUIRun("PAUP Consensus Trees");
124
125                                // if (command.hasToken(0)) {
126                                grun.setCommand(((StringToken) command.getToken())
127                                                .stringValue());
128                                // }
129
130                                // if (uiXMLFile.hasToken(0)) {
131                                grun.setUIXMLFile(((StringToken) uiXMLFile.getToken())
132                                                .stringValue());
133                                // }
134
135                                // if (outputFile.hasToken(0)) {
136                                grun.setOutputFileName(((StringToken) outputFile.getToken())
137                                                .stringValue());
138                                // }
139
140                                // if (errorFile.hasToken(0)) {
141                                grun.setErrorFileName(((StringToken) errorFile.getToken())
142                                                .stringValue());
143                                // }
144
145                                // if (workingDirectory.hasToken(0)) {
146                                grun.setWorkingDirectory(((StringToken) workingDirectory
147                                                .getToken()).stringValue());
148                                // }
149
150                                grun.setArgumentValue(((StringToken) inputParameterName.get(0))
151                                                .stringValue(), ((StringToken) inputParameterValue
152                                                .get(0)).stringValue());
153
154                                grun.setArgumentsWithGUIGen();
155
156                                // if path to output file is > 64 chars paup will throw an error
157                                // so, we have give paup only the filename, which causes it to
158                                // write to
159                                // its own dir, then rename the file to the location specified
160                                // by the
161                                // outFilePath
162                                // Here is how we handle the file rename issue
163                                // outfile is the file that user assigned for PAUP output
164                                // infile is the file that user assigned for PAUP input
165                                File outfile = new File(grun.getArgumentValue("outfile"));
166                                File infile = new File(grun.getArgumentValue("infile"));
167                                // paupApp indicates where PAUP is
168                                File paupApp = new File(_paupActor.getAppPathForOS());
169                                // paupOut is the real output that is generated by PAUP.
170                                // It consists of the directory PAUP is in,
171                                // plus the dir seperator, plus the outfile name
172                                File paupOut = new File(paupApp.getParent()
173                                                + Globals.getInstance().getDirSep() + outfile.getName());
174                                // paupIn is the real input that is fed to PAUP.
175                                // It consists of the directory PAUP is in,
176                                // plus the dir seperator, plus the infile name
177                                File paupIn = new File(paupApp.getParent()
178                                                + Globals.getInstance().getDirSep() + infile.getName());
179
180                                // Now we are going to copy the input file to its new location
181                                // in PAUP directory
182                                FileChannel in = null, out = null;
183                                try {
184                                        in = new FileInputStream(infile).getChannel();
185                                        out = new FileOutputStream(paupIn).getChannel();
186
187                                        in.transferTo(0, in.size(), out); // copy from infile to
188                                                                                                                // paupIn
189                                } catch (Exception e) {
190                                        System.out
191                                                        .println("Error(s) reported during file copy from "
192                                                                        + infile.getAbsolutePath() + " to "
193                                                                        + paupIn.getAbsolutePath() + ".");
194                                        e.printStackTrace();
195                                } finally {
196                                        if (in != null)
197                                                in.close();
198                                        if (out != null)
199                                                out.close();
200                                }
201
202                                // this command has paup:
203                                // 1. import input and write to output
204                                // 2. execute contree and append trees to output
205                                String commands = "EXECUTE " + paupIn.getName() + ";"
206                                                + " EXPORT File=" + paupOut.getName()
207                                                + " FORMAT = NEXUS TREES=NO REPLACE=YES;"
208                                                + " CLEARTREES NOWARN=YES;" + " SET WARNRESET=NO; "
209                                                + grun.getArguments() + " TreeFile ="
210                                                + paupOut.getName() + " APPEND=YES;";
211
212                                String paupCmdFileName = ((StringToken) paupCmdFile.getToken())
213                                                .stringValue();
214                                cipresFile cmdFile = new cipresFile(paupCmdFileName);
215                                cmdFile.fillFromString("#NEXUS\nBEGIN PAUP;\n" + commands
216                                                + " QUIT;\nEND;");
217
218                                grun.setArguments(paupCmdFileName);
219
220                                grun.setWaitForExecution(true);
221
222                                grun.execute();
223
224                                // now move outfile to its proper location
225                                if (!outfile.getAbsolutePath().equalsIgnoreCase(
226                                                paupOut.getAbsolutePath())) {
227                                        paupOut.renameTo(outfile);
228                                }
229
230                                exitCode.send(0, new IntToken(grun.getExitCode()));
231
232                                standardOutput.send(0,
233                                                new StringToken(grun.getStandardOutput()));
234                                standardError.send(0, new StringToken(grun.getStandardError()));
235
236                                outputParameterValue.send(0, new StringToken(grun
237                                                .getArgumentValue(((StringToken) parameterForOutput
238                                                                .getToken()).stringValue())));
239                        } catch (Exception e) {
240                                e.printStackTrace();
241                        }
242                }
243        }
244
245        /**
246         * Post fire the actor. Return false to indicated that the process has
247         * finished. If it returns true, the process will continue indefinitely.
248         */
249        public boolean postfire() {
250                return false;
251        }
252
253        /**
254         * private variables _paupActor records program information for PAUP.
255         */
256        private ActorInfo _paupActor;
257
258}