001/*
002 * Copyright (c) 1999-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.sdm.spa.actors.piw.viz;
031
032import javax.swing.SwingUtilities;
033
034import ptolemy.actor.TypedAtomicActor;
035import ptolemy.actor.TypedIOPort;
036import ptolemy.data.ArrayToken;
037import ptolemy.data.IntToken;
038import ptolemy.data.RecordToken;
039import ptolemy.data.StringToken;
040import ptolemy.data.type.ArrayType;
041import ptolemy.data.type.BaseType;
042import ptolemy.data.type.RecordType;
043import ptolemy.data.type.Type;
044import ptolemy.kernel.CompositeEntity;
045import ptolemy.kernel.util.IllegalActionException;
046import ptolemy.kernel.util.NameDuplicationException;
047
048//////////////////////////////////////////////////////////////////////////
049//// PIWVisualizationActor
050/**
051 * This actor is used to visualize data from various sources in SPA's promoter
052 * identification workflow. It takes the input given to it from the workflow and
053 * passes it to PIWVisualizationFrame, where the real work of creating the
054 * visualization is started. In other words, this acts as a liason between the
055 * workflow and the code for creating the visualization. Only when all of the
056 * information that is needed exists, should the PIWVisualizationFrame be
057 * created.
058 * 
059 * @author Beth Yost
060 * @author xiaowen
061 * @version $Id: VizActor.java 24234 2010-05-06 05:21:26Z welker $
062 */
063
064public class VizActor extends TypedAtomicActor {
065
066        /**
067         * Construct an actor with the given container and name.
068         * 
069         * @param container
070         *            The container.
071         * @param name
072         *            The name of this actor.
073         * @exception IllegalActionException
074         *                If the actor cannot be contained by the proposed
075         *                contained.
076         * @exception NameDuplicationException
077         *                If the container already has an actor with this name.
078         */
079        public VizActor(CompositeEntity container, String name)
080                        throws NameDuplicationException, IllegalActionException {
081
082                super(container, name);
083
084                // create the port
085                String[] arrNames = { "TransfacNames", // names of transcription factor
086                                                                                                // binding sites
087                                "TransfacSites", // indices corresponding to the names
088                                "OrigSeq", // original sequence input to BLAST
089                                "AccessionNumber", // original accession number input by user
090                                "GeneID", // Gene ID returned by BLAST
091                                "ClustalWSeq" // sequence returned by ClustalW
092                };
093
094                Type[] arrTypes = { new ArrayType(BaseType.STRING),
095                                new ArrayType(BaseType.INT), BaseType.STRING, BaseType.STRING,
096                                BaseType.STRING, BaseType.STRING };
097
098                portSequences = new TypedIOPort(this, "Sequences", true, false);
099                portSequences.setTypeEquals(new ArrayType(new RecordType(arrNames,
100                                arrTypes)));
101
102                _createIcon();
103        }
104
105        // /////////////////////////////////////////////////////////////////
106        // // public variables ////
107
108        public TypedIOPort portSequences;
109
110        // /////////////////////////////////////////////////////////////////
111        // // public methods ////
112
113        /**
114         * Also for testing, if called, create the visualization frame then stop
115         * calling this actor This is just set up this way for testing and needs to
116         * be changed.
117         * 
118         * @exception IllegalActionException
119         *                If the parent class throws it.
120         */
121        public void fire() throws IllegalActionException {
122                // Get the input array token.
123                ArrayToken arrSeqs = (ArrayToken) portSequences.get(0);
124
125                // Sequences to be displayed.
126                final Sequence[] sequences = new Sequence[arrSeqs.length()];
127
128                // Loop through each element of the array.
129                for (int i = 0; i < arrSeqs.length(); i++) {
130                        // Get the record token.
131                        RecordToken rec = (RecordToken) arrSeqs.getElement(i);
132
133                        // Extract the fields of the record token.
134                        ArrayToken arrTokTransfacNames = (ArrayToken) rec
135                                        .get("TransfacNames");
136                        ArrayToken arrTokTransfacSites = (ArrayToken) rec
137                                        .get("TransfacSites");
138                        StringToken strTokOrigSeq = (StringToken) rec.get("OrigSeq");
139                        StringToken strTokAccessionNumber = (StringToken) rec
140                                        .get("AccessionNumber");
141                        StringToken strTokGeneID = (StringToken) rec.get("GeneID");
142                        StringToken strTokClustalWSeq = (StringToken) rec
143                                        .get("ClustalWSeq");
144
145                        // Make sure there are equal numbers of transcription factor names
146                        // and sites
147                        if (arrTokTransfacNames.length() != arrTokTransfacSites.length()) {
148                                throw new IllegalActionException("Error detected by "
149                                                + this.getFullName() + "\n" + "There were "
150                                                + arrTokTransfacNames.length()
151                                                + " transcription factor names, and "
152                                                + arrTokTransfacSites
153                                                + " transcription factor sites input"
154                                                + " for accession number '"
155                                                + strTokAccessionNumber.stringValue()
156                                                + "' and gene ID '" + strTokGeneID.stringValue());
157                        }
158
159                        // Get an array of transcription factor binding sites.
160                        TranscriptionFactorBindingSite[] arrTFBS = new TranscriptionFactorBindingSite[arrTokTransfacNames
161                                        .length()];
162
163                        for (int j = 0; j < arrTokTransfacNames.length(); j++) {
164                                arrTFBS[j] = new TranscriptionFactorBindingSite(
165                                                ((StringToken) arrTokTransfacNames.getElement(j))
166                                                                .stringValue(), ((IntToken) arrTokTransfacSites
167                                                                .getElement(j)).intValue());
168                        }
169
170                        // Create the sequence.
171                        sequences[i] = new Sequence(strTokAccessionNumber.stringValue(),
172                                        strTokGeneID.stringValue(),
173                                        strTokClustalWSeq.stringValue(), arrTFBS);
174                }
175
176                // Put this in the Swing thread in case there are race conditions.
177                SwingUtilities.invokeLater(new Runnable() {
178                        public void run() {
179                                VizApplication app = new VizApplication(false);
180                                app.show(sequences);
181                        }
182                });
183        }
184
185        // /////////////////////////////////////////////////////////////////
186        // // private methods ////
187
188        /** Create and set the svg icon (a DNA strand) to be displayed in SPA. */
189        private void _createIcon() {
190                // Creating a green and red double helix.
191                _attachText("_iconDescription", "<svg>\n"
192                                + "<rect x=\"-20\" y=\"-15\" " + "width=\"40\" height=\"30\" "
193                                + "style=\"fill:lightGrey\"/>\n" + "<rect x=\"-15\" y=\"-10\" "
194                                + "width=\"30\" height=\"20\" " + "style=\"fill:white\"/>\n"
195
196                                + "<line x1=\"-3\" y1=\"6\" x2=\"3\" y2=\"6\" "
197                                + "style=\"stroke:green\"/>\n"
198                                + "<line x1=\"-4\" y1=\"4\" x2=\"4\" y2=\"4\" "
199                                + "style=\"stroke:green\"/>\n"
200                                + "<line x1=\"-3\" y1=\"2\" x2=\"3\" y2=\"2\" "
201                                + "style=\"stroke:red\"/>\n"
202
203                                + "<line x1=\"-3\" y1=\"-2\" x2=\"3\" y2=\"-2\" "
204                                + "style=\"stroke:green\"/>\n"
205                                + "<line x1=\"-4\" y1=\"-4\" x2=\"4\" y2=\"-4\" "
206                                + "style=\"stroke:green\"/>\n"
207                                + "<line x1=\"-3\" y1=\"-6\" x2=\"3\" y2=\"-6\" "
208                                + "style=\"stroke:red\"/>\n"
209
210                                + "<line x1=\"-4\" y1=\"-4\" x2=\"4\" y2=\"4\" "
211                                + "style=\"stroke:black\"/>\n"
212                                + "<line x1=\"-4\" y1=\"4\" x2=\"4\" y2=\"-4\" "
213                                + "style=\"stroke:black\"/>\n"
214
215                                + "<line x1=\"-4\" y1=\"4\" x2=\"4\" y2=\"10\" "
216                                + "style=\"stroke:black\"/>\n"
217                                + "<line x1=\"-4\" y1=\"10\" x2=\"4\" y2=\"4\" "
218                                + "style=\"stroke:black\"/>\n"
219
220                                + "<line x1=\"-4\" y1=\"-4\" x2=\"4\" y2=\"-10\" "
221                                + "style=\"stroke:black\"/>\n"
222                                + "<line x1=\"-4\" y1=\"-10\" x2=\"4\" y2=\"-4\" "
223                                + "style=\"stroke:black\"/>\n"
224
225                                + "</svg>\n");
226
227        }
228}
229
230// vim: ts=4 sw=4 et