Main Page   Packages   Class Hierarchy   Compound List   File List   Compound Members  

SortComposer.java

00001 /*
00002  *  Copyright 2006-2007 Columbia University.
00003  *
00004  *  This file is part of MEAPsoft.
00005  *
00006  *  MEAPsoft is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License version 2 as
00008  *  published by the Free Software Foundation.
00009  *
00010  *  MEAPsoft is distributed in the hope that it will be useful, but
00011  *  WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with MEAPsoft; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00018  *  02110-1301 USA
00019  *
00020  *  See the file "COPYING" for the text of the license.
00021  */
00022 
00023 package com.meapsoft.composers;
00024 
00025 import gnu.getopt.Getopt;
00026 
00027 import java.io.IOException;
00028 import java.text.NumberFormat;
00029 import java.util.Vector;
00030 
00031 import com.meapsoft.ChunkDist;
00032 import com.meapsoft.EDLChunk;
00033 import com.meapsoft.EDLFile;
00034 import com.meapsoft.EuclideanDist;
00035 import com.meapsoft.FeatChunk;
00036 import com.meapsoft.FeatFile;
00037 import com.meapsoft.Heap;
00038 import com.meapsoft.MaxHeap;
00039 import com.meapsoft.MinHeap;
00040 import com.meapsoft.ParserException;
00041 
00049 public class SortComposer extends Composer
00050 {
00051         public static String description = "SortComposer sorts the " +
00052         "features in ascending or descending " +
00053         "order. If there are multiple features, " +
00054         "or more than one value per feature, it " +
00055         "sorts according to distance in" +
00056         " Euclidean space.";
00057         
00058     String outFileName = "sorted.edl";
00059 
00060     FeatFile featFile;
00061     int[] featdim = null;
00062     ChunkDist dist;
00063     boolean reverseSort = false;
00064     boolean debug = false;
00065     boolean normalizeFeatures = true;
00066 
00067     public SortComposer(String featFN, String outFN)
00068     {
00069         this(featFN, outFN, new EuclideanDist());
00070     }
00071 
00072     public SortComposer(FeatFile featFN, EDLFile outFN)
00073     {
00074         this(featFN, outFN, new EuclideanDist());
00075     }
00076 
00077     public SortComposer(String featFN, String outFN, ChunkDist cd)
00078     {
00079         this(new FeatFile(featFN), new EDLFile(outFN), cd);
00080     }
00081 
00082     public SortComposer(FeatFile featFN, EDLFile outFN, ChunkDist cd)
00083     {
00084         featFile = featFN;
00085         outFile = outFN;
00086         dist = cd;
00087         featdim = cd.featdim;
00088 
00089         if(outFile == null)
00090             outFile = new EDLFile("");
00091     }
00092 
00093     public void printUsageAndExit() 
00094     {
00095         System.out.println("Usage: SortComposer [-options] features.feat \n\n" + 
00096                "  where options include:\n" + 
00097                "    -o output_file  the file to write the output to (defaults to sorted.edl)\n" +
00098                "    -g              debug mode (prints out chunk features on each line of output file)\n" +
00099                "    -r              sort in reverse order");
00100         printCommandLineOptions('i');
00101         printCommandLineOptions('d');
00102         printCommandLineOptions('c');
00103         System.out.println();
00104         System.exit(0);
00105     }
00106 
00110     public SortComposer(String[] args) 
00111     {
00112         if(args.length == 0)
00113             printUsageAndExit();
00114 
00115         Vector features = new Vector();
00116 
00117         // Parse arguments
00118         String argString = "d:i:o:c:r:g";
00119         featdim = parseFeatDim(args, argString);
00120         dist = parseChunkDist(args, argString, featdim);
00121         parseCommands(args, argString);
00122 
00123         Getopt opt = new Getopt("SortComposer", args, argString);
00124         opt.setOpterr(false);
00125         
00126         int c = -1;
00127         while ((c =opt.getopt()) != -1) 
00128         {
00129             switch(c) 
00130             {
00131             case 'o':
00132                 outFileName = opt.getOptarg();
00133                 break;
00134             case 'r':
00135                 reverseSort = true;
00136                 break;
00137             case 'g':
00138                 debug = true;
00139                 break;
00140             case 'd':  // already handled above
00141                 break;
00142             case 'i':  // already handled above
00143                 break;
00144             case 'c':  // already handled above
00145                 break;
00146             case '?':
00147                 printUsageAndExit();
00148                 break;
00149             default:
00150                 System.out.print("getopt() returned " + c + "\n");
00151             }
00152         }
00153         
00154         // parse arguments
00155         int ind = opt.getOptind();
00156         if(ind > args.length)
00157             printUsageAndExit();
00158         
00159         featFile = new FeatFile(args[args.length-1]);
00160         outFile = new EDLFile(outFileName);
00161 
00162         System.out.println("Composing " + outFileName + 
00163                            " from " +  args[args.length-1] + ".");
00164     }
00165 
00166     public void setReverseSort(boolean b)
00167     {
00168         reverseSort = b;
00169     }
00170 
00171     public void setNormalizeFeatures(boolean b)
00172     {
00173         normalizeFeatures = b;
00174     }
00175 
00176     public void setup() throws IOException, ParserException
00177     {
00178         super.setup();
00179 
00180         if(!featFile.haveReadFile)
00181             featFile.readFile();
00182 
00183         if(featFile.chunks.size() == 0)
00184             throw new ParserException(featFile.filename, "No chunks found");
00185 
00186         if(normalizeFeatures)
00187         {
00188             featFile = (FeatFile)featFile.clone();
00189             featFile.normalizeFeatures();
00190             featFile.applyFeatureWeights();
00191         }
00192 
00193         progress.setMaximum(featFile.chunks.size());
00194     }
00195     
00196     public EDLFile compose()
00197     {
00198         // how many feature dimensions are we using?
00199         int maxdim = 0;
00200         if(featdim != null)
00201         {
00202             for(int x = 0; x < featdim.length; x++)
00203             {
00204                 if(featdim[x] > maxdim)
00205                     maxdim = featdim[x]; 
00206             }
00207         }
00208         else
00209             maxdim = ((FeatChunk)featFile.chunks.get(0)).numFeatures();
00210         
00211         FeatChunk targetChunk = new FeatChunk("",0,0);
00212         for(int i = 0; i <= maxdim; i++)
00213             //targetChunk.addFeature(0);
00214             targetChunk.addFeature(Integer.MIN_VALUE);
00215         
00216         dist.setTarget(targetChunk);
00217         
00218         // maintain a set of chunks sorted using dist from targetChunk
00219         Heap chunks = null;
00220         if(reverseSort)
00221             chunks = new MaxHeap(dist);
00222         else
00223             chunks = new MinHeap(dist);
00224         chunks.addAll(featFile.chunks);
00225         
00226         NumberFormat fmt = NumberFormat.getInstance();
00227         fmt.setMaximumFractionDigits(3);
00228         
00229         double currTime = 0;
00230         while(chunks.size() > 0)
00231         {
00232             FeatChunk match = (FeatChunk)chunks.remove(0);
00233 
00234             // turn match chunk into an EDL chunk 
00235             EDLChunk nc = new EDLChunk(match, currTime);
00236 
00237             if(debug)
00238             {
00239                 nc.comment = "    # feats = ";
00240                 double[] feat = match.getFeatures(featdim);
00241                 for(int x = 0; x < feat.length-1; x++)
00242                     nc.comment += fmt.format(feat[x]) + ", ";
00243                 nc.comment += fmt.format(feat[feat.length-1]);
00244             }
00245 
00246             outFile.chunks.add(nc);
00247             
00248             currTime += match.length;
00249 
00250             progress.setValue(progress.getValue()+1);   
00251         }
00252 
00253         // outFile now contains some chunks.
00254         outFile.haveReadFile = true;
00255 
00256         return outFile;
00257     } 
00258 
00259     public static void main(String[] args) 
00260     {
00261         SortComposer m = new SortComposer(args);
00262         long startTime = System.currentTimeMillis();
00263         m.run();
00264         System.out.println("Done. Took " +
00265                            ((System.currentTimeMillis() - startTime)/1000.0)
00266                            + "s");
00267         System.exit(0);
00268     }
00269 }

Generated on Tue Feb 6 19:02:27 2007 for MEAPsoft by doxygen1.2.18