001    /*
002     * Copyright 2007, 2012 Stephen Fisher and Junhyong Kim, University of
003     * Pennsylvania.
004     *
005     * This file is part of Glo-DB.
006     * 
007     * Glo-DB is free software: you can redistribute it and/or modify it
008     * under the terms of the GNU General Public License as published by
009     * the Free Software Foundation, either version 3 of the License, or
010     * (at your option) any later version.
011     * 
012     * Glo-DB is distributed in the hope that it will be useful, but
013     * WITHOUT ANY WARRANTY; without even the implied warranty of
014     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015     * General Public License for more details.
016     * 
017     * You should have received a copy of the GNU General Public License
018     * along with Glo-DB. If not, see <http://www.gnu.org/licenses/>.
019     *
020     * @(#)GloDBMain.java
021     */
022    
023    package edu.upenn.gloDB;
024    
025    import org.python.util.InteractiveConsole; 
026    import org.python.core.*; 
027    import javax.swing.UIManager;
028    import java.util.prefs.*;
029    
030    /**
031     * GloDBMain program.
032     *
033     * @author  Stephen Fisher
034     * @version $Id: GloDBMain.java,v 1.1.2.11 2007/03/01 21:17:32 fisher Exp $
035     */
036    
037    public class GloDBMain { 
038             public static InteractiveConsole console = new InteractiveConsole();
039             public static boolean ISBATCH = false;
040    
041             /** 
042              * Built-in default property values.  
043              */
044             //      public static Preferences systemDefaults = Preferences.systemRoot().node("/edu/upenn/gloDB");
045    
046             /** User established properties. */
047             public static Preferences userDefaults = Preferences.userRoot().node("/edu/upenn/gloDB");
048    
049        /**
050         * @param args  Command line arguments.
051         */
052        public static void main(String[] args) throws PyException { 
053                      try {
054                                    // use the local (platform-dependent) look and feel for the GUI
055                                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
056                      } catch (Exception e) { }
057    
058                      //              System.out.println("Hello, brave new world");
059                      //              console.push("print sys");
060                      //              console.set("a", new PyInteger(42));
061                      //              console.push("print a");
062                      //              console.push("x = 2 + 2");
063                      //              PyObject x = console.get("x");
064                      //              System.out.println("x: " + x);
065                      //              console.push("print a");
066    
067                      // setup some convenient references
068                      console.set("trackPool", ObjectHandles.getTrackPool());
069                      //              console.set("featurePool", ObjectHandles.getFeaturePool());
070                      console.set("sequencePool", ObjectHandles.getSequencePool());
071    
072                      //              console.push("print");
073                      console.push("print 'Glo-DB'");
074                      console.push("print 'version 1.0'");
075                      console.push("print 'Copyright 2007, 2012 Stephen Fisher and Junhyong Kim, University of Pennsylvania.'");
076                      console.push("print 'This program comes with ABSOLUTELY NO WARRANTY; for details type: warranty()'");
077                      console.push("print ");
078    
079                      try {
080                                    // process the built-in command line arguments
081                                    for (int i = 0; i < args.length; i++) {
082                                             // check for the BATCH flag
083                                             if (args[i].compareToIgnoreCase("-BATCH") == 0) {
084                                                      ISBATCH = true;
085                                                      continue;
086                                             }
087                                    }
088    
089                                    console.push("print 'Loading startup scripts...'");
090                                    // load user-defined functions into the console.
091                                    console.exec("from startup import *");
092    
093                                    // process the user-defined command line arguments
094                                    for (int i = 0; i < args.length; i++) {
095                                             // skip the BATCH flag
096                                             if (args[i].compareToIgnoreCase("-BATCH") == 0) {
097                                                      continue;
098                                             }
099    
100                                             GloDBUtils.printMsg("Running command line arg: " + args[i]);
101                                             console.push(args[i]);
102                                    }
103                      } catch (Exception e) { 
104                                    System.err.println(" ** ERROR: Error loading startup script.");
105                                    System.err.println(" ** ERROR: Startup script not loaded.");
106    
107                                    // XXX Should turn on the Stack dumping with a flag when
108                                    // running the program.
109    
110                                    // dump stack because getMessage() doesn't work here.
111                                    // 'console' must munge this up.
112                                    System.err.println(e);
113                      }
114    
115                      if (! ISBATCH) console.interact("");
116        }
117    
118             public static String getSystemProperty(String property) {
119                      return System.getProperty(property);
120             }
121    
122             public static void setSystemProperty(String property, String value) {
123                      if ((property == null) || (property == "")) return;
124                      System.setProperty(property, value);
125             }
126    
127             /**
128              * A simple class to experiment with your JVM's garbage collector
129              * and memory sizes for various data types.
130              *
131              * @author <a href="mailto:vlad@trilogy.com">Vladimir Roubtsov</a>
132              */
133        public static void sizeOf() {
134            // "warm up" all classes/methods that we are going to use:
135            runGC();
136            usedMemory();
137            
138            // array to keep strong references to allocated objects:
139            final int count = 10000; // 10000 or so is enough for small ojects
140            Object[] objects = new Object[count];
141            
142            long heap1 = 0;
143    
144                      Sequence s = new Sequence(false);
145                      edu.upenn.gloDB.io.GFFTrack gt = new edu.upenn.gloDB.io.GFFTrack();
146    
147            // allocate count+1 objects, discard the first one:
148            for (int i = -1; i < count; ++i) {
149                Object object;
150                
151                // INSTANTIATE YOUR DATA HERE AND ASSIGN IT TO 'object':
152                
153                                    //            object = new Object(); // 8 bytes
154                //object = new Integer (i); // 16 bytes
155                //object = new Long (i); // same size as Integer?
156                //object = createString (10); // 56 bytes? fine...
157                //object = createString (9)+' '; // 72 bytes? the article explains why
158                //object = new char [10]; // 32 bytes
159                //object = new byte [32][1]; // 656 bytes?!
160    
161                                    //                              object = new Sequence();  // 521 bytes
162                                    //                              object = new Track(false);  // 283 bytes (248 not in trackPool)
163                                    /*
164                                    Feature feature = new ExactFeature(0, 1, s);  // 184 bytes; 
165                                                                                                                                     // 144 not in featurePool;
166                                                                                                                                     // 323 if contains 6 attributes
167                                    String attributes = "";
168                                    attributes += "source=gadfly";
169                                    attributes += "feature=translation";
170                                    attributes += "score=.";
171                                    attributes += "strand=-"; 
172                                    attributes += "frame=.";
173                                    attributes += "attributes=genegrp=CG3038; transgrp=CG3038-RB; name=CG3038:1";
174                                    HashMap attributes = new HashMap();
175                                    attributes.put("source", "gadfly");    // get source
176                                    attributes.put("feature", "translation");   // get feature label
177                                    attributes.put("score", ".");     // get score
178                                    attributes.put("strand", "-");    // get strand
179                                    attributes.put("frame", ".");     // get frame
180                                    attributes.put("attributes", "genegrp=CG3038; transgrp=CG3038-RB; name=CG3038:1");
181                                    feature.setAttributes(attributes);
182                                    feature.setAttributes("source=sim4:na_dbEST.same.dmel;feature=match;score=.;strand=-;frame=.;attributes=ID=:2687161_sim4;Name=RH64340.5prime");
183                                    object = feature;
184                                    */
185    
186                                    //                              gt.load("data/fly/dmel-4-r4.0.gff", FileIO.GFF);
187    
188                                    // claims 3188 bytes but jvm usage increases 35 MB
189                                    object = gt.load("data/gb1.gff");
190              
191                if (i >= 0)
192                    objects[i] = object;
193                else {
194                    object = null; // discard the "warmup" object
195                    runGC();
196                    heap1 = usedMemory(); // take a "before" heap snapshot
197                }
198            }
199    
200            runGC();
201            long heap2 = usedMemory(); // take an "after" heap snapshot:
202            
203            final int size = Math.round (((float)(heap2 - heap1))/count);
204            System.out.println ("'before' heap: " + heap1 + ", 'after' heap: " + heap2);
205            System.out.println ("heap delta: " + (heap2 - heap1) +
206                ", {" + objects [0].getClass () + "} size = " + size + " bytes");
207        }
208    
209        // a helper method for creating Strings of desired length
210        // and avoiding getting tricked by String interning:
211        public static String createString(final int length) {
212            final char[] result = new char[length];
213            for (int i = 0; i < length; ++i) result[i] = (char) i;
214            
215            return new String (result);
216        }
217    
218        // this is our way of requesting garbage collection to be run:
219        // [how aggressive it is depends on the JVM to a large degree, but
220        // it is almost always better than a single Runtime.gc() call]
221             public static void runGC() {
222            // for whatever reason it helps to call Runtime.gc()
223            // using several method calls:
224                      try {
225                                    for (int r = 0; r < 4; ++r) _runGC();
226                      } catch (Exception e) { System.err.println(e); }
227        }
228    
229        public static void _runGC() {
230            long usedMem1 = usedMemory(), usedMem2 = Long.MAX_VALUE;
231    
232                      try {
233                                    for (int i = 0; (usedMem1 < usedMem2) && (i < 1000); ++i) {
234                                             s_runtime.runFinalization();
235                                             s_runtime.gc();
236                                             Thread.currentThread().yield();
237                                             
238                                             usedMem2 = usedMem1;
239                                             usedMem1 = usedMemory();
240                                    }
241                      } catch (Exception e) { System.err.println(e); }
242        }
243    
244        public static long usedMemory() {
245            return s_runtime.totalMemory() - s_runtime.freeMemory();
246        }
247        
248        public static final Runtime s_runtime = Runtime.getRuntime();
249    
250    } // GloDBMain.java