gr.evoltrio.conf.CliParametersParser.java Source code

Java tutorial

Introduction

Here is the source code for gr.evoltrio.conf.CliParametersParser.java

Source

/**
 * This file is part of EvolTrio.
 *
 * EvolTrio is licensed under the GPLv3.
 *
 * For licensing information please see the file license.txt included with EvolTrio
 * or have a look at the top of class gr.evoltrio.core.Evolution which representatively
 * includes the EvolTrio license policy applicable for any file delivered with EvolTrio.
 */
package gr.evoltrio.conf;

import gr.evoltrio.core.EvolConfiguration;
import gr.evoltrio.fitness.FiltersFactory;
import gr.evoltrio.fitness.SoloFitnessEvol;
import gr.evoltrio.midi.MusicConfiguration;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

/**
 * 
 * @author Konstantinos Georgiadis
 * @since 0.0.1
 */
public class CliParametersParser {

    // TODO put tha somewhere else
    private CommandLineParser parser;
    private Options options;
    CommandLine line;

    private String[] args;

    public CliParametersParser(String[] args) {

        this.args = args;

        parser = new GnuParser();
        options = new Options();

        // add options first
        addOptions();

        // parse the command line arguments
        try {
            line = parser.parse(options, args);
            parseParameters();
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    private void addOptions() {
        OptionBuilder.withLongOpt("begDur").withDescription("Sets the duration of the first note in a phrase")
                .hasArg().withArgName("[1,6]");
        // music parameters
        options.addOption(OptionBuilder.create());

        options.addOption(OptionBuilder.withLongOpt("phraseNotes")
                .withDescription("Sets the number of notes a phrase will contain").hasArg().withArgName("[4,32]")
                .create());

        options.addOption(OptionBuilder.withLongOpt("intJump")
                .withDescription("Sets the max interval jump between two adjacent notes").hasArg()
                .withArgName("[1,12]").create());

        options.addOption(OptionBuilder.withLongOpt("durJump")
                .withDescription("Sets the max duration jump between two adjacent notes").hasArg()
                .withArgName("[1,6]").create());

        options.addOption(OptionBuilder.withLongOpt("note").withDescription("The pitch of the key note").hasArg()
                .withArgName("[ C | C# | .. | B ]").create());

        options.addOption(OptionBuilder.withLongOpt("octave").withDescription("The octave of the key note").hasArg()
                .withArgName("[2,7]").create());

        options.addOption(OptionBuilder.withLongOpt("pattern").withDescription("The music pattern to use").hasArg()
                .withArgName("[ I-IV-V-I ]").create());

        options.addOption(OptionBuilder.withLongOpt("drums").withDescription("The drum pattern to use").hasArg()
                .withArgName("[ default ]").create());

        options.addOption(OptionBuilder.withLongOpt("bass").withDescription("The bass pattern to use").hasArg()
                .withArgName("[ default ]").create());

        options.addOption(OptionBuilder.withLongOpt("tempo").withDescription("Defines the music tempo").hasArg()
                .withArgName("[ ADAGIO ]").create());

        options.addOption(OptionBuilder.withLongOpt("organ")
                .withDescription("The midi instrument that the solist is going to use").hasArg()
                .withArgName("[0,127]").create());

        // parameters for the evolution
        options.addOption(OptionBuilder.withLongOpt("random").withDescription("The random generator to use")
                .hasArg().withArgName("[ STOCK | CAUCHY | GAUSSIAN ]").create());

        options.addOption(OptionBuilder.withLongOpt("natural").withDescription("The natural selector to use")
                .hasArg().withArgName("[ BEST | THRESHOLD | TOURNAMENT | WEIGHTED ]").create());

        options.addOption("u", "execBefore", false, "Execute the natural selector before the genetic operators");

        options.addOption(OptionBuilder.withLongOpt("minpop")
                .withDescription("Minimum percent size guaranteed for population").hasArg().withArgName("[0,100]")
                .create());

        options.addOption(OptionBuilder.withLongOpt("previousGen")
                .withDescription(
                        "Defines the percentage of the chromosomes that are going to enter the new population")
                .hasArg().withArgName("[0,1]").create());

        options.addOption("f", "constant", false, "Keep constant the population size");

        options.addOption(OptionBuilder.withLongOpt("crossover").withDescription("Defines the crossover rate")
                .hasArg().withArgName("[0,1]").create());

        options.addOption(OptionBuilder.withLongOpt("mutation").withDescription("Defines the mutation rate")
                .hasArg().withArgName("[0,100]").create());

        options.addOption(OptionBuilder.withLongOpt("pop").withDescription("Defines the population size").hasArg()
                .withArgName("[0,1000]").create());

        options.addOption(OptionBuilder.withLongOpt("iterations")
                .withDescription("Sets the number of iterations that each phrase will evolve").hasArg()
                .withArgName("[1,10000]").create());

        // fitness parameters
        options.addOption("1", "filtall", false,
                "Enables all the fitness filters. This option will override any other made that involves filters");

        options.addOption("P", "pitch", false, "Enables simple pitch fitness filter");
        options.addOption("D", "duration", false, "Enables simple duration fitness filter");
        options.addOption("S", "scale", false, "Enables scale notes fitness filter. USE THIS!");
        options.addOption("T", "time", false, "Enables time fitness filter");
        options.addOption("B", "dull", false, "Enables dull (boring music) fitness filter");
        options.addOption("H", "high", false, "Enables high diversity of notes fitness filter");

        options.addOption("R", "repetition1", false, "Enables repetition of notes fitness filter");
        options.addOption("E", "repetition2", false, "Enables a different repetition of notes fitness filter");
        options.addOption("A", "ascending", false, "Enables adjacent ascending notes fitness filter");
        options.addOption("Z", "descending", false, "Enables adjacent descending notes fitness filter");

        // options.addOption(OptionBuilder.withLongOpt("file").isRequired()
        // .withDescription("The file to store the produced midi")
        // .hasArg().withArgName("FILE").create());

        options.addOption("v", "version", false, "Show version");

        options.addOption("h", "help", false, "Print this screen and quit");

    }

    /**
     * TODO correct this to smt more generic
     */
    private void parseParameters() {
        try {

            // validate that block-size has been set
            if (line.hasOption("help")) {
                // print the value of block-size
                System.out.println(line.getOptionValue("help"));
                HelpFormatter formatter = new HelpFormatter();
                formatter.setWidth(120);
                formatter.printHelp("java -jar EvolTrio.jar [ OPTIONS ] FILE", options);
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
    }

    public void getMusicConfig() {

        // validate the beggining duration
        if (line.hasOption("begDur")) {
            // parse the value
            int value = Integer.parseInt(line.getOptionValue("begDur"));
            MusicConfiguration.getInstance().setBeginningDuration(value);
        }
        // validate the phrase notes
        if (line.hasOption("phraseNotes")) {

            int value = Integer.parseInt(line.getOptionValue("phraseNotes"));

            MusicConfiguration.getInstance().setPhraseNotes(value);
        }

        // validate the maximum interval jump
        if (line.hasOption("intJump")) {

            int value = Integer.parseInt(line.getOptionValue("intJump"));
            MusicConfiguration.getInstance().setMaxIntervalJump(value);
        }
        // validate the maximum duration jump
        if (line.hasOption("durJump")) {

            int value = Integer.parseInt(line.getOptionValue("durJump"));
            MusicConfiguration.getInstance().setMaxDurationJump(value);

        }
        // validate the octave -- it comes first
        // afterwards the note is going to set the keyNote
        if (line.hasOption("octave")) {

            int value = Integer.parseInt(line.getOptionValue("octave"));
            MusicConfiguration.getInstance().setOctave(value);
        }
        // validate for the note
        if (line.hasOption("note")) {

            String value = line.getOptionValue("note");
            MusicConfiguration.getInstance().setRootNote(value);
        }

        if (line.hasOption("pattern")) {

            String value = line.getOptionValue("pattern");
            MusicConfiguration.getInstance().setMusicPattern(value);
        }

        if (line.hasOption("drums")) {

            String value = line.getOptionValue("drums");
            MusicConfiguration.getInstance().setDrumPattern(value);
        }

        if (line.hasOption("bass")) {

            String value = line.getOptionValue("bass");
            MusicConfiguration.getInstance().setBassPattern(value);

        }

        if (line.hasOption("organ")) {

            int value = Integer.parseInt(line.getOptionValue("organ"));
            MusicConfiguration.getInstance().setSoloOrgan(value);
        }

        if (line.hasOption("tempo")) {

            String value = line.getOptionValue("tempo");
            MusicConfiguration.getInstance().setTempo(value);
        }

    }

    public EvolConfiguration getEvolConfig() {
        String randomGen = "stock";
        String naturalSel = "best";
        boolean executeNaturalBefore = false;
        double selectFromPrevGen = 1.0d;
        int minPopSizePercent = 0;
        boolean keepPopSizeConstant = false;
        double crossoverRate = 0.55d;
        int mutationRate = 32;
        int popSize = 100;
        int iterations = 100;

        try {
            if (line.hasOption("random")) {
                // parse the value
                String value = line.getOptionValue("random");

                boolean genFound = false;

                for (String rndG : EvolConfiguration.RANDOMGENERATORS)
                    if (value.equalsIgnoreCase(rndG))
                        genFound = true;

                if (!genFound) {
                    throw new ParseException("Invalid value for random generator : " + value
                            + ". Possible values are stock,cauchy or gaussian");
                }

                randomGen = value;
            }

            if (line.hasOption("natural")) {
                // parse the value
                String value = line.getOptionValue("natural");

                boolean naturFound = false;

                for (String natF : EvolConfiguration.NATURALSELECTORS)
                    if (value.equalsIgnoreCase(natF))
                        naturFound = true;

                if (!naturFound) {
                    throw new ParseException("Invalid value for natural generator : " + value
                            + ". Possible values are best,threshold,tournament or weighted");

                }
                naturalSel = value;
            }
            // TODO change order
            if (line.hasOption("minpop")) {
                // parse the value
                int value = Integer.parseInt(line.getOptionValue("minpop"));

                if (value < 0 || value > 100) {
                    throw new ParseException("Invalid value for minimum size percent : " + value
                            + " . Possible values are [0,100].");

                }
                minPopSizePercent = value;
            }
            // TODO change corresponding values to double
            if (line.hasOption("previousGen")) {
                // parse the value
                int value = Integer.parseInt(line.getOptionValue("previousGen"));
                if (value < 0 || value > 1) {
                    throw new ParseException("Invalid value for select from previous generation : " + value
                            + " . Possible values are [0,1].");
                }
                selectFromPrevGen = value;
            }

            if (line.hasOption("crossover")) {
                // parse the value
                double value = Double.parseDouble(line.getOptionValue("crossover"));
                if (value < 0 || value > 1) {
                    throw new ParseException(
                            "Invalid value for crossover rate : " + value + " . Possible values are [0,1].");
                }
                crossoverRate = value;
            }

            if (line.hasOption("mutation")) {
                // parse the value
                int value = Integer.parseInt(line.getOptionValue("mutation"));
                if (value < 0 || value > 100) {
                    throw new ParseException(
                            "Invalid value for mutation rate : " + value + " . Possible values are [0,100].");
                }
                mutationRate = value;
            }

            if (line.hasOption("pop")) {
                // parse the value
                int value = Integer.parseInt(line.getOptionValue("pop"));
                if (value < 1 || value > 1000) {
                    throw new ParseException(
                            "Invalid value for population size : " + value + " . Possible values are [0,1000].");
                }
                iterations = value;
            }

            if (line.hasOption("iterations")) {
                // parse the value
                int value = Integer.parseInt(line.getOptionValue("iterations"));
                if (value < 1 || value > 10000) {
                    throw new ParseException("Invalid value for the number of iterations : " + value
                            + " . Possible values are 0,10000].");

                }
                iterations = value;
            }

        } catch (ParseException exp) {
            System.out.println("Unexpected exception:" + exp.getMessage());
        }
        // TODO figure out smt for the invalid parameters
        return new EvolConfiguration(randomGen, naturalSel, executeNaturalBefore, minPopSizePercent,
                selectFromPrevGen, keepPopSizeConstant, crossoverRate, mutationRate, iterations);

    }

    public SoloFitnessEvol getSoloFitness() {

        SoloFitnessEvol soloFitnessEvol = new SoloFitnessEvol();

        if (line.hasOption("P") || line.hasOption("pitch")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.SIMPLEPITCH);
        }
        if (line.hasOption("D") || line.hasOption("duration")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.SIMPLEDURATION);
        }
        if (line.hasOption("S") || line.hasOption("scale")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.OUTOFSCALE);
        }
        if (line.hasOption("T") || line.hasOption("time")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.TIME);
        }
        if (line.hasOption("B") || line.hasOption("dull")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.DULL);
        }
        if (line.hasOption("H") || line.hasOption("high")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.HIGHANDLOW);
        }
        if (line.hasOption("R") || line.hasOption("repetition1")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.ROOTNOTE);
        }
        if (line.hasOption("E") || line.hasOption("repetition2")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.THREENOTE);
        }
        if (line.hasOption("A") || line.hasOption("ascending")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.ASCENDING);
        }
        if (line.hasOption("Z") || line.hasOption("descending")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.DESCENDING);
        }
        if (line.hasOption("1") || line.hasOption("filtall")) {
            soloFitnessEvol.addFilter(FiltersFactory.Filter.SIMPLEPITCH);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.SIMPLEDURATION);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.OUTOFSCALE);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.TIME);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.DULL);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.HIGHANDLOW);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.ROOTNOTE);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.THREENOTE);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.ASCENDING);
            soloFitnessEvol.addFilter(FiltersFactory.Filter.DESCENDING);
        }

        return soloFitnessEvol;
    }

    public static void main(String[] args) {
        new CliParametersParser(new String[] { "--h", "--phraseNotes=32" }).getSoloFitness();
    }

}