001/**
002 * Copyright (c) 2011, The University of Southampton and the individual contributors.
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification,
006 * are permitted provided that the following conditions are met:
007 *
008 *   *  Redistributions of source code must retain the above copyright notice,
009 *      this list of conditions and the following disclaimer.
010 *
011 *   *  Redistributions in binary form must reproduce the above copyright notice,
012 *      this list of conditions and the following disclaimer in the documentation
013 *      and/or other materials provided with the distribution.
014 *
015 *   *  Neither the name of the University of Southampton nor the names of its
016 *      contributors may be used to endorse or promote products derived from this
017 *      software without specific prior written permission.
018 *
019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029 */
030package org.openimaj.tools.clusterquantiser;
031
032import java.io.File;
033import java.io.IOException;
034import java.io.StringWriter;
035import java.util.ArrayList;
036import java.util.List;
037
038import org.kohsuke.args4j.Argument;
039import org.kohsuke.args4j.CmdLineException;
040import org.kohsuke.args4j.CmdLineParser;
041import org.kohsuke.args4j.Option;
042import org.kohsuke.args4j.ProxyOptionHandler;
043import org.openimaj.ml.clustering.SpatialClusters;
044import org.openimaj.tools.clusterquantiser.ClusterType.ClusterTypeOp;
045
046/**
047 * Options for clustering/quantising tool
048 * 
049 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk)
050 * @author Sina Samangooei (ss@ecs.soton.ac.uk)
051 */
052public abstract class AbstractClusterQuantiserOptions {
053        /**
054         * Usage info
055         */
056        public static String EXTRA_USAGE_INFO = "\n"
057                        + "Note: the create, info and quant options are mutually exclusive. The depth,\n"
058                        + "clusters, verbosity, and samples arguments are only valid in conjuction with\n"
059                        + "the create option; they are silently ignored otherwise. The file-type argument"
060                        + "is required in create and quant modes.\n" + "\n"
061                        + "Mail bug reports and suggestions to <jsh2@ecs.soton.ac.uk>.\n";
062
063        @Option(
064                        name = "--info",
065                        aliases = "-if",
066                        required = false,
067                        usage = "Print statistics about STRING.",
068                        metaVar = "STRING")
069        protected String infoFile;
070        protected boolean info_mode = false;
071
072        @Option(
073                        name = "--info-diff",
074                        aliases = "-dif",
075                        required = false,
076                        usage = "Calculate the distance between two comparable clusters.",
077                        metaVar = "STRING")
078        protected String otherInfoFile;
079
080        @Option(
081                        name = "--quant",
082                        aliases = "-q",
083                        required = false,
084                        usage = "Quantize features using vocabulary in FILE.",
085                        metaVar = "STRING")
086        protected String quantLocation;
087        // protected File quantLocation;
088        protected boolean quant_mode = false;
089
090        @Option(
091                        name = "--count-mode",
092                        aliases = "-cm",
093                        required = false,
094                        usage = "Output quantisation counts only (rather than each feature quantised)")
095        private boolean count_mode = false;
096
097        @Option(
098                        name = "--verbosity",
099                        aliases = "-v",
100                        required = false,
101                        usage = "Specify verbosity during creation.",
102                        metaVar = "NUMBER")
103        private int verbosity = 0;
104
105        @Option(
106                        name = "--file-type",
107                        aliases = "-t",
108                        required = false,
109                        usage = "Specify the type of file to be read.",
110                        handler = ProxyOptionHandler.class)
111        protected FileType fileType;
112
113        @Option(
114                        name = "--threads",
115                        aliases = "-j",
116                        required = false,
117                        usage = "Use NUMBER threads for quantization.",
118                        metaVar = "NUMBER")
119        private int concurrency = Runtime.getRuntime().availableProcessors();
120
121        @Option(
122                        name = "--extension",
123                        aliases = "-e",
124                        required = false,
125                        usage = "Specify the extension to be added to quantiser output.")
126        protected String extension = ".loc";
127
128        @Option(
129                        name = "--exact-quantisation-mode",
130                        aliases = "-eqm",
131                        required = false,
132                        usage = "Specify the quantisation mode.")
133        protected boolean exactQuant = false;
134
135        @Option(
136                        name = "--random-seed",
137                        aliases = "-rs",
138                        required = false,
139                        usage = "Specify the random seed for all the algorithms which happen to be random.",
140                        metaVar = "NUMBER")
141        private long randomSeed = -1;
142
143        @Argument(required = false)
144        protected List<File> inputFiles = new ArrayList<File>();
145
146        private String[] args;
147
148        /**
149         * Construct with arguments
150         * 
151         * @param args
152         */
153        public AbstractClusterQuantiserOptions(String[] args) {
154                this.args = args;
155        }
156
157        /**
158         * Prepare options by parsing arguments
159         * 
160         * @throws CmdLineException
161         */
162        public void prepare() throws CmdLineException {
163                final CmdLineParser parser = new CmdLineParser(this);
164                try {
165                        parser.parseArgument(args);
166                        this.validate();
167                } catch (final CmdLineException e) {
168                        String message = "";
169                        message += e.getMessage() + "\n";
170                        message += "Usage: java -jar JClusterQuantiser.jar [options...] [files...]" + "\n";
171
172                        final StringWriter sw = new StringWriter();
173                        parser.printUsage(sw, null);
174
175                        message += sw.toString();
176                        message += ClusterQuantiserOptions.EXTRA_USAGE_INFO + "\n";
177
178                        throw new CmdLineException(parser, message);
179                }
180        }
181
182        /**
183         * @return the file
184         * @throws IOException
185         */
186        public String getTreeFile() throws IOException {
187                if (info_mode)
188                        return infoFile;
189                if (quant_mode)
190                        return quantLocation;
191                return null;
192        }
193
194        /**
195         * @return otherInfoFile
196         */
197        public String getOtherInfoFile() {
198                if (info_mode)
199                        return otherInfoFile;
200                return null;
201        }
202
203        /**
204         * @return true if in info mode
205         */
206        public boolean isInfoMode() {
207                return info_mode;
208        }
209
210        /**
211         * @return true if in quant mode
212         */
213        public boolean isQuantMode() {
214                return quant_mode;
215        }
216
217        /**
218         * @return the verbosity
219         */
220        public int getVerbosity() {
221                return verbosity;
222        }
223
224        /**
225         * @return the file type
226         */
227        public FileType getFileType() {
228                return fileType;
229        }
230
231        /**
232         * @return the number of threads to use
233         */
234        public int getConcurrency() {
235                return concurrency;
236        }
237
238        /**
239         * @return the file extension
240         */
241        public String getExtension() {
242                return extension;
243        }
244
245        /**
246         * @return true if in count mode
247         */
248        public boolean getCountMode() {
249                return this.count_mode;
250        }
251
252        /**
253         * @return the random seed
254         */
255        public long getRandomSeed() {
256                return randomSeed;
257        }
258
259        /**
260         * @return the input file
261         */
262        public abstract String getInputFileString();
263
264        /**
265         * @return the output file
266         */
267        public abstract String getOutputFileString();
268
269        /**
270         * Validate the options
271         * 
272         * @throws CmdLineException
273         */
274        public abstract void validate() throws CmdLineException;
275
276        /**
277         * @return the cluster type
278         */
279        public abstract ClusterTypeOp getClusterType();
280
281        /**
282         * @return the other-info type
283         */
284        public abstract ClusterTypeOp getOtherInfoType();
285
286        /**
287         * @return the java class representing the clusters
288         */
289        public abstract Class<? extends SpatialClusters<?>> getClusterClass();
290
291        /**
292         * @return the java class representing the clusters
293         */
294        public abstract Class<? extends SpatialClusters<?>> getOtherInfoClass();
295
296        /**
297         * Set the file type
298         * 
299         * @param fileType
300         */
301        public void setFileType(FileType fileType) {
302                this.fileType = fileType;
303        }
304}